a7n_platform/
clipboard.rs1use a7n_core::clipboard::{Generation, Item, LocalChange};
6use tokio::sync::{mpsc, oneshot};
7
8#[cfg(any(windows, target_os = "macos"))]
9mod fetch;
10#[cfg(all(unix, not(target_os = "macos")))]
11mod formats;
12#[cfg(target_os = "macos")]
13mod macos;
14pub mod uri_list;
15#[cfg(all(unix, not(target_os = "macos")))]
16pub(crate) mod wayland;
17#[cfg(all(unix, not(target_os = "macos")))]
18mod x11;
19
20#[cfg(any(windows, test))]
21#[path = "clipboard/windows/cf_html.rs"]
22mod cf_html;
23#[cfg(windows)]
24mod windows;
25#[cfg(all(test, not(windows)))]
26#[path = "clipboard/windows/drop_files.rs"]
27mod windows_drop_files;
28#[cfg(all(test, not(windows)))]
29#[path = "clipboard/windows/image.rs"]
30mod windows_image;
31
32#[derive(Debug)]
35pub struct Clipboard {
36 pub images: bool,
38 pub files: bool,
42 pub changes: mpsc::Receiver<LocalChange>,
43 pub commands: mpsc::Sender<ClipboardCommand>,
44 pub pastes: mpsc::Receiver<PasteRequest>,
46}
47
48#[derive(Debug)]
49pub enum ClipboardCommand {
50 Set {
51 generation: Generation,
52 items: Vec<Item>,
53 lazy: Vec<LazyItem>,
55 },
56}
57
58#[derive(Debug, Clone, PartialEq, Eq)]
60pub struct LazyItem {
61 pub mime: String,
62 pub size: u64,
63 pub item_index: u32,
65 pub top_level: u32,
69}
70
71impl LazyItem {
72 pub(crate) fn within_limit(&self) -> bool {
74 self.mime == a7n_core::clipboard::FILES
75 || self.size <= a7n_core::clipboard::limit_for(&self.mime) as u64
76 }
77}
78
79pub(crate) const FILE_PASTE_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(10 * 60);
82
83#[derive(Debug)]
86pub struct PasteRequest {
87 pub generation: Generation,
88 pub item_index: u32,
89 pub reply: oneshot::Sender<Option<Vec<u8>>>,
90}
91
92#[derive(Debug, thiserror::Error)]
93pub enum ClipboardError {
94 #[error("clipboard is not supported on this platform")]
95 Unsupported,
96 #[cfg(target_os = "macos")]
97 #[error("macOS clipboard failed: {0}")]
98 Macos(#[from] std::io::Error),
99 #[cfg(windows)]
100 #[error("Windows clipboard failed: {0}")]
101 Windows(#[from] std::io::Error),
102 #[cfg(all(unix, not(target_os = "macos")))]
103 #[error("X11 clipboard failed: {0}")]
104 X11(#[from] crate::input::InputError),
105 #[cfg(all(unix, not(target_os = "macos")))]
106 #[error("Wayland clipboard failed: {0}")]
107 Wayland(#[from] wayland::WaylandError),
108}
109
110pub fn start() -> Result<Clipboard, ClipboardError> {
116 #[cfg(all(unix, not(target_os = "macos")))]
117 {
118 use crate::input::{Backend, detect_backend};
119 match detect_backend() {
120 Backend::X11 => return Ok(x11::start()?),
121 Backend::Wayland => return Ok(wayland::start()?),
122 Backend::None => {}
123 }
124 }
125 #[cfg(windows)]
126 {
127 Ok(windows::start()?)
128 }
129 #[cfg(target_os = "macos")]
130 {
131 Ok(macos::start()?)
132 }
133 #[cfg(not(any(windows, target_os = "macos")))]
134 Err(ClipboardError::Unsupported)
135}