fix: user workflow deadlock (#677)
This commit is contained in:
@@ -71,6 +71,39 @@ function createKeyEventHandler(options: TerminalKeyHandlerOptions) {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Defer WebGL addon loading to the next animation frame so the initial
|
||||
* synchronous work (Terminal + FitAddon + open) stays within the browser's
|
||||
* frame budget.
|
||||
*
|
||||
* Skips WebGL on Firefox: its canvas fingerprinting protection silently
|
||||
* poisons readback data, corrupting the glyph texture atlas.
|
||||
*/
|
||||
function deferWebGLAddon(refs: Pick<TerminalInitOptions, "xtermRef" | "webglAddonRef">) {
|
||||
const isFirefox = typeof navigator !== "undefined" && /firefox/i.test(navigator.userAgent);
|
||||
if (isFirefox) {
|
||||
log("Skipping WebGL addon on Firefox (canvas fingerprinting protection)");
|
||||
return;
|
||||
}
|
||||
requestAnimationFrame(() => {
|
||||
const term = refs.xtermRef.current;
|
||||
if (!term || refs.webglAddonRef.current) return;
|
||||
try {
|
||||
const webglAddon = new WebglAddon();
|
||||
webglAddon.onContextLoss(() => {
|
||||
log("WebGL context lost");
|
||||
webglAddon.dispose();
|
||||
refs.webglAddonRef.current = null;
|
||||
});
|
||||
term.loadAddon(webglAddon);
|
||||
refs.webglAddonRef.current = webglAddon;
|
||||
log("WebGL addon loaded");
|
||||
} catch (e) {
|
||||
log("WebGL failed, using canvas:", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function initTerminalInstance(
|
||||
termContainer: HTMLDivElement,
|
||||
refs: Pick<
|
||||
@@ -121,26 +154,7 @@ function initTerminalInstance(
|
||||
}
|
||||
refs.xtermRef.current = terminal;
|
||||
refs.fitAddonRef.current = fitAddon;
|
||||
// Defer WebGL addon loading to the next animation frame so the initial
|
||||
// synchronous work (Terminal + FitAddon + open) stays within the browser's
|
||||
// frame budget and avoids "Violation: 'setTimeout' handler took Xms" warnings.
|
||||
requestAnimationFrame(() => {
|
||||
const term = refs.xtermRef.current;
|
||||
if (!term || refs.webglAddonRef.current) return;
|
||||
try {
|
||||
const webglAddon = new WebglAddon();
|
||||
webglAddon.onContextLoss(() => {
|
||||
log("WebGL context lost");
|
||||
webglAddon.dispose();
|
||||
refs.webglAddonRef.current = null;
|
||||
});
|
||||
term.loadAddon(webglAddon);
|
||||
refs.webglAddonRef.current = webglAddon;
|
||||
log("WebGL addon loaded");
|
||||
} catch (e) {
|
||||
log("WebGL failed, using canvas:", e);
|
||||
}
|
||||
});
|
||||
deferWebGLAddon(refs);
|
||||
exposeBufferReader(termContainer, terminal);
|
||||
const handleResize = () => {
|
||||
const rect = termContainer.getBoundingClientRect();
|
||||
|
||||
Reference in New Issue
Block a user