From 35c567d2e8ce63587d2dfbdf80cb34099b01f15c Mon Sep 17 00:00:00 2001 From: llc Date: Mon, 27 Jul 2026 13:06:15 +0200 Subject: [PATCH] fix: allow text selection in mouse-tracking sessions on macOS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A TUI that turns on mouse tracking (CSI ?1002h / ?1003h) makes xterm.js forward every drag to the application, so no text can be selected. Terminal.app and iTerm2 let you hold Option to override that; xterm.js gates the same escape hatch behind macOptionClickForcesSelection, which defaults to false. The symptom is misleading: Cmd+C finds no selection, so xterm's copy handler is a no-op and fails silently, leaving the previous clipboard contents in place. The next paste then inserts stale text and reads as a broken paste. Windows and Linux are unaffected — there the override is Shift, which needs no option. --- public/terminal-manager.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/public/terminal-manager.js b/public/terminal-manager.js index 6863b226..54b75ba1 100644 --- a/public/terminal-manager.js +++ b/public/terminal-manager.js @@ -179,6 +179,13 @@ function createTerminalEntry(session) { scrollback: 10000, convertEol: true, allowProposedApi: true, + // A TUI that turns on full mouse tracking (CSI ?1003h) makes xterm forward every + // drag to the application, so normal text selection is dead. Terminal.app and + // iTerm2 let you hold Option to override that; xterm.js requires opting in. + // Without this, selecting (and therefore copying) inside such a session is + // impossible on macOS and Cmd+C silently leaves the previous clipboard contents + // in place. Windows/Linux get the same escape hatch via Shift, which needs no flag. + macOptionClickForcesSelection: true, linkHandler: { activate: (_event, uri) => { if (uri.startsWith('file://') && typeof openFileInPanel === 'function') {