Skip to content

Commit 16879db

Browse files
committed
refactor: use default xtermjs renderer
1 parent 4cc1651 commit 16879db

4 files changed

Lines changed: 21 additions & 159 deletions

File tree

apps/desktop/package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
"@xterm/addon-search": "^0.16.0",
2020
"@xterm/addon-unicode11": "^0.9.0",
2121
"@xterm/addon-web-links": "^0.12.0",
22-
"@xterm/addon-webgl": "^0.19.0",
2322
"@xterm/xterm": "^6.0.0",
2423
"lucide-react": "^0.453.0",
2524
"prismjs": "^1.29.0",

apps/desktop/src/hooks/useAppState.ts

Lines changed: 20 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,6 @@ interface TerminalRuntime extends TerminalRendererRuntime {
5252
viewportHandler?: (() => void) | null;
5353
viewportRestoreRaf?: number;
5454
activationRaf?: number;
55-
rendererAttachRaf?: number;
56-
webglPostInitTimer?: number;
5755
notificationDisposables?: Array<{ dispose: () => void }>;
5856
}
5957

@@ -733,40 +731,26 @@ export function useAppState(
733731

734732
const {
735733
applyTerminalAppearance,
736-
clearPendingRendererAttach,
737-
ensureWebglRenderer,
738-
loadTerminalFonts,
739734
refreshTerminalRows,
740-
refreshWebglRenderer,
741735
} = useTerminalRenderer();
742736

743737
const applyTerminalAppearanceToRuntime = useCallback(
744-
(runtime: TerminalRuntime, appearance: TerminalAppearance, ensureRenderer = true) => {
738+
(runtime: TerminalRuntime, appearance: TerminalAppearance) => {
745739
if (!runtime.term) {
746740
return;
747741
}
748742
applyTerminalAppearance(runtime, appearance);
749-
if (ensureRenderer) {
750-
ensureWebglRenderer(runtime, appearance);
751-
}
752-
if (runtime.webgl) {
753-
refreshWebglRenderer(runtime);
754-
} else {
755-
refreshTerminalRows(runtime.term);
756-
}
743+
refreshTerminalRows(runtime.term);
757744
scheduleTerminalFit(runtime, true);
758745
},
759-
[applyTerminalAppearance, ensureWebglRenderer, refreshTerminalRows, refreshWebglRenderer, scheduleTerminalFit]
746+
[applyTerminalAppearance, refreshTerminalRows, scheduleTerminalFit]
760747
);
761748

762-
const applyTerminalAppearanceToAll = useCallback(
763-
(appearance: TerminalAppearance, ensureRenderer = true) => {
764-
forEachTerminalRuntime(runtimeRef.current, (runtime) => {
765-
applyTerminalAppearanceToRuntime(runtime, appearance, ensureRenderer);
766-
});
767-
},
768-
[applyTerminalAppearanceToRuntime]
769-
);
749+
const applyTerminalAppearanceToAll = useCallback((appearance: TerminalAppearance) => {
750+
forEachTerminalRuntime(runtimeRef.current, (runtime) => {
751+
applyTerminalAppearanceToRuntime(runtime, appearance);
752+
});
753+
}, [applyTerminalAppearanceToRuntime]);
770754

771755
const activateRuntime = useCallback(
772756
(runtime: TerminalRuntime, options?: { focus?: boolean; clearSelection?: boolean }) => {
@@ -783,7 +767,7 @@ export function useAppState(
783767
return;
784768
}
785769
const appearance = toTerminalAppearance(configRef.current.settings);
786-
applyTerminalAppearanceToRuntime(runtime, appearance, true);
770+
applyTerminalAppearanceToRuntime(runtime, appearance);
787771
if (options?.clearSelection !== false) {
788772
runtime.term.clearSelection();
789773
}
@@ -809,10 +793,6 @@ export function useAppState(
809793
[activateRuntime, restoreRuntimeViewport, scheduleTerminalFit]
810794
);
811795

812-
const refreshTerminalRenderersAfterFontLoad = useCallback(() => {
813-
applyTerminalAppearanceToAll(toTerminalAppearance(configRef.current.settings));
814-
}, [applyTerminalAppearanceToAll, toTerminalAppearance]);
815-
816796
const terminalAppearance = useMemo(
817797
() =>
818798
toTerminalAppearance({
@@ -896,24 +876,12 @@ export function useAppState(
896876
applyTerminalAppearanceToAll(terminalAppearance);
897877
}, [applyTerminalAppearanceToAll, terminalAppearance]);
898878

899-
useEffect(() => {
900-
let cancelled = false;
901-
loadTerminalFonts(terminalAppearance).then(() => {
902-
if (cancelled) {
903-
return;
904-
}
905-
applyTerminalAppearanceToAll(terminalAppearance);
906-
});
907-
return () => {
908-
cancelled = true;
909-
};
910-
}, [applyTerminalAppearanceToAll, loadTerminalFonts, terminalAppearance]);
911-
912879
useEffect(() => {
913880
const fontSet = document.fonts;
914881
if (!fontSet || typeof fontSet.addEventListener !== "function") {
915882
return;
916883
}
884+
917885
let cancelled = false;
918886
const scheduleRefresh = () => {
919887
if (cancelled || fontRefreshRafRef.current !== undefined) {
@@ -924,13 +892,13 @@ export function useAppState(
924892
if (cancelled) {
925893
return;
926894
}
927-
refreshTerminalRenderersAfterFontLoad();
895+
applyTerminalAppearanceToAll(terminalAppearance);
928896
});
929897
};
930-
void fontSet.ready.then(() => {
931-
scheduleRefresh();
932-
});
898+
899+
void fontSet.ready.then(scheduleRefresh);
933900
fontSet.addEventListener("loadingdone", scheduleRefresh);
901+
934902
return () => {
935903
cancelled = true;
936904
fontSet.removeEventListener("loadingdone", scheduleRefresh);
@@ -939,7 +907,7 @@ export function useAppState(
939907
fontRefreshRafRef.current = undefined;
940908
}
941909
};
942-
}, [refreshTerminalRenderersAfterFontLoad]);
910+
}, [applyTerminalAppearanceToAll, terminalAppearance]);
943911

944912
const cycleSession = useCallback(() => {
945913
const list = sessionsRef.current;
@@ -1251,13 +1219,13 @@ export function useAppState(
12511219
runtime.term = term;
12521220
runtime.fit = fit;
12531221
applyTerminalAppearance(runtime, terminalAppearance);
1254-
ensureWebglRenderer(runtime, terminalAppearance);
1222+
refreshTerminalRows(term);
12551223
},
12561224
[
12571225
applyTerminalAppearance,
12581226
attachTerminalHandlers,
12591227
configureTerminalOptions,
1260-
ensureWebglRenderer,
1228+
refreshTerminalRows,
12611229
terminalAppearance,
12621230
]
12631231
);
@@ -1282,7 +1250,6 @@ export function useAppState(
12821250

12831251
const cleanupTerminalRuntimeAttachment = useCallback(
12841252
(runtime: TerminalRuntime) => {
1285-
clearPendingRendererAttach(runtime);
12861253
if (runtime.activationRaf !== undefined) {
12871254
window.cancelAnimationFrame(runtime.activationRaf);
12881255
runtime.activationRaf = undefined;
@@ -1309,7 +1276,7 @@ export function useAppState(
13091276
runtime.resizeRaf = undefined;
13101277
}
13111278
},
1312-
[clearPendingRendererAttach]
1279+
[]
13131280
);
13141281

13151282
const detachTerminalRuntime = useCallback(
@@ -1327,12 +1294,7 @@ export function useAppState(
13271294
detachTerminalRuntime(runtime);
13281295
runtime.notificationDisposables?.forEach((disposable) => disposable.dispose());
13291296
runtime.notificationDisposables = undefined;
1330-
if (runtime.term) {
1331-
runtime.term.dispose();
1332-
} else {
1333-
runtime.webgl?.dispose();
1334-
}
1335-
runtime.webgl = undefined;
1297+
runtime.term?.dispose();
13361298
runtime.term = undefined;
13371299
runtime.fit = undefined;
13381300
runtime.ptyId = undefined;
@@ -1668,8 +1630,6 @@ export function useAppState(
16681630
}
16691631

16701632
const envMap = ensureTermEnv(envListToMap(repo.env));
1671-
const currentSettings = configRef.current.settings;
1672-
await loadTerminalFonts(toTerminalAppearance(currentSettings));
16731633

16741634
const initCommands: string[] = [...initialCommands, `cd ${escapeShellArg(sessionCwd)}`];
16751635
const preCommands = repo.preCommands.trim();
@@ -1718,7 +1678,7 @@ export function useAppState(
17181678
});
17191679
return true;
17201680
},
1721-
[ensureTerminalRuntime, loadTerminalFonts, notify, registerPty, toTerminalAppearance, updateSession]
1681+
[ensureTerminalRuntime, notify, registerPty, updateSession]
17221682
);
17231683

17241684
const restartAgentSession = useCallback(
Lines changed: 1 addition & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { useCallback } from "react";
2-
import { WebglAddon } from "@xterm/addon-webgl";
32
import { Terminal } from "@xterm/xterm";
43

54
export const DEFAULT_TERMINAL_LINE_HEIGHT = 1.25;
@@ -12,9 +11,6 @@ export interface TerminalAppearance {
1211

1312
export interface TerminalRendererRuntime {
1413
term?: Terminal;
15-
webgl?: WebglAddon;
16-
rendererAttachRaf?: number;
17-
webglPostInitTimer?: number;
1814
}
1915

2016
function refreshTerminalRows(term?: Terminal) {
@@ -25,20 +21,6 @@ function refreshTerminalRows(term?: Terminal) {
2521
}
2622

2723
export function useTerminalRenderer() {
28-
const loadTerminalFonts = useCallback((appearance: TerminalAppearance) => {
29-
if (!document.fonts?.load) {
30-
return Promise.resolve();
31-
}
32-
const sample = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
33-
const specs = [
34-
`${appearance.fontSize}px ${appearance.fontFamily}`,
35-
`italic ${appearance.fontSize}px ${appearance.fontFamily}`,
36-
`700 ${appearance.fontSize}px ${appearance.fontFamily}`,
37-
`italic 700 ${appearance.fontSize}px ${appearance.fontFamily}`,
38-
];
39-
return Promise.allSettled(specs.map((spec) => document.fonts.load(spec, sample))).then(() => undefined);
40-
}, []);
41-
4224
const applyTerminalAppearance = useCallback((runtime: TerminalRendererRuntime, appearance: TerminalAppearance) => {
4325
const term = runtime.term;
4426
if (!term) {
@@ -58,6 +40,7 @@ export function useTerminalRenderer() {
5840
root.style.fontFamily = appearance.fontFamily;
5941
root.style.fontSize = fontSizePx;
6042
root.style.lineHeight = lineHeightCss;
43+
6144
const accessibilityTree = root.querySelector(".xterm-accessibility-tree") as HTMLElement | null;
6245
if (accessibilityTree) {
6346
accessibilityTree.style.fontFamily = appearance.fontFamily;
@@ -66,80 +49,8 @@ export function useTerminalRenderer() {
6649
}
6750
}, []);
6851

69-
const clearPendingRendererAttach = useCallback((runtime: TerminalRendererRuntime) => {
70-
if (runtime.rendererAttachRaf !== undefined) {
71-
window.cancelAnimationFrame(runtime.rendererAttachRaf);
72-
runtime.rendererAttachRaf = undefined;
73-
}
74-
if (runtime.webglPostInitTimer !== undefined) {
75-
window.clearTimeout(runtime.webglPostInitTimer);
76-
runtime.webglPostInitTimer = undefined;
77-
}
78-
}, []);
79-
80-
const refreshWebglRenderer = useCallback((runtime: TerminalRendererRuntime) => {
81-
if (!runtime.webgl) {
82-
return;
83-
}
84-
runtime.webgl.clearTextureAtlas();
85-
refreshTerminalRows(runtime.term);
86-
}, []);
87-
88-
const ensureWebglRenderer = useCallback(
89-
(runtime: TerminalRendererRuntime, appearance: TerminalAppearance) => {
90-
const term = runtime.term;
91-
if (!term) {
92-
return;
93-
}
94-
if (runtime.webgl) {
95-
refreshWebglRenderer(runtime);
96-
return;
97-
}
98-
clearPendingRendererAttach(runtime);
99-
void loadTerminalFonts(appearance).then(() => {
100-
if (runtime.term !== term || runtime.webgl) {
101-
return;
102-
}
103-
runtime.rendererAttachRaf = window.requestAnimationFrame(() => {
104-
runtime.rendererAttachRaf = window.requestAnimationFrame(() => {
105-
runtime.rendererAttachRaf = undefined;
106-
if (runtime.term !== term || runtime.webgl) {
107-
return;
108-
}
109-
try {
110-
const webgl = new WebglAddon();
111-
term.loadAddon(webgl);
112-
runtime.webgl = webgl;
113-
webgl.onContextLoss(() => {
114-
if (runtime.webgl === webgl) {
115-
runtime.webgl = undefined;
116-
}
117-
webgl.dispose();
118-
});
119-
refreshWebglRenderer(runtime);
120-
runtime.webglPostInitTimer = window.setTimeout(() => {
121-
runtime.webglPostInitTimer = undefined;
122-
if (runtime.webgl !== webgl) {
123-
return;
124-
}
125-
refreshWebglRenderer(runtime);
126-
}, 100);
127-
} catch {
128-
// Fallback to canvas renderer when WebGL is unavailable.
129-
}
130-
});
131-
});
132-
});
133-
},
134-
[clearPendingRendererAttach, loadTerminalFonts, refreshWebglRenderer]
135-
);
136-
13752
return {
13853
applyTerminalAppearance,
139-
clearPendingRendererAttach,
140-
ensureWebglRenderer,
141-
loadTerminalFonts,
14254
refreshTerminalRows,
143-
refreshWebglRenderer,
14455
};
14556
}

pnpm-lock.yaml

Lines changed: 0 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)