diff --git a/apps/desktop/src/app/right-sidebar/terminal/persistent.test.tsx b/apps/desktop/src/app/right-sidebar/terminal/persistent.test.tsx
index 638beaae1a8d..cc6b15c1507f 100644
--- a/apps/desktop/src/app/right-sidebar/terminal/persistent.test.tsx
+++ b/apps/desktop/src/app/right-sidebar/terminal/persistent.test.tsx
@@ -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()
+ 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()
+
+ expect(raf.request).not.toHaveBeenCalled()
+
+ act(() => window.dispatchEvent(new Event('focus')))
+
+ expect(raf.pending()).toBe(1)
+ })
})
diff --git a/apps/desktop/src/app/right-sidebar/terminal/persistent.tsx b/apps/desktop/src/app/right-sidebar/terminal/persistent.tsx
index 5827ec0a8795..3fe2edb04a78 100644
--- a/apps/desktop/src/app/right-sidebar/terminal/persistent.tsx
+++ b/apps/desktop/src/app/right-sidebar/terminal/persistent.tsx
@@ -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