Revert "fix: terminal shortcuts firing in wrong worktree" (#546)

This commit is contained in:
Brennan Benson
2026-04-12 15:07:23 -07:00
committed by GitHub
parent 220f9747ab
commit 0569eb46a6
2 changed files with 22 additions and 25 deletions
+14 -17
View File
@@ -148,11 +148,7 @@ export default function Terminal(): React.JSX.Element | null {
mountedWorktreeIdsRef.current.delete(id)
}
}
// Why: tracks worktrees that have already been initialized (either by
// auto-creating a first tab or by having tabs on first activation). Once a
// worktree is in this set, closing all its tabs will NOT auto-spawn a
// replacement — the user explicitly chose to close them.
const initializedWorktreesRef = useRef(new Set<string>())
const initialTabCreationGuardRef = useRef<string | null>(null)
// Auto-create first tab when worktree activates
useEffect(() => {
@@ -160,22 +156,27 @@ export default function Terminal(): React.JSX.Element | null {
return
}
if (!activeWorktreeId) {
initialTabCreationGuardRef.current = null
return
}
// Why: skip auto-creation if terminal tabs already exist, or if editor files
// are open for this worktree. The user may have intentionally closed all
// terminal tabs while keeping editors open — auto-spawning a terminal would
// be disruptive.
if (tabs.length > 0 || worktreeFiles.length > 0 || worktreeBrowserTabs.length > 0) {
initializedWorktreesRef.current.add(activeWorktreeId)
if (initialTabCreationGuardRef.current === activeWorktreeId) {
initialTabCreationGuardRef.current = null
}
return
}
// Why: once a worktree has been initialized (had tabs or auto-created one),
// don't auto-create again. This prevents a new terminal from spawning
// immediately after the user closes the last tab. Also guards against
// React StrictMode double-invocation.
if (initializedWorktreesRef.current.has(activeWorktreeId)) {
// In React StrictMode (dev), mount effects are intentionally invoked twice.
// Track the worktree we already initialized so we only create one first tab.
if (initialTabCreationGuardRef.current === activeWorktreeId) {
return
}
initializedWorktreesRef.current.add(activeWorktreeId)
initialTabCreationGuardRef.current = activeWorktreeId
createTab(activeWorktreeId)
}, [
workspaceSessionReady,
@@ -543,11 +544,7 @@ export default function Terminal(): React.JSX.Element | null {
<TabGroupSplitLayout
layout={effectiveLayout}
worktreeId={worktree.id}
// Why: hidden worktrees must not have a focused group, otherwise
// their TerminalPanes register window-level keydown handlers
// that fire alongside the visible worktree's handlers — causing
// shortcuts like Cmd+D to split panes in the wrong worktree.
focusedGroupId={isVisible ? activeGroupIdByWorktree[worktree.id] : undefined}
focusedGroupId={activeGroupIdByWorktree[worktree.id]}
/>
</div>
)
@@ -140,7 +140,7 @@ export function useTerminalKeyboardShortcuts({
if (action.type === 'sendInput') {
e.preventDefault()
e.stopImmediatePropagation()
e.stopPropagation()
const pane = manager.getActivePane() ?? manager.getPanes()[0]
if (!pane) {
return
@@ -165,7 +165,7 @@ export function useTerminalKeyboardShortcuts({
return
}
e.preventDefault()
e.stopImmediatePropagation()
e.stopPropagation()
void window.api.ui.writeClipboardText(selection).catch(() => {
/* ignore clipboard write failures */
})
@@ -176,7 +176,7 @@ export function useTerminalKeyboardShortcuts({
// top-level find-in-page flow to fall back to.
if (action.type === 'toggleSearch') {
e.preventDefault()
e.stopImmediatePropagation()
e.stopPropagation()
setSearchOpen((prev) => !prev)
return
}
@@ -184,7 +184,7 @@ export function useTerminalKeyboardShortcuts({
// Cmd+K clears active pane screen + scrollback.
if (action.type === 'clearActivePane') {
e.preventDefault()
e.stopImmediatePropagation()
e.stopPropagation()
const pane = manager.getActivePane() ?? manager.getPanes()[0]
if (pane) {
pane.terminal.clear()
@@ -199,7 +199,7 @@ export function useTerminalKeyboardShortcuts({
return
}
e.preventDefault()
e.stopImmediatePropagation()
e.stopPropagation()
// Collapse expanded pane before switching
if (expandedPaneIdRef.current !== null) {
@@ -228,7 +228,7 @@ export function useTerminalKeyboardShortcuts({
return
}
e.preventDefault()
e.stopImmediatePropagation()
e.stopPropagation()
const pane = manager.getActivePane() ?? panes[0]
if (!pane) {
return
@@ -243,7 +243,7 @@ export function useTerminalKeyboardShortcuts({
// every pane instead of just the focused one.
if (action.type === 'closeActivePane') {
e.preventDefault()
e.stopImmediatePropagation()
e.stopPropagation()
const pane = manager.getActivePane() ?? manager.getPanes()[0]
if (!pane) {
return
@@ -257,7 +257,7 @@ export function useTerminalKeyboardShortcuts({
// (matches Ghostty behavior).
if (action.type === 'splitActivePane') {
e.preventDefault()
e.stopImmediatePropagation()
e.stopPropagation()
if (expandedPaneIdRef.current !== null) {
setExpandedPane(null)
restoreExpandedLayout()