fix(terminal): repaint after WebGL attach (#1817)

Centralize the xterm refresh after successful WebGL attachment so resumed, reparented, or setting-toggled panes do not show a stale empty WebGL canvas until the next output or resize.
This commit is contained in:
Neil
2026-05-14 01:18:53 -07:00
committed by GitHub
parent e2e6f43b2a
commit 2908367186
3 changed files with 20 additions and 8 deletions
@@ -96,6 +96,7 @@ describe('attachWebgl', () => {
attachWebgl(pane)
expect(pane.terminal.loadAddon).toHaveBeenCalledTimes(1)
expect(webglMock.contextLossHandler).not.toBeNull()
vi.mocked(pane.terminal.refresh).mockClear()
webglMock.contextLossHandler?.()
@@ -109,6 +110,14 @@ describe('attachWebgl', () => {
expect(pane.terminal.loadAddon).toHaveBeenCalledTimes(1)
})
it('repaints the current buffer after WebGL attaches', () => {
const pane = createPane()
attachWebgl(pane)
expect(pane.terminal.refresh).toHaveBeenCalledWith(0, 23)
})
it('does not attach WebGL while initial rendering is deferred', () => {
const pane = createPane()
pane.webglAttachmentDeferred = true
@@ -47,13 +47,5 @@ export function resumePaneRendering(panes: Iterable<ManagedPaneInternal>): void
for (const pane of panes) {
pane.webglAttachmentDeferred = false
reattachWebglIfNeeded(pane)
// Why: fresh WebGL canvas has no content — refresh prevents frozen terminal.
if (pane.webglAddon) {
try {
pane.terminal.refresh(0, pane.terminal.rows - 1)
} catch {
/* ignore */
}
}
}
}
@@ -21,6 +21,16 @@ function shouldUseWebgl(pane: ManagedPaneInternal): boolean {
)
}
function refreshTerminalAfterWebglAttach(pane: ManagedPaneInternal): void {
try {
// Why: a newly attached WebGL canvas starts empty; repaint immediately so
// resume/reparent/settings toggles do not look frozen until new output.
pane.terminal.refresh(0, pane.terminal.rows - 1)
} catch {
/* ignore — pane may have been disposed in the meantime */
}
}
export function disposeWebgl(
pane: ManagedPaneInternal,
options?: { refreshDimensions?: boolean }
@@ -84,6 +94,7 @@ export function attachWebgl(pane: ManagedPaneInternal): void {
})
pane.terminal.loadAddon(webglAddon)
pane.webglAddon = webglAddon
refreshTerminalAfterWebglAttach(pane)
} catch (err) {
if (pane.terminalGpuAcceleration === 'auto') {
// Why: mirrors VS Code's `terminal.integrated.gpuAcceleration=auto`