fix(dashboard): keep terminal WebGL renderer alive across GPU context loss - #252
Merged
Conversation
… loss xterm's WebglAddon was created with no onContextLoss handler. When the GPU drops the addon's WebGL context — common when several terminal panes each hold a context (browsers cap WebGL contexts, and useTerminal creates/disposes one per pane on visibility changes) or after a GPU reset — the addon silently stops painting. The terminal then appears to freeze: characters typed into the PTY only show up once a resize or focus nudge forces a full repaint, which reads as "I type and have to wait for it to appear." Add an IWebglAddon abstraction exposing onContextLoss and a loadWebglAddon() helper that disposes and recreates the addon on context loss, so live rendering resumes immediately. This is xterm's documented recommended handling for the WebGL renderer. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
nox-0x
approved these changes
Jun 25, 2026
nox-0x
left a comment
Collaborator
There was a problem hiding this comment.
Approving — clean, focused fix that follows xterm's documented onContextLoss recovery pattern; the dispose-and-recreate loop is correctly guarded against torn-down state and against late handlers from a stale addon (webglAddon === addon check), and the discarded IDisposable from onContextLoss is fine since addon.dispose() cleans up its own listeners. As the PR notes, runtime repro of GPU context loss wasn't possible, but the fix is strictly more correct regardless.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Recurring report: "sometimes I have to wait for the characters I type into a terminal to appear."
Investigation ruled out the usual suspects:
useState, so per-keystroke store re-renders aren't the cause.fetchSessions/fetchNotificationsequality guards (from the perf: Tier 1 dashboard rendering optimizations #88 perf work) are intact, so polling doesn't trigger a re-render storm.useEffectdeps are stable, so the pane isn't tearing down/rebuilding the WebSocket.pty.onData → ws.send) and client receive path (ws.onmessage → terminal.write) are both immediate, with no batching.That points at the renderer.
xterm-backend.tscreated the WebGL addon asnew WebglAddon()with noonContextLosshandler. When the GPU drops the addon's WebGL context — common because this hook creates/disposes a context per pane on every visibility change and browsers cap WebGL contexts (~16), plus ordinary GPU resets — the addon silently stops painting. The terminal then only updates when a resize/focus nudge forces a full repaint, so typed characters appear to "hang" until then. xterm's docs explicitly require handlingonContextLossand recreating the addon.Fix
IWebglAddonabstraction exposingonContextLoss(terminal/types.ts).useTerminal.tswith aloadWebglAddon()helper that, on context loss, disposes and recreates the addon (when the pane is still visible) so live GPU rendering resumes immediately instead of stalling.Files
packages/dashboard/src/terminal/types.ts—IWebglAddoninterfacepackages/dashboard/src/hooks/useTerminal.ts—loadWebglAddon()with context-loss recoveryTesting
tsc --buildclean; biome clean (one pre-existing unrelated suppression warning atuseTerminal.ts:200)🤖 Generated with Claude Code