fix: disable WebGL renderer to fix black-on-black text in tmux
The xterm.js WebGL addon has known rendering bugs with reverse-video (inverse color) ANSI sequences — exactly what tmux uses for its status bar, pane borders, and selected text. On desktop the WebGL addon loaded successfully, causing characters to render as black-on-black and appear to 'disappear'. On mobile WebGL typically fails to initialize, so the terminal silently fell back to the DOM renderer which handles these color attributes correctly. - Remove WebGL addon loading and its cleanup logic - Remove unused xterm-addon-webgl import and dependency - DOM renderer is the default and correctly handles all ANSI color attributes including reverse video Quality gates: tsc --noEmit (pass), build (pass), bundle -100KB Refs: xterm.js WebGL reverse-video / minimumContrastRatio issues
This commit is contained in:
@@ -8,7 +8,6 @@ import React, {
|
||||
import { Terminal } from "xterm";
|
||||
import { FitAddon } from "xterm-addon-fit";
|
||||
import { WebLinksAddon } from "xterm-addon-web-links";
|
||||
import { WebglAddon } from "xterm-addon-webgl";
|
||||
import "xterm/css/xterm.css";
|
||||
|
||||
import {
|
||||
@@ -310,25 +309,13 @@ export const TerminalComponent = React.forwardRef<TerminalRef, TerminalProps>(
|
||||
term.loadAddon(fitAddon);
|
||||
term.loadAddon(new WebLinksAddon());
|
||||
|
||||
// Load WebGL renderer for GPU acceleration, fall back to DOM
|
||||
let webglAddon: WebglAddon | null = null;
|
||||
try {
|
||||
webglAddon = new WebglAddon();
|
||||
term.loadAddon(webglAddon);
|
||||
webglAddon.onContextLoss(() => {
|
||||
console.warn("WebGL context lost, falling back to DOM renderer");
|
||||
try {
|
||||
webglAddon?.dispose();
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
webglAddon = null;
|
||||
// Trigger a refit since cell dimensions may differ
|
||||
requestAnimationFrame(() => fitTerminal());
|
||||
});
|
||||
} catch (e) {
|
||||
console.warn("WebGL renderer failed to load, using DOM renderer", e);
|
||||
}
|
||||
// NOTE: WebGL renderer disabled.
|
||||
// The WebGL addon causes black-on-black rendering artifacts with
|
||||
// tmux/vim reverse-video (inverse color) sequences on desktop.
|
||||
// Mobile already uses the DOM renderer (WebGL fails there), which
|
||||
// handles these color attributes correctly. The DOM renderer is
|
||||
// fast enough for typical terminal workloads.
|
||||
// See: xterm.js WebGL known issues with reverse video / minimumContrastRatio
|
||||
|
||||
const container = terminalRef.current;
|
||||
|
||||
@@ -585,16 +572,6 @@ export const TerminalComponent = React.forwardRef<TerminalRef, TerminalProps>(
|
||||
window.clearInterval(heartbeatCheckRef.current);
|
||||
heartbeatCheckRef.current = null;
|
||||
}
|
||||
// Dispose WebGL addon BEFORE the terminal to avoid race with
|
||||
// RenderService.setRenderer accessing a disposed renderer
|
||||
if (webglAddon) {
|
||||
try {
|
||||
webglAddon.dispose();
|
||||
} catch {
|
||||
// Ignore disposal errors from partially torn-down terminal
|
||||
}
|
||||
webglAddon = null;
|
||||
}
|
||||
try {
|
||||
term.dispose();
|
||||
} catch {
|
||||
|
||||
Reference in New Issue
Block a user