blob: dd0a834844438a870db9fb2e9d569802b23aff7c [file] [log] [blame]
#[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))]
use std::ffi::c_void;
use log::{debug, warn};
use alacritty_terminal::term::ClipboardType;
#[cfg(any(test, not(any(feature = "x11", target_os = "macos", windows))))]
use copypasta::nop_clipboard::NopClipboardContext;
#[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))]
use copypasta::wayland_clipboard;
#[cfg(all(feature = "x11", not(any(target_os = "macos", windows))))]
use copypasta::x11_clipboard::{Primary as X11SelectionClipboard, X11ClipboardContext};
#[cfg(any(feature = "x11", target_os = "macos", windows))]
use copypasta::ClipboardContext;
use copypasta::ClipboardProvider;
pub struct Clipboard {
clipboard: Box<dyn ClipboardProvider>,
selection: Option<Box<dyn ClipboardProvider>>,
}
impl Clipboard {
#[cfg(any(not(feature = "wayland"), target_os = "macos", windows))]
pub fn new() -> Self {
Self::default()
}
#[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))]
pub unsafe fn new(display: Option<*mut c_void>) -> Self {
match display {
Some(display) => {
let (selection, clipboard) =
wayland_clipboard::create_clipboards_from_external(display);
Self { clipboard: Box::new(clipboard), selection: Some(Box::new(selection)) }
},
None => Self::default(),
}
}
/// Used for tests and to handle missing clipboard provider when built without the `x11`
/// feature.
#[cfg(any(test, not(any(feature = "x11", target_os = "macos", windows))))]
pub fn new_nop() -> Self {
Self { clipboard: Box::new(NopClipboardContext::new().unwrap()), selection: None }
}
}
impl Default for Clipboard {
fn default() -> Self {
#[cfg(any(target_os = "macos", windows))]
return Self { clipboard: Box::new(ClipboardContext::new().unwrap()), selection: None };
#[cfg(all(feature = "x11", not(any(target_os = "macos", windows))))]
return Self {
clipboard: Box::new(ClipboardContext::new().unwrap()),
selection: Some(Box::new(X11ClipboardContext::<X11SelectionClipboard>::new().unwrap())),
};
#[cfg(not(any(feature = "x11", target_os = "macos", windows)))]
return Self::new_nop();
}
}
impl Clipboard {
pub fn store(&mut self, ty: ClipboardType, text: impl Into<String>) {
let clipboard = match (ty, &mut self.selection) {
(ClipboardType::Selection, Some(provider)) => provider,
(ClipboardType::Selection, None) => return,
_ => &mut self.clipboard,
};
clipboard.set_contents(text.into()).unwrap_or_else(|err| {
warn!("Unable to store text in clipboard: {}", err);
});
}
pub fn load(&mut self, ty: ClipboardType) -> String {
let clipboard = match (ty, &mut self.selection) {
(ClipboardType::Selection, Some(provider)) => provider,
_ => &mut self.clipboard,
};
match clipboard.get_contents() {
Err(err) => {
debug!("Unable to load text from clipboard: {}", err);
String::new()
},
Ok(text) => text,
}
}
}