From c4323e40c127cbbdf1c61e5de489186302a8f99b Mon Sep 17 00:00:00 2001 From: centdix Date: Sat, 21 Feb 2026 17:22:43 +0000 Subject: [PATCH] fix: enable clipboard support and suppress browser context menu in web terminal Co-Authored-By: Claude Opus 4.5 --- dev-dashboard/backend/src/terminal.ts | 1 + .../frontend/src/lib/Terminal.svelte | 24 +++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/dev-dashboard/backend/src/terminal.ts b/dev-dashboard/backend/src/terminal.ts index 0d7f6fb484..37ee668469 100644 --- a/dev-dashboard/backend/src/terminal.ts +++ b/dev-dashboard/backend/src/terminal.ts @@ -62,6 +62,7 @@ export async function attach( const cmd = [ `tmux new-session -d -s "${gName}" -t "${tmuxSession}"`, `tmux set-option -t "${gName}" mouse on`, + `tmux set-option -t "${gName}" set-clipboard on`, `tmux select-window -t "${gName}:${windowTarget}"`, `stty rows ${rows} cols ${cols}`, `exec tmux attach-session -t "${gName}"`, diff --git a/dev-dashboard/frontend/src/lib/Terminal.svelte b/dev-dashboard/frontend/src/lib/Terminal.svelte index ef21d60970..6a975858f6 100644 --- a/dev-dashboard/frontend/src/lib/Terminal.svelte +++ b/dev-dashboard/frontend/src/lib/Terminal.svelte @@ -32,6 +32,30 @@ term.loadAddon(new WebLinksAddon()); term.open(containerEl); + // Prevent browser context menu so tmux right-click works unobstructed + containerEl.addEventListener("contextmenu", (e) => e.preventDefault()); + + // Handle OSC 52 sequences from tmux → write to system clipboard + term.parser.registerOscHandler(52, (data) => { + const idx = data.indexOf(";"); + if (idx !== -1) { + const b64 = data.slice(idx + 1); + try { + const text = atob(b64); + navigator.clipboard.writeText(text); + } catch {} + } + return true; + }); + + // Auto-copy on xterm.js selection (e.g. when user Shift+drags to bypass tmux mouse) + term.onSelectionChange(() => { + const sel = term.getSelection(); + if (sel) { + navigator.clipboard.writeText(sel); + } + }); + requestAnimationFrame(() => fitAddon.fit()); const protocol = location.protocol === "https:" ? "wss:" : "ws:";