Terminal: Ctrl+C copies a selection (else ^C), Ctrl+V pastes, over http too; drop Log out everywhere

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Mitchell-Johnson
2026-09-19 10:44:17 -07:00
co-authored by Claude Fable 5.1
parent d7ed4d8549
commit d3f2a83249
6 changed files with 28 additions and 28 deletions
+20
View File
@@ -84,6 +84,26 @@ export default function TerminalPane({ id, active, register, onStatus, onExit }:
}
connect()
// Ctrl+C / Ctrl+V as on any desktop. Returning false tells xterm to leave the key alone,
// and *not* preventing the default lets the browser fire its own copy / paste event —
// which xterm answers with its selection, or pastes (bracketed, if the shell asked). That
// path needs no navigator.clipboard, so it works over plain http on the LAN as well.
term.attachCustomKeyEventHandler((e) => {
if (e.type !== 'keydown') return true
const k = e.key.toLowerCase(), ctrl = e.ctrlKey && !e.altKey && !e.metaKey
const copy = (ctrl && k === 'c' && (e.shiftKey || term.hasSelection())) || (ctrl && k === 'insert')
const paste = (ctrl && k === 'v') || (e.shiftKey && !ctrl && k === 'insert')
if (copy) {
if (!term.hasSelection()) { e.preventDefault(); return false } // Ctrl+Shift+C with nothing selected: not devtools, not ^C
if (e.shiftKey) { e.preventDefault(); document.execCommand('copy') } // Chrome keeps Ctrl+Shift+C for itself; copy by hand
if (navigator.clipboard) navigator.clipboard.writeText(term.getSelection()).catch(() => {})
window.setTimeout(() => term.clearSelection(), 50) // so the next Ctrl+C is an interrupt again
return false
}
if (paste) return false
return true
})
term.onData((d) => {
if (ctrlArmed && d.length === 1) {
ctrlArmed = false