fix: wl-copy --paste-once for fast clipboard on Wayland/GNOME
This commit is contained in:
parent
800d33e6a7
commit
cc05e02559
1 changed files with 29 additions and 13 deletions
|
|
@ -495,28 +495,44 @@ 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 300–900 ms 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 is_wayland {
|
||||||
|
// --paste-once: don't wait — child stays alive until the
|
||||||
|
// compositor reads the data (Ctrl+V arrives later).
|
||||||
|
// Detach the wait so we don't block.
|
||||||
|
std::thread::spawn(move || {
|
||||||
|
let _ = child.wait();
|
||||||
});
|
});
|
||||||
if let Ok(status) = result {
|
|
||||||
if status.success() {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
// X11: wait for xclip to finish writing
|
||||||
|
child.wait().map(|s| s.success()).unwrap_or(false)
|
||||||
}
|
}
|
||||||
eprintln!("[vietc] copy_to_clipboard: {} failed", prog);
|
Err(e) => {
|
||||||
|
eprintln!("[vietc] copy_to_clipboard: {} spawn failed: {}", prog, e);
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Send Ctrl+V through our uinput device.
|
/// Send Ctrl+V through our uinput device.
|
||||||
fn send_ctrl_v(&self) {
|
fn send_ctrl_v(&self) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue