Repository navigation
fix(app): keep keyboard focus in opened and switched terminals - #57980
Conversation
There was a problem hiding this comment.
The terminal.tsx change looks right: reading the focus request once stops the same mount from running the restore branch and handing focus back to the prompt. I couldn't run the app here because there's no browser in the sandbox, so I only checked the model test (it passes, and fails with the base model.ts) and the type checks (gui-extensions is clean; app fails only on the existing activity-chips.fixture.tsx error you mentioned).
Public API: unchanged. This is an internal dependency bump plus focus handling inside the app.
Concerns:
- The
#review-panelexemption inmodel.tsis broader than the ⌘1–9 case needs. See the inline comment. ghostty-webis pinned to the head commit of an open PR. If that branch is rebased or squash-merged before this lands, the commit could disappear and installs would break. It would be safer to wait for ghostty-web#5 to merge and pin the merge commit.
|
|
||
| if (event.target.closest("#terminal-panel")) return | ||
| // The side region focuses its selected tab trigger or root while switching tabs; only focus leaving it cancels. | ||
| if (event.target.closest("#terminal-panel, #review-panel")) return |
There was a problem hiding this comment.
This exempts focus anywhere in the side region, not just the tab trigger or root that the tab switch focuses. Any request that hasn't been used yet now outlives the user moving to other side-panel content. Two examples:
- Ctrl+Alt+T, then clicking into the file tree or review diff before
pty.createresolves. The pending request survives, and the new terminal takes focus when it mounts. - ⌘2 to a terminal, then ⌘3 to a non-terminal tab before the request is used. The request stays open and later takes focus when that terminal becomes active again.
Could this only ignore the elements the switch itself focuses (the #review-panel root and its tab triggers, e.g. event.target.id === "review-panel" || event.target.closest('#review-panel [role="tab"]'))? Also, this would no longer tie the terminal extension to all of the host's panel DOM.
Summary
ghostty-webto anomalyco/ghostty-web#5, which hides the cursor while the terminal is unfocused and makesopen()mount-only. The branch already includes ghostty-web's mouse reporting fix, so the localghostty-web@0.3.0patch is removed.autoFocusand the same mount then ran the restore branch, handing focus back to the prompt. The terminal now reads the request once.ghostty-web#5 is still open, so the dependency points at its head commit (
e91e38a). It should move to the merge commit once that lands.Recording
The recording below shows the panel-opening fix: Ctrl+` from the prompt, hiding and reopening an existing terminal, and Ctrl+Alt+T for a new one, with focus staying in the terminal each time. It doesn't show the ⌘1–9 fix.
terminal-focus-fix.mp4
Validation
packages/app/component-tests/terminal-focus.spec.ts: a terminal opened with a focus request keeps focus, and one opened without a request leaves focus in the composer. The first case fails without the fix; 10/10 repeats pass at 2 workers.packages/gui-extensions/src/terminal/model.test.ts: focus moving within the side region keeps a terminal focus request, and focus leaving it cancels the request. The first case fails without the fix.bun testandbun typecheckinpackages/gui-extensions;bun typecheckinpackages/app.--no-verify. The pre-push check fails on a type error already on beta:packages/app/src/session/composer/activity-chips.fixture.tsximportsMarkedProviderfrom@opencode/ui/context/marked, which feat(app): highlight code with @pierre/highlights instead of Shiki #57937 removed. Nothing else in the check failed.Added by the opencode bot (AI-generated).
Fixes #57536
Related: #55992