fix(terminal): Render with xterm's DOM renderer

The WebGL renderer rasterizes each glyph against its cell background, so
text over the selection came out at a visibly lighter weight than the
rest and looked like a different font. The DOM renderer draws text like
the editor does, selected or not.

Claude-Session: https://claude.ai/code/session_01B65qLEKnkeYTGdbwhLpjCu
Цей коміт міститься в:
l0ng-ai committed 2026-10-24 13:42:07 +08:00
1 джерело 86f1f666d7
коміт 99b4f8bdf6
3 files changed
+2 -23

No files matched your search

+2 -14
Переглянути файл
@@ -286,9 +286,10 @@ export class TerminalSession {
if (this.host.parentElement !== container) container.appendChild(this.host);
if (!this.opened) {
this.opened = true;
// xterm's DOM renderer: the WebGL one rasterizes glyphs per background, so
// selected text rendered at a visibly different weight than the rest.
this.term.open(this.host);
this.term.textarea?.addEventListener("focus", () => this.opts.onFocus(this.key));
void this.loadRenderer();
}
this.resizeObserver?.disconnect();
this.resizeObserver = new ResizeObserver(() => this.scheduleFit());
@@ -302,19 +303,6 @@ export class TerminalSession {
if (this.host.parentElement === container) container.removeChild(this.host);
}
private async loadRenderer() {
// WebGL when available; xterm's DOM renderer is the built-in fallback.
try {
const { WebglAddon } = await import("@xterm/addon-webgl");
if (this.disposed) return;
const webgl = new WebglAddon();
webgl.onContextLoss(() => webgl.dispose());
this.term.loadAddon(webgl);
} catch {
/* no WebGL: keep the DOM renderer */
}
}
private scheduleFit() {
if (this.fitRaf) return;
const run = () => {