fix(terminal): let app shortcuts pass through xterm terminals#1411
Conversation
…laction#1410) Cmd+. (toggle right sidebar) and other app shortcuts were swallowed when an xterm terminal had focus. Two issues contributed: 1. The terminal's custom key handler returned true for unhandled Cmd+key combos, telling xterm to consume them. Added a modifier guard that returns false so these events propagate to the window. 2. The global shortcut handler skipped shortcuts when event.target was a TEXTAREA — but xterm uses a hidden textarea for keyboard capture. Excluded xterm's xterm-helper-textarea from the editable-target check so app shortcuts fire from terminals. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When Cmd+. collapses the right sidebar, any focused element inside it (such as xterm's hidden textarea) is now blurred so focus returns to the main content area. Agent terminals in the main panel are unaffected. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
@ckafrouni is attempting to deploy a commit to the General Action Team on Vercel. A member of the Team first needs to authorize it. |
Greptile SummaryThis PR fixes a two-layer problem that caused app-level keyboard shortcuts ( Key changes:
Critical regression on Linux/Windows: The Confidence Score: 2/5
|
| Filename | Overview |
|---|---|
| src/renderer/terminal/TerminalSessionManager.ts | New return false guard for Ctrl+key combos on non-Mac platforms is too broad — it blocks Ctrl+C (SIGINT), Ctrl+D (EOF), Ctrl+Z (SIGTSTP), and all other xterm control-character sequences from reaching the PTY, breaking fundamental terminal functionality on Linux/Windows. |
| src/renderer/hooks/useKeyboardShortcuts.ts | Correctly excludes xterm-helper-textarea from the editable-target check using classList.contains, with safe optional chaining. Logic is sound and targeted. |
| src/renderer/components/RightSidebar.tsx | Adds asideRef and a useEffect to blur any focused element inside the sidebar when it collapses. Implementation is clean and correctly scoped to the sidebar subtree. |
Sequence Diagram
sequenceDiagram
participant User
participant xterm as xterm.js<br/>(xterm-helper-textarea)
participant TSM as TerminalSessionManager<br/>attachCustomKeyEventHandler
participant PTY as PTY Process
participant KS as useKeyboardShortcuts<br/>(window keydown)
participant App as App Handler
Note over User,App: Before this PR — Cmd+. in terminal (macOS)
User->>xterm: Cmd+. keydown
xterm->>TSM: custom handler (returns true)
TSM-->>xterm: true → xterm processes it
Note over KS: target is TEXTAREA → isEditableTarget=true<br/>shortcut skipped
Note over App: Cmd+. never reaches app
Note over User,App: After this PR — Cmd+. in terminal (macOS)
User->>xterm: Cmd+. keydown
xterm->>TSM: custom handler
Note over TSM: metaKey + not in handled list → return false
TSM-->>xterm: false → xterm skips it, event propagates
xterm->>KS: keydown bubbles to window
Note over KS: isXtermTextarea=true → isEditableTarget=false<br/>shortcut matched
KS->>App: toggleRightSidebar()
App->>xterm: sidebar collapses → RightSidebar useEffect blurs focused element
xterm-->>User: focus returned to main area
Note over User,App: Regression — Ctrl+C (no selection) on Linux
User->>xterm: Ctrl+C keydown (no selection)
xterm->>TSM: custom handler
Note over TSM: copy handler skipped (no selection)<br/>new guard: ctrlKey + non-Mac → return false
TSM-->>xterm: false → xterm does NOT send SIGINT to PTY
PTY-->>User: running process NOT interrupted ❌
Last reviewed commit: 34c905b
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…fier guard Replaces the broad Cmd+key / Ctrl+key pass-through with a precise check against registered app shortcut keys. This prevents breaking terminal control sequences (Ctrl+C, Ctrl+D, Ctrl+Z, etc.) on Linux/Windows where Ctrl is used for both app shortcuts and terminal signals.
|
I'm using APP_SHORTCUTS now, so only actual app shortcuts passthrough now. |
|
Thanks for catching this and for taking this on! |
Fixes #1410 —
Cmd+.(toggle right sidebar) and other app shortcuts were swallowed when focus was in any xterm.js terminal.Root cause (two layers):
Terminal handler consumed the event:
TerminalSessionManager.ts'sattachCustomKeyEventHandlerreturnedtruefor unhandledCmd+keycombos, telling xterm to process them and preventing propagation to the global shortcut listener.Global shortcut handler skipped the event:
useKeyboardShortcuts.tstreats anyTEXTAREAtarget as an editable field and skips most shortcuts — but xterm uses a hidden<textarea class="xterm-helper-textarea">for keyboard capture, so all app shortcuts were silently skipped when a terminal had focus.Fix (3 parts):
Centralized shortcut check in the terminal handler (
TerminalSessionManager.ts): Instead of a broad modifier guard that would break terminal control sequences (Ctrl+C,Ctrl+D,Ctrl+Z, etc.) on Linux/Windows, the terminal handler now importsAPP_SHORTCUTSand pre-computes sets of registered shortcut keys. Only key combos that match an actual app shortcut pass through to the global handler — everything else stays with xterm. This is cross-platform safe and automatically covers future shortcuts.xterm textarea exclusion in the global handler (
useKeyboardShortcuts.ts): Excluded xterm'sxterm-helper-textareafrom the editable-target check so app shortcuts are recognized when originating from a terminal.Sidebar focus blur (
RightSidebar.tsx): When the right sidebar collapses, any focused element inside it (e.g. the sidebar terminal) is blurred so focus returns to the main content area. Agent terminals in the main panel are unaffected.Test plan
Cmd+.→ right sidebar togglesCmd+.→ sidebar closes and terminal loses focusCmd+B→ left sidebar togglesCmd+K→ command palette opensCmd+Cstill copies selected text in terminalCmd+Backspacestill clears the lineCmd+Left/Rightstill navigates to start/end of line