use a7n_core::clipboard::{Generation, Item, LocalChange};
use tokio::sync::{mpsc, oneshot};
#[cfg(any(windows, target_os = "macos"))]
mod fetch;
#[cfg(all(unix, not(target_os = "macos")))]
mod formats;
#[cfg(target_os = "macos")]
mod macos;
pub mod uri_list;
#[cfg(all(unix, not(target_os = "macos")))]
pub(crate) mod wayland;
#[cfg(all(unix, not(target_os = "macos")))]
mod x11;
#[cfg(any(windows, test))]
#[path = "clipboard/windows/cf_html.rs"]
mod cf_html;
#[cfg(windows)]
mod windows;
#[cfg(all(test, not(windows)))]
#[path = "clipboard/windows/drop_files.rs"]
mod windows_drop_files;
#[cfg(all(test, not(windows)))]
#[path = "clipboard/windows/image.rs"]
mod windows_image;
#[derive(Debug)]
pub struct Clipboard {
pub images: bool,
pub files: bool,
pub changes: mpsc::Receiver<LocalChange>,
pub commands: mpsc::Sender<ClipboardCommand>,
pub pastes: mpsc::Receiver<PasteRequest>,
}
#[derive(Debug)]
pub enum ClipboardCommand {
Set {
generation: Generation,
items: Vec<Item>,
lazy: Vec<LazyItem>,
},
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct LazyItem {
pub mime: String,
pub size: u64,
pub item_index: u32,
pub top_level: u32,
}
impl LazyItem {
pub(crate) fn within_limit(&self) -> bool {
self.mime == a7n_core::clipboard::FILES
|| self.size <= a7n_core::clipboard::limit_for(&self.mime) as u64
}
}
pub(crate) const FILE_PASTE_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(10 * 60);
#[derive(Debug)]
pub struct PasteRequest {
pub generation: Generation,
pub item_index: u32,
pub reply: oneshot::Sender<Option<Vec<u8>>>,
}
#[derive(Debug, thiserror::Error)]
pub enum ClipboardError {
#[error("clipboard is not supported on this platform")]
Unsupported,
#[cfg(target_os = "macos")]
#[error("macOS clipboard failed: {0}")]
Macos(#[from] std::io::Error),
#[cfg(windows)]
#[error("Windows clipboard failed: {0}")]
Windows(#[from] std::io::Error),
#[cfg(all(unix, not(target_os = "macos")))]
#[error("X11 clipboard failed: {0}")]
X11(#[from] crate::input::InputError),
#[cfg(all(unix, not(target_os = "macos")))]
#[error("Wayland clipboard failed: {0}")]
Wayland(#[from] wayland::WaylandError),
}
pub fn start() -> Result<Clipboard, ClipboardError> {
#[cfg(all(unix, not(target_os = "macos")))]
{
use crate::input::{Backend, detect_backend};
match detect_backend() {
Backend::X11 => return Ok(x11::start()?),
Backend::Wayland => return Ok(wayland::start()?),
Backend::None => {}
}
}
#[cfg(windows)]
{
Ok(windows::start()?)
}
#[cfg(target_os = "macos")]
{
Ok(macos::start()?)
}
#[cfg(not(any(windows, target_os = "macos")))]
Err(ClipboardError::Unsupported)
}