#[cfg(target_os = "linux")]
use std::io::Write as _;
#[cfg(target_os = "linux")]
use std::process::{Command, Stdio};
pub fn copy(text: &str) {
#[cfg(target_os = "linux")]
{
if pipe_to("wl-copy", &[], text)
|| pipe_to("xclip", &["-selection", "clipboard"], text)
|| pipe_to("xsel", &["--clipboard", "--input"], text)
{
return;
}
let _ = arboard::Clipboard::new().and_then(|mut ctx| ctx.set_text(text));
}
#[cfg(not(target_os = "linux"))]
{
let _ = arboard::Clipboard::new().and_then(|mut ctx| ctx.set_text(text));
}
}
pub fn paste() -> Option<String> {
if let Ok(mut ctx) = arboard::Clipboard::new()
&& let Ok(text) = ctx.get_text()
{
return Some(text);
}
#[cfg(target_os = "linux")]
return read_from("wl-paste", &["--no-newline"])
.or_else(|| read_from("xclip", &["-selection", "clipboard", "-out"]))
.or_else(|| read_from("xsel", &["--clipboard", "--output"]));
#[cfg(not(target_os = "linux"))]
None
}
#[cfg(target_os = "linux")]
fn pipe_to(cmd: &str, args: &[&str], text: &str) -> bool {
let Ok(mut child) = Command::new(cmd)
.args(args)
.stdin(Stdio::piped())
.stdout(Stdio::null())
.stderr(Stdio::null())
.spawn()
else {
return false;
};
let write_ok = child
.stdin
.take()
.map(|mut s| s.write_all(text.as_bytes()).is_ok())
.unwrap_or(false);
let _ = child.wait();
write_ok
}
#[cfg(target_os = "linux")]
fn read_from(cmd: &str, args: &[&str]) -> Option<String> {
let output = Command::new(cmd)
.args(args)
.stdout(Stdio::piped())
.stderr(Stdio::null())
.output()
.ok()?;
if output.status.success() {
String::from_utf8(output.stdout).ok()
} else {
None
}
}