From cd9540b106771eb36591ab02551282149317d4f8 Mon Sep 17 00:00:00 2001 From: megaproxy Date: Fri, 22 May 2026 23:10:51 +0100 Subject: [PATCH] Add Ctrl+Shift+C / Ctrl+Shift+V copy-paste in terminal panes Uses attachCustomKeyEventHandler so xterm doesn't first consume Ctrl+V and inject a raw ^V into the PTY. Paste routes through term.paste() so broadcasting and bracketed paste continue to work. --- src/components/XtermPane.tsx | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/components/XtermPane.tsx b/src/components/XtermPane.tsx index 17a715f..21615ee 100644 --- a/src/components/XtermPane.tsx +++ b/src/components/XtermPane.tsx @@ -169,6 +169,37 @@ export default function XtermPane({ onInputRef.current?.(b64); }); + // Ctrl+Shift+C / Ctrl+Shift+V — copy selection / paste from clipboard. + // Runs before xterm consumes the key, so the textarea never sees a raw + // Ctrl+V (which would otherwise inject ^V into the PTY). term.paste() + // routes through onData → writeToPane, so broadcasting and bracketed + // paste both keep working for free. + term?.attachCustomKeyEventHandler((e) => { + if (e.type !== "keydown") return true; + if (!e.ctrlKey || !e.shiftKey || e.altKey) return true; + if (e.code === "KeyC") { + const sel = term?.getSelection(); + if (sel) { + void navigator.clipboard + .writeText(sel) + .catch((err) => console.warn("clipboard write failed:", err)); + } + e.preventDefault(); + return false; + } + if (e.code === "KeyV") { + e.preventDefault(); + navigator.clipboard + .readText() + .then((text) => { + if (text && term) term.paste(text); + }) + .catch((err) => console.warn("clipboard read failed:", err)); + return false; + } + return true; + }); + // Focus detection: xterm.js doesn't expose onFocus as a first-class event // in all versions, so try the proposed API first then fall back to the DOM. term?.onSelectionChange(() => {}); // ensure addon system is initialised; noop