fix: cancel activate focus frame (#3408)

This commit is contained in:
Neil
2026-05-29 18:35:24 -07:00
committed by GitHub
parent 216f5a12d9
commit ff6b66efee
2 changed files with 50 additions and 1 deletions
@@ -0,0 +1,38 @@
import { afterEach, describe, expect, it, vi } from 'vitest'
import { activateTabAndFocusPane } from './activate-tab-and-focus-pane'
const setActiveTab = vi.hoisted(() => vi.fn())
vi.mock('@/store', () => ({
useAppStore: {
getState: () => ({
setActiveTab
})
}
}))
describe('activateTabAndFocusPane', () => {
afterEach(() => {
vi.unstubAllGlobals()
vi.clearAllMocks()
})
it('cancels a pending pane focus frame when a newer activation starts', () => {
const cancelAnimationFrame = vi.fn()
vi.stubGlobal(
'requestAnimationFrame',
vi.fn(() => 12)
)
vi.stubGlobal('cancelAnimationFrame', cancelAnimationFrame)
vi.stubGlobal('window', {
dispatchEvent: vi.fn()
})
activateTabAndFocusPane('tab-1', 'leaf-1')
activateTabAndFocusPane('tab-2', 'leaf-2')
expect(setActiveTab).toHaveBeenNthCalledWith(1, 'tab-1')
expect(setActiveTab).toHaveBeenNthCalledWith(2, 'tab-2')
expect(cancelAnimationFrame).toHaveBeenCalledWith(12)
})
})
@@ -1,6 +1,15 @@
import { useAppStore } from '@/store'
import { FOCUS_TERMINAL_PANE_EVENT, type FocusTerminalPaneDetail } from '@/constants/terminal'
let pendingFocusPaneFrameId: number | null = null
function cancelPendingFocusPaneFrame(): void {
if (pendingFocusPaneFrameId !== null) {
cancelAnimationFrame(pendingFocusPaneFrameId)
pendingFocusPaneFrameId = null
}
}
export function activateTabAndFocusPane(
tabId: string,
leafId: string | null,
@@ -11,12 +20,14 @@ export function activateTabAndFocusPane(
}
): void {
useAppStore.getState().setActiveTab(tabId)
cancelPendingFocusPaneFrame()
if (leafId === null) {
return
}
// Why: defer one frame so the new TerminalPane has mounted its
// FOCUS_TERMINAL_PANE_EVENT listener before we dispatch.
requestAnimationFrame(() => {
pendingFocusPaneFrameId = requestAnimationFrame(() => {
pendingFocusPaneFrameId = null
const detail: FocusTerminalPaneDetail = {
tabId,
leafId,