Skip to content

fix: solve #4010 — clear WebGL texture atlas on terminal reattach/resize - #4011

Closed
github-actions[bot] wants to merge 1 commit into
mainfrom
triage/issue-4010-25283678241
Closed

github-actions[bot] wants to merge 1 commit into
mainfrom
triage/issue-4010-25283678241

Conversation

@github-actions

@github-actions github-actions Bot commented May 3, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Root cause: The xterm WebGL renderer keeps glyphs in a texture atlas. On macOS the GPU compositor can drop or corrupt atlas pages during extended usage / display sleep / repeated detach-reattach cycles without firing onContextLoss. xterm.refresh() then paints from the corrupt atlas, producing the RTL-looking glyphs reported in [bug] Terminal intermittently renders English text as RTL-looking gibberish #4010.
  • Fix: Expose clearTextureAtlas() from WebglAddon via createTerminalInWrapper and call it inside fitAndRefresh whenever the cached terminal is reattached to a container (always) or a resize changes terminal dimensions. This forces the GPU renderer to rebuild glyphs on every reattach so stale/garbage texture coordinates can't leak through.
  • Test: v1-terminal-cache.test.ts shadow-tests the decision logic in fitAndRefresh / attachToContainer — verifying atlas invalidation order (clear-before-refresh), forced clear on reattach, conditional clear on resize, and no-op on spurious ResizeObserver fires. Real WebGL/xterm aren't available under bun:test, so the tests mirror the production code paths against mocks.

What changed

  • helpers.ts — createTerminalInWrapper now returns a clearTextureAtlas callback that safely no-ops when WebGL is unavailable (DOM fallback after context loss or addon load failure).
  • v1-terminal-cache.ts — CachedTerminal carries the new callback; fitAndRefresh accepts a clearAtlas option and invokes the callback before xterm.refresh() when forced or when fit changed dimensions; attachToContainer always passes clearAtlas: true.

Why partial vs. full fix

Issue #4010 has no deterministic repro (intermittent during extended terminal sessions). Tab-switch / window-resize is the most common trigger and is fully covered here. Pure idle-corruption (no reattach, no resize) would need additional triggers (focus / visibility / display-wake) — out of scope for this minimal fix.

Test plan

  • bun test apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/ — 72 tests pass (6 new)
  • bun run lint:fix — clean
  • cd apps/desktop && bun run typecheck — clean
  • Manual on macOS: open a terminal, run a long Codex/Claude session, switch tabs back and forth, observe glyph integrity
  • Manual on macOS: resize the window across the terminal pane, observe glyphs after resize

Closes #4010


Summary by cubic

Clears the WebGL texture atlas on terminal reattach and on dimension-changing resize to stop corrupted glyphs on macOS. Rebuilds glyphs before refresh, resolving #4010.

  • Bug Fixes
    • Expose clearTextureAtlas() from WebglAddon via createTerminalInWrapper (no-op if WebGL is unavailable).
    • Update v1-terminal-cache: call fitAndRefresh(..., { clearAtlas: true }) on reattach; clear atlas only when resize changes cols/rows; always clear before xterm.refresh().
    • Add tests for clear-before-refresh order, forced clear on reattach, conditional clear on resize, and no-op on spurious ResizeObserver fires.

Written for commit 96fbaf0. Summary will update on new commits.

Expose `clearTextureAtlas()` from the xterm WebGL addon via
`createTerminalInWrapper` and call it before `xterm.refresh()` in
`fitAndRefresh` whenever the cached terminal is reattached to a
container, or whenever a resize changes the terminal dimensions.

The macOS GPU compositor can drop or corrupt atlas pages without
firing `onContextLoss`, leaving stale glyph textures that paint as
RTL-looking gibberish across an otherwise readable terminal. Forcing
the atlas to rebuild on every reattach removes the stale state.
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.

[bug] Terminal intermittently renders English text as RTL-looking gibberish

1 participant