feat: add wayland clipboard support

This commit is contained in:
Ogulcan Celik 2026-01-08 17:44:29 +03:00 committed by Mario Zechner
parent 9ed88646a8
commit a174578673
2 changed files with 33 additions and 7 deletions

View file

@ -1,5 +1,6 @@
import { execSync } from "child_process";
import { execSync, spawn } from "child_process";
import { platform } from "os";
import { isWaylandSession } from "./clipboard-image.js";
export function copyToClipboard(text: string): void {
const p = platform();
@ -11,17 +12,41 @@ export function copyToClipboard(text: string): void {
} else if (p === "win32") {
execSync("clip", options);
} else {
// Linux - try xclip first, fall back to xsel
try {
execSync("xclip -selection clipboard", options);
} catch {
execSync("xsel --clipboard --input", options);
// Linux - try wl-copy for Wayland, fall back to xclip/xsel for X11
const isWayland = isWaylandSession();
if (isWayland) {
try {
// Verify wl-copy exists (spawn errors are async and won't be caught)
execSync("which wl-copy", { stdio: "ignore" });
// wl-copy with execSync hangs due to fork behavior; use spawn instead
const proc = spawn("wl-copy", [], { stdio: ["pipe", "ignore", "ignore"] });
proc.stdin.on("error", () => {
// Ignore EPIPE errors if wl-copy exits early
});
proc.stdin.write(text);
proc.stdin.end();
proc.unref();
} catch {
// Fall back to xclip/xsel (works on XWayland)
try {
execSync("xclip -selection clipboard", options);
} catch {
execSync("xsel --clipboard --input", options);
}
}
} else {
try {
execSync("xclip -selection clipboard", options);
} catch {
execSync("xsel --clipboard --input", options);
}
}
}
} catch (error) {
const msg = error instanceof Error ? error.message : String(error);
if (p === "linux") {
throw new Error(`Failed to copy to clipboard. Install xclip or xsel: ${msg}`);
const tools = isWaylandSession() ? "wl-copy, xclip, or xsel" : "xclip or xsel";
throw new Error(`Failed to copy to clipboard. Install ${tools}: ${msg}`);
}
throw new Error(`Failed to copy to clipboard: ${msg}`);
}