fix(desktop): restore terminal buffer after Unicode 11 activation#3581
Conversation
The persisted xterm buffer was being replayed before the Unicode11Addon was loaded, so CJK, emoji, and ZWJ sequences got parsed with Unicode 6 cell widths. The wrong widths baked into the buffer, producing garbled glyphs on repaint — especially visible with many Claude Code tabs open and Chinese content (#3572). Mirrors VS Code's pattern: load Unicode11Addon during terminal construction, before the first write. Also bumps @xterm/* to the versions VS Code ships (xterm 6.1.0-beta.197, webgl 0.20.0-beta.196).
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughDeferred terminal buffer restoration until xterm addons finish loading; updated several Changes
Sequence Diagram(s)sequenceDiagram
participant App as Desktop App
participant Terminal as Terminal Instance
participant AddonLoader as Addon Loader
participant BufferStore as Buffer Restore
App->>Terminal: createRuntime(wrapper, terminalId)
Terminal->>Terminal: terminal.open(wrapper)
Terminal->>AddonLoader: loadAddons(terminal)
AddonLoader-->>Terminal: addonsResult (search, progress, dispose, ...)
Terminal->>BufferStore: restoreBuffer(terminalId, terminal)
BufferStore-->>Terminal: replay buffer
Terminal-->>App: return TerminalRuntime (includes addons and dispose)
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Possibly related issues
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Greptile SummaryThis PR fixes garbled CJK/emoji rendering when restoring persisted terminal buffers in the desktop app. The root cause was that Key changes:
Confidence Score: 5/5Safe to merge — the fix is minimal, correct, and well-justified by VS Code's own initialization pattern. The one-line reorder is the right fix: No files require special attention.
|
| Filename | Overview |
|---|---|
| apps/desktop/src/renderer/lib/terminal/terminal-runtime.ts | Core fix: moves loadAddons before restoreBuffer in createRuntime() so Unicode 11 cell widths are active before the buffer is replayed; logic is correct and minimal. |
| apps/desktop/package.json | Bumps all @xterm/* packages 2 beta versions (195→197, webgl 194→196) to match VS Code's current pinned versions; straightforward dependency update. |
| bun.lock | Auto-generated lockfile updated to reflect the xterm version bumps in package.json; no manual review needed. |
Sequence Diagram
sequenceDiagram
participant CR as createRuntime()
participant XT as XTerm instance
participant LA as loadAddons()
participant U11 as Unicode11Addon
participant RB as restoreBuffer()
participant LS as localStorage
CR->>XT: new XTerm() + open(wrapper)
Note over CR,XT: Before fix: restoreBuffer ran here (Unicode 6 widths active)
CR->>LA: loadAddons(terminal)
LA->>XT: loadAddon(Unicode11Addon)
LA->>XT: unicode.activeVersion = "11"
Note over XT: Unicode 11 width tables now active
LA-->>CR: searchAddon, progressAddon, dispose
CR->>RB: restoreBuffer(terminalId, terminal)
RB->>LS: getItem(terminal-buffer:id)
LS-->>RB: serialized VT data
RB->>XT: terminal.write(data)
Note over XT: Parses CJK/emoji/ZWJ with correct Unicode 11 widths
Reviews (1): Last reviewed commit: "fix(desktop): restore terminal buffer af..." | Re-trigger Greptile
🧹 Preview Cleanup CompleteThe following preview resources have been cleaned up:
Thank you for your contribution! 🎉 |
Summary
Fixes #3572 — garbled CJK/Latin rendering with many Claude Code tabs open.
unicode.activeVersion = "11") before replaying the persisted terminal buffer. PreviouslyrestoreBufferran first, so xterm parsed CJK / emoji / ZWJ sequences using Unicode 6 cell widths and baked the wrong widths into the restored buffer — producing the garbled glyphs on repaint that the issue reporters and @johann-taberlet both observed (resizing the window forces a reflow, which is why that "fixes" it temporarily)._updateUnicodeVersion()is called during terminal construction (xtermTerminal.ts:302), before any write orattachToElement.@xterm/*to the versions VS Code currently ships (xterm/unicode11/etc.6.1.0-beta.197, webgl0.20.0-beta.196). We were 2 beta versions behind across the board.What I considered and didn't do
The bot investigation noted
onContextLossinterminal-addons.tsdoesn't flip the sharedsuggestedRendererTypeto"dom", so subsequent terminals keep retrying WebGL after a cascading context-loss. I tried adding that fallback, but VS Code deliberately doesn't do it either (xtermTerminal.ts:853-856— only a WebGL load failure flips the flag, not context loss) because a transient GPU hiccup shouldn't disable WebGL app-wide. Leaving our behavior aligned with VS Code.If CJK corruption returns after this lands under heavy multi-tab usage, the next thing to investigate is the WebGL context cap / cascading context-loss path — but that's a separate issue and a more invasive change.
Test plan
Summary by cubic
Fixes garbled CJK/emoji rendering in restored terminals by activating Unicode 11 before replaying the buffer. Aligns terminal init with VS Code to prevent wrong cell widths after reloads and tab switches.
Bug Fixes
unicode.activeVersion = "11") beforerestoreBuffer(...)so CJK/emoji/ZWJ sequences use Unicode 11 widths.Dependencies
@xterm/xtermand addons to6.1.0-beta.197and@xterm/addon-webglto0.20.0-beta.196to match VS Code.Written for commit ea65a58. Summary will update on new commits.
Summary by CodeRabbit
Chores
Bug Fixes