fix: wl-copy --paste-once for fast clipboard on Wayland/GNOME
Some checks are pending
Build & Release / Build & test (push) Waiting to run
Build & Release / Build .deb (push) Blocked by required conditions

This commit is contained in:
Khoa Vo 2026-07-01 12:41:56 +07:00
parent 800d33e6a7
commit cc05e02559

View file

@ -495,27 +495,43 @@ impl UinputInjector {
fn copy_to_clipboard(s: &str) -> bool { fn copy_to_clipboard(s: &str) -> bool {
let is_wayland = std::env::var("WAYLAND_DISPLAY").is_ok(); let is_wayland = std::env::var("WAYLAND_DISPLAY").is_ok();
let (prog, args): (&str, &[&str]) = if is_wayland { let (prog, args): (&str, &[&str]) = if is_wayland {
("wl-copy", &[]) // On Wayland/GNOME, wl-copy exits before the compositor reads
// the clipboard data. --paste-once keeps it alive until pasted,
// eliminating the 300900ms compositor lookup delay. We spawn
// it detached (no .wait()) — the child lives until Ctrl+V lands.
("wl-copy", &["--paste-once"])
} else { } else {
("xclip", &["-selection", "clipboard", "-i"]) ("xclip", &["-selection", "clipboard", "-i"])
}; };
let mut cmd = Self::user_cmd(prog); let mut cmd = Self::user_cmd(prog);
cmd.args(args); cmd.args(args);
let result = cmd cmd.stdin(std::process::Stdio::piped());
.stdin(std::process::Stdio::piped()) cmd.stdout(std::process::Stdio::null());
.spawn() cmd.stderr(std::process::Stdio::null());
.and_then(|mut child| {
match cmd.spawn() {
Ok(mut child) => {
use std::io::Write; use std::io::Write;
child.stdin.take().unwrap().write_all(s.as_bytes())?; if let Some(mut stdin) = child.stdin.take() {
child.wait() let _ = stdin.write_all(s.as_bytes());
}); }
if let Ok(status) = result { if is_wayland {
if status.success() { // --paste-once: don't wait — child stays alive until the
return true; // compositor reads the data (Ctrl+V arrives later).
// Detach the wait so we don't block.
std::thread::spawn(move || {
let _ = child.wait();
});
return true;
}
// X11: wait for xclip to finish writing
child.wait().map(|s| s.success()).unwrap_or(false)
}
Err(e) => {
eprintln!("[vietc] copy_to_clipboard: {} spawn failed: {}", prog, e);
false
} }
} }
eprintln!("[vietc] copy_to_clipboard: {} failed", prog);
false
} }
/// Send Ctrl+V through our uinput device. /// Send Ctrl+V through our uinput device.