term_model/
clipboard.rs
1#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "fuchsia")))]
16use std::ffi::c_void;
17
18#[cfg(not(target_os = "fuchsia"))]
19use log::{debug, warn};
20
21#[cfg(not(target_os = "fuchsia"))]
22use copypasta::nop_clipboard::NopClipboardContext;
23#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "fuchsia")))]
24use copypasta::wayland_clipboard;
25#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "fuchsia")))]
26use copypasta::x11_clipboard::{Primary as X11SelectionClipboard, X11ClipboardContext};
27#[cfg(not(target_os = "fuchsia"))]
28use copypasta::{ClipboardContext, ClipboardProvider};
29
30pub struct Clipboard {
31 #[cfg(not(target_os = "fuchsia"))]
32 clipboard: Box<dyn ClipboardProvider>,
33 #[cfg(not(target_os = "fuchsia"))]
34 selection: Option<Box<dyn ClipboardProvider>>,
35}
36
37impl Clipboard {
38 #[cfg(any(target_os = "macos", target_os = "windows", target_os = "fuchsia"))]
39 pub fn new() -> Self {
40 Self::default()
41 }
42
43 #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "fuchsia")))]
44 pub fn new(display: Option<*mut c_void>) -> Self {
45 if let Some(display) = display {
46 let (selection, clipboard) =
47 unsafe { wayland_clipboard::create_clipboards_from_external(display) };
48 return Self { clipboard: Box::new(clipboard), selection: Some(Box::new(selection)) };
49 }
50
51 Self {
52 clipboard: Box::new(ClipboardContext::new().unwrap()),
53 selection: Some(Box::new(X11ClipboardContext::<X11SelectionClipboard>::new().unwrap())),
54 }
55 }
56
57 #[cfg(not(target_os = "fuchsia"))]
59 pub fn new_nop() -> Self {
60 Self { clipboard: Box::new(NopClipboardContext::new().unwrap()), selection: None }
61 }
62
63 #[cfg(target_os = "fuchsia")]
64 pub fn new_nop() -> Self {
65 Self {}
66 }
67}
68
69impl Default for Clipboard {
70 #[cfg(not(target_os = "fuchsia"))]
71 fn default() -> Self {
72 Self { clipboard: Box::new(ClipboardContext::new().unwrap()), selection: None }
73 }
74
75 #[cfg(target_os = "fuchsia")]
76 fn default() -> Self {
77 Self {}
78 }
79}
80
81#[derive(Debug)]
82pub enum ClipboardType {
83 Clipboard,
84 Selection,
85}
86
87impl Clipboard {
94 #[cfg(not(target_os = "fuchsia"))]
95 pub fn store(&mut self, ty: ClipboardType, text: impl Into<String>) {
96 let clipboard = match (ty, &mut self.selection) {
97 (ClipboardType::Selection, Some(provider)) => provider,
98 (ClipboardType::Selection, None) => return,
99 _ => &mut self.clipboard,
100 };
101 clipboard.set_contents(text.into()).unwrap_or_else(|err| {
102 warn!("Unable to store text in clipboard: {}", err);
103 });
104 }
105
106 #[cfg(target_os = "fuchsia")]
107 pub fn store(&mut self, _ty: ClipboardType, _text: impl Into<String>) {
108 }
110
111 #[cfg(not(target_os = "fuchsia"))]
112 pub fn load(&mut self, ty: ClipboardType) -> String {
113 let clipboard = match (ty, &mut self.selection) {
114 (ClipboardType::Selection, Some(provider)) => provider,
115 _ => &mut self.clipboard,
116 };
117
118 match clipboard.get_contents() {
119 Err(err) => {
120 debug!("Unable to load text from clipboard: {}", err);
121 String::new()
122 },
123 Ok(text) => text,
124 }
125 }
126
127 #[cfg(target_os = "fuchsia")]
128 pub fn load(&mut self, _ty: ClipboardType) -> String {
129 String::new()
130 }
131}