fix(desktop): cover nested terminal layout changes

This commit is contained in:
Andy 2026-07-17 15:44:44 +08:00 committed by Brooklyn Nicholson
parent 651a313d2b
commit 9aaabdcbf4
2 changed files with 25 additions and 3 deletions

View file

@ -14,6 +14,7 @@ vi.mock('./workspace', () => ({
let resizeObserverCallback: ResizeObserverCallback | null = null
let mutationObserverCallback: MutationCallback | null = null
let mutationObserveCalls: Array<{ options?: MutationObserverInit; target: Node }> = []
let root: Root | null = null
let container: HTMLDivElement | null = null
let windowStateCallback: ((payload: { isMinimized?: boolean; isVisible?: boolean }) => void) | null = null
@ -128,6 +129,7 @@ describe('PersistentTerminal rect tracking', () => {
installWindowStateBridge()
resizeObserverCallback = null
mutationObserverCallback = null
mutationObserveCalls = []
vi.stubGlobal(
'ResizeObserver',
class {
@ -148,7 +150,9 @@ describe('PersistentTerminal rect tracking', () => {
}
disconnect = vi.fn()
observe = vi.fn()
observe = vi.fn((target: Node, options?: MutationObserverInit) => {
mutationObserveCalls.push({ options, target })
})
takeRecords = vi.fn(() => [])
} as unknown as typeof MutationObserver
)
@ -206,6 +210,8 @@ describe('PersistentTerminal rect tracking', () => {
render(<Harness />)
expect(mutationObserveCalls.some(call => call.options?.subtree === true)).toBe(true)
act(() => {
raf.runNext()
})
@ -287,4 +293,18 @@ describe('PersistentTerminal rect tracking', () => {
})
expect(raf.pending()).toBe(0)
})
it('does not schedule an initial frame when mounted while unfocused', () => {
const raf = installRaf()
vi.mocked(document.hasFocus).mockReturnValue(false)
vi.spyOn(HTMLElement.prototype, 'getBoundingClientRect').mockReturnValue(rect(10, 20, 200, 100))
render(<Harness />)
expect(raf.request).not.toHaveBeenCalled()
act(() => window.dispatchEvent(new Event('focus')))
expect(raf.pending()).toBe(1)
})
})

View file

@ -161,6 +161,8 @@ export function PersistentTerminal({ onAddSelectionToChat }: PersistentTerminalP
scheduleMeasure()
})
pauseController = createRendererLoopPauseController(handleVisibilityChange)
if (measure()) {
scheduleMeasure()
}
@ -171,13 +173,13 @@ export function PersistentTerminal({ onAddSelectionToChat }: PersistentTerminalP
positionObserver?.observe(node, {
attributeFilter: ['class', 'style', 'hidden', 'aria-hidden', 'data-state'],
attributes: true,
childList: true
childList: true,
subtree: true
})
}
window.addEventListener('resize', scheduleMeasure)
window.addEventListener('scroll', scheduleMeasure, true)
pauseController = createRendererLoopPauseController(handleVisibilityChange)
return () => {
stopped = true