Closes#211. Copying from the terminal only worked through the browser
context menu, because xterm turns Ctrl+C into 0x03 and cancels the keydown,
so the muscle-memory copy failed silently and read as "no copy-paste at all".
With a selection, Ctrl+C now copies it, toasts, clears the selection and
sends nothing to the PTY. With no selection it falls through unchanged, so
the interrupt is intact. Ctrl+Shift+C is an explicit copy chord that never
falls through: an explicit copy that interrupts a running agent because the
selection happened to be empty would be a footgun.
Three details that keep the interrupt safe:
- The decision lives in attachCustomKeyEventHandler (terminal-ui.js) and the
no-selection path returns true WITHOUT preventDefault. xterm calls the
custom handler before its own cancel(), so returning false alone does not
cancel the event; the copy path therefore calls preventDefault explicitly,
or the browser would run its native copy on top of ours.
- copy-selection is a full registry entry (rebindable and disableable in App
Settings) whose action is deliberately absent from SHORTCUT_ACTIONS, the
same trick command-palette uses: the generic capture loop preventDefaults
every match it dispatches, which would cost the user the interrupt key.
- The gate is keydown-only, since the custom handler also runs for keypress
and keyup.
Copy goes through _copyText (Clipboard API, then hidden-textarea +
execCommand) rather than raw navigator.clipboard, because install.sh's LAN
option serves plain HTTP where navigator.clipboard is undefined; the
fallback steals focus, so the terminal is refocused afterwards.
Tests: test/terminal-copy-selection.test.ts pins the gate and the
SHORTCUT_ACTIONS invariant; test/terminal-copy-shortcut.test.ts drives real
key presses in chromium and asserts on the clipboard plus the bytes xterm
emitted (browser-driven, so excluded from test:ci like the other Playwright
suites). Verified manually on an isolated beta instance before landing.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>