From b3d0b63f4b0601500e7e1c2fea5eda783aca5765 Mon Sep 17 00:00:00 2001 From: "tao.chen" <93983997+taochen-ct@users.noreply.github.com> Date: Fri, 3 Jul 2026 11:03:05 +0800 Subject: [PATCH] fix: defer xterm fit to ResizeObserver ticks Co-Authored-By: Claude --- web/src/components/terminal/TerminalPanel.tsx | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/web/src/components/terminal/TerminalPanel.tsx b/web/src/components/terminal/TerminalPanel.tsx index 77c269b..4016a1b 100644 --- a/web/src/components/terminal/TerminalPanel.tsx +++ b/web/src/components/terminal/TerminalPanel.tsx @@ -34,7 +34,6 @@ export function TerminalPanel() { terminal.writeln("$ pnpm test"); terminal.writeln("mock: 3 files checked, 0 failures"); terminal.write("$ "); - fitAddon.fit(); } catch { setFailed(true); terminal?.dispose(); @@ -42,13 +41,34 @@ export function TerminalPanel() { return; } + let rafId: number | undefined; + const scheduleFit = () => { + if (rafId !== undefined) return; + rafId = requestAnimationFrame(() => { + rafId = undefined; + try { + fitAddon?.fit(); + } catch { + // fit() throws when the container has zero dimensions; ignore + // and wait for the next ResizeObserver tick. + } + }); + }; + + const resizeObserver = new ResizeObserver(scheduleFit); + resizeObserver.observe(container); + const handleResize = () => { - fitAddon?.fit(); + scheduleFit(); }; window.addEventListener("resize", handleResize); return () => { + if (rafId !== undefined) { + cancelAnimationFrame(rafId); + } + resizeObserver.disconnect(); window.removeEventListener("resize", handleResize); terminal?.dispose(); fitAddon?.dispose();