
arboard advertises that it works with Wayland, but in reality it only works with Wayland terminal applications. To make the clipboard work with applications that draw Wayland surfaces, arboard isn't going to work. Copypasta does support Wayland's graphical clipboard, but the usage isn't documented. However, for the reasons mentioned in #1474 the move from Copypasta to arboard makes sense. To resolve the issue, this commit brings in an optional dependency smithay-clipboard, that is a crate that correctly handles the Wayland clipboard in graphical applications. It is used by default if a Wayland window handle is found. If for some reason the handle to the Wayland window handle cannot be fetched, arboard is used as a backup.
142 lines
4 KiB
Rust
142 lines
4 KiB
Rust
use std::os::raw::c_void;
|
|
|
|
/// Handles interfacing with the OS clipboard.
|
|
///
|
|
/// If the "clipboard" feature is off, or we cannot connect to the OS clipboard,
|
|
/// then a fallback clipboard that just works works within the same app is used instead.
|
|
pub struct Clipboard {
|
|
#[cfg(feature = "arboard")]
|
|
arboard: Option<arboard::Clipboard>,
|
|
|
|
#[cfg(all(
|
|
any(
|
|
target_os = "linux",
|
|
target_os = "dragonfly",
|
|
target_os = "freebsd",
|
|
target_os = "netbsd",
|
|
target_os = "openbsd"
|
|
),
|
|
feature = "smithay-clipboard"
|
|
))]
|
|
smithay: Option<smithay_clipboard::Clipboard>,
|
|
|
|
/// Fallback manual clipboard.
|
|
clipboard: String,
|
|
}
|
|
|
|
impl Clipboard {
|
|
#[allow(unused_variables)]
|
|
pub fn new(#[allow(unused_variables)] wayland_display: Option<*mut c_void>) -> Self {
|
|
Self {
|
|
#[cfg(feature = "arboard")]
|
|
arboard: init_arboard(),
|
|
#[cfg(all(
|
|
any(
|
|
target_os = "linux",
|
|
target_os = "dragonfly",
|
|
target_os = "freebsd",
|
|
target_os = "netbsd",
|
|
target_os = "openbsd"
|
|
),
|
|
feature = "smithay-clipboard"
|
|
))]
|
|
smithay: init_smithay_clipboard(wayland_display),
|
|
clipboard: Default::default(),
|
|
}
|
|
}
|
|
|
|
pub fn get(&mut self) -> Option<String> {
|
|
#[cfg(all(
|
|
any(
|
|
target_os = "linux",
|
|
target_os = "dragonfly",
|
|
target_os = "freebsd",
|
|
target_os = "netbsd",
|
|
target_os = "openbsd"
|
|
),
|
|
feature = "smithay-clipboard"
|
|
))]
|
|
if let Some(clipboard) = &mut self.smithay {
|
|
return match clipboard.load() {
|
|
Ok(text) => Some(text),
|
|
Err(err) => {
|
|
tracing::error!("Paste error: {}", err);
|
|
None
|
|
}
|
|
};
|
|
}
|
|
|
|
#[cfg(feature = "arboard")]
|
|
if let Some(clipboard) = &mut self.arboard {
|
|
return match clipboard.get_text() {
|
|
Ok(text) => Some(text),
|
|
Err(err) => {
|
|
tracing::error!("Paste error: {}", err);
|
|
None
|
|
}
|
|
};
|
|
}
|
|
|
|
Some(self.clipboard.clone())
|
|
}
|
|
|
|
pub fn set(&mut self, text: String) {
|
|
#[cfg(all(
|
|
any(
|
|
target_os = "linux",
|
|
target_os = "dragonfly",
|
|
target_os = "freebsd",
|
|
target_os = "netbsd",
|
|
target_os = "openbsd"
|
|
),
|
|
feature = "smithay-clipboard"
|
|
))]
|
|
if let Some(clipboard) = &mut self.smithay {
|
|
clipboard.store(text);
|
|
return;
|
|
}
|
|
|
|
#[cfg(feature = "arboard")]
|
|
if let Some(clipboard) = &mut self.arboard {
|
|
if let Err(err) = clipboard.set_text(text) {
|
|
tracing::error!("Copy/Cut error: {}", err);
|
|
}
|
|
return;
|
|
}
|
|
|
|
self.clipboard = text;
|
|
}
|
|
}
|
|
|
|
#[cfg(feature = "arboard")]
|
|
fn init_arboard() -> Option<arboard::Clipboard> {
|
|
match arboard::Clipboard::new() {
|
|
Ok(clipboard) => Some(clipboard),
|
|
Err(err) => {
|
|
tracing::error!("Failed to initialize clipboard: {}", err);
|
|
None
|
|
}
|
|
}
|
|
}
|
|
|
|
#[cfg(all(
|
|
any(
|
|
target_os = "linux",
|
|
target_os = "dragonfly",
|
|
target_os = "freebsd",
|
|
target_os = "netbsd",
|
|
target_os = "openbsd"
|
|
),
|
|
feature = "smithay-clipboard"
|
|
))]
|
|
fn init_smithay_clipboard(
|
|
wayland_display: Option<*mut c_void>,
|
|
) -> Option<smithay_clipboard::Clipboard> {
|
|
if let Some(display) = wayland_display {
|
|
#[allow(unsafe_code)]
|
|
Some(unsafe { smithay_clipboard::Clipboard::new(display) })
|
|
} else {
|
|
tracing::error!("Cannot initialize smithay clipboard without a display handle!");
|
|
None
|
|
}
|
|
}
|