egui_winit/
clipboard.rs
1use raw_window_handle::RawDisplayHandle;
2
3pub struct Clipboard {
8 #[cfg(all(feature = "arboard", not(target_os = "android")))]
9 arboard: Option<arboard::Clipboard>,
10
11 #[cfg(all(
12 any(
13 target_os = "linux",
14 target_os = "dragonfly",
15 target_os = "freebsd",
16 target_os = "netbsd",
17 target_os = "openbsd"
18 ),
19 feature = "smithay-clipboard"
20 ))]
21 smithay: Option<smithay_clipboard::Clipboard>,
22
23 clipboard: String,
25}
26
27impl Clipboard {
28 pub fn new(_raw_display_handle: Option<RawDisplayHandle>) -> Self {
30 Self {
31 #[cfg(all(feature = "arboard", not(target_os = "android")))]
32 arboard: init_arboard(),
33
34 #[cfg(all(
35 any(
36 target_os = "linux",
37 target_os = "dragonfly",
38 target_os = "freebsd",
39 target_os = "netbsd",
40 target_os = "openbsd"
41 ),
42 feature = "smithay-clipboard"
43 ))]
44 smithay: init_smithay_clipboard(_raw_display_handle),
45
46 clipboard: Default::default(),
47 }
48 }
49
50 pub fn get(&mut self) -> Option<String> {
51 #[cfg(all(
52 any(
53 target_os = "linux",
54 target_os = "dragonfly",
55 target_os = "freebsd",
56 target_os = "netbsd",
57 target_os = "openbsd"
58 ),
59 feature = "smithay-clipboard"
60 ))]
61 if let Some(clipboard) = &mut self.smithay {
62 return match clipboard.load() {
63 Ok(text) => Some(text),
64 Err(err) => {
65 log::error!("smithay paste error: {err}");
66 None
67 }
68 };
69 }
70
71 #[cfg(all(feature = "arboard", not(target_os = "android")))]
72 if let Some(clipboard) = &mut self.arboard {
73 return match clipboard.get_text() {
74 Ok(text) => Some(text),
75 Err(err) => {
76 log::error!("arboard paste error: {err}");
77 None
78 }
79 };
80 }
81
82 Some(self.clipboard.clone())
83 }
84
85 pub fn set(&mut self, text: String) {
86 #[cfg(all(
87 any(
88 target_os = "linux",
89 target_os = "dragonfly",
90 target_os = "freebsd",
91 target_os = "netbsd",
92 target_os = "openbsd"
93 ),
94 feature = "smithay-clipboard"
95 ))]
96 if let Some(clipboard) = &mut self.smithay {
97 clipboard.store(text);
98 return;
99 }
100
101 #[cfg(all(feature = "arboard", not(target_os = "android")))]
102 if let Some(clipboard) = &mut self.arboard {
103 if let Err(err) = clipboard.set_text(text) {
104 log::error!("arboard copy/cut error: {err}");
105 }
106 return;
107 }
108
109 self.clipboard = text;
110 }
111}
112
113#[cfg(all(feature = "arboard", not(target_os = "android")))]
114fn init_arboard() -> Option<arboard::Clipboard> {
115 profiling::function_scope!();
116
117 log::trace!("Initializing arboard clipboard…");
118 match arboard::Clipboard::new() {
119 Ok(clipboard) => Some(clipboard),
120 Err(err) => {
121 log::warn!("Failed to initialize arboard clipboard: {err}");
122 None
123 }
124 }
125}
126
127#[cfg(all(
128 any(
129 target_os = "linux",
130 target_os = "dragonfly",
131 target_os = "freebsd",
132 target_os = "netbsd",
133 target_os = "openbsd"
134 ),
135 feature = "smithay-clipboard"
136))]
137fn init_smithay_clipboard(
138 raw_display_handle: Option<RawDisplayHandle>,
139) -> Option<smithay_clipboard::Clipboard> {
140 #![allow(clippy::undocumented_unsafe_blocks)]
141
142 profiling::function_scope!();
143
144 if let Some(RawDisplayHandle::Wayland(display)) = raw_display_handle {
145 log::trace!("Initializing smithay clipboard…");
146 #[allow(unsafe_code)]
147 Some(unsafe { smithay_clipboard::Clipboard::new(display.display.as_ptr()) })
148 } else {
149 #[cfg(feature = "wayland")]
150 log::debug!("Cannot init smithay clipboard without a Wayland display handle");
151 #[cfg(not(feature = "wayland"))]
152 log::debug!(
153 "Cannot init smithay clipboard: the 'wayland' feature of 'egui-winit' is not enabled"
154 );
155 None
156 }
157}