diff --git a/public/index.html b/public/index.html index 3f82dee..7964e5e 100644 --- a/public/index.html +++ b/public/index.html @@ -18179,8 +18179,20 @@

⌨️ Keyboard Shortcuts

// browser restoring focus after an alt-tab — leaves the pane visually active but // deaf. A click on it is an unambiguous "I am typing here"; don't steal focus back // when the user is dragging out a selection. + // + // Copy-on-select rides the same mouseup. xterm has no built-in option for it + // (that was an xterm v4 option, removed upstream), and a right-click can't + // fall back to the browser's native "Copy" because xterm clears the selection + // on the right mousedown before the context menu opens. It is NOT wired to + // `term.onSelectionChange`: that fires from the selection service's refresh on + // every animation frame while the mouse is still dragging, which is a + // clipboard write per frame — and over plain http `copyText()` falls back to a + // focused off-screen textarea, so it would also steal focus mid-drag. host.addEventListener('mouseup', () => { - if (term.hasSelection && term.hasSelection()) return; + if (term.hasSelection && term.hasSelection()) { + copyText(term.getSelection()).catch(() => {}); + return; + } try { term.focus(); } catch {} }); _connectTerminalWs(sessionId); diff --git a/test/composer-terminal.test.js b/test/composer-terminal.test.js index d774711..efa6877 100644 --- a/test/composer-terminal.test.js +++ b/test/composer-terminal.test.js @@ -203,8 +203,13 @@ check('a reconnect refocuses the pane', /ws\.onopen = \(\) => \{[\s\S]{0,700}?requestAnimationFrame\(\(\) => \{ try \{ term\.focus\(\); \} catch \{\} \}\);/.test(TB), true); check('clicking the pane refocuses it', /host\.addEventListener\('mouseup'[\s\S]{0,260}?term\.focus\(\)/.test(TB), true); -check('but not while a selection is being dragged out', - /host\.addEventListener\('mouseup'[\s\S]{0,160}?if \(term\.hasSelection && term\.hasSelection\(\)\) return;/.test(TB), true); +check('but not while a selection is being dragged out — that mouseup copies the selection instead', + /host\.addEventListener\('mouseup'[\s\S]{0,160}?if \(term\.hasSelection && term\.hasSelection\(\)\) \{\s*copyText\(term\.getSelection\(\)\)[^\n]*\n\s*return;/.test(TB), true); +// xterm fires onSelectionChange from the selection service's refresh on every +// animation frame while the mouse is still dragging — a clipboard write per frame, +// and over plain http copyText()'s textarea fallback steals focus mid-drag. +check('copy-on-select is not wired to term.onSelectionChange', + /term\.onSelectionChange\(/.test(TB), false); console.log('\n— i18n: the three new keys exist in all five locales —');