Skip to content

feat(app): render terminals via WebGL, attached only to the active pane#446

Merged
fujibee merged 2 commits into
mainfrom
feat/webgl-renderer
Jul 20, 2026
Merged

feat(app): render terminals via WebGL, attached only to the active pane#446
fujibee merged 2 commits into
mainfrom
feat/webgl-renderer

Conversation

@fujibee

@fujibee fujibee commented Jul 20, 2026

Copy link
Copy Markdown
Owner

Summary

  • Root cause of issue Desktop app (Windows): input cursor flickers with Codex CLI output in the web-based terminal pane #383's reported flicker: koit determined the original report was the Codex CLI's animated "Working (Ns...)" status text, not the input cursor. Investigation traced this to xterm.js's default DOM renderer, which does a full replaceChildren() DOM-node rebuild of an entire terminal row on every content update — its own source explicitly calls this renderer "not meant to be particularly fast" and describes it as "a fallback for when the webgl addon is slow." A CLI repeatedly recoloring the same status line forces that expensive rebuild on every frame.
  • Adds @xterm/addon-webgl (0.19.0) as the primary renderer. This is a real fix, not a workaround — it's xterm.js's own intended fast path — and also a general performance improvement for all terminal output, not just this one animation.
  • Scoped to the currently active pane only, not mount/unmount: every pane across every tab/team stays mounted for the app's whole session (live PTY + scrollback), so eagerly attaching WebGL to every mounted pane would exhaust the browser's concurrent-WebGL-context cap (Chromium: ~8-16) well before a typical multi-pane session's real pane count. TerminalPane gets a new required active prop; a dedicated effect attaches WebglAddon when the pane becomes active and disposes it (releasing the GPU context) when it goes inactive.
  • Handles real GPU/driver context loss via onContextLoss: disposes and falls back to the default DOM renderer for the rest of that pane's active session — no regression on unsupported/locked-down GPUs, no retry loop.

Test plan

  • tsc --noEmit clean
  • pnpm test — 152 passed (no new tests: the added logic is a thin, non-pure attach/detach effect over real xterm/WebGL objects, consistent with this repo's convention of only unit-testing extracted pure logic — flagging for co1 in case a different call is warranted here)
  • Manually verified live in tauri dev by koit: no rendering breakage or hangs across 3 teams / ~10 panes, switching tabs/teams repeatedly. Visual comparison of shimmer smoothness and the DOM->WebGL anti-aliasing change (ClearType-ish -> more grayscale) also confirmed fine by koit directly.

@fujibee
fujibee merged commit 3f87d60 into main Jul 20, 2026
7 checks passed
@fujibee
fujibee deleted the feat/webgl-renderer branch July 20, 2026 04:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant