From 738e01bb7c54724bc3eda13d2d16cc8f90c0efc1 Mon Sep 17 00:00:00 2001 From: Fusion Date: Sun, 24 May 2026 19:31:15 +0200 Subject: [PATCH] fix: add window resize fallback and delay refresh to next frame - Add window resize listener as fallback for ResizeObserver - Use 250ms debounce to avoid early layout reads - Delay term.refresh() to next animation frame so renderer can process resize before we force redraw - Clean up window resize listener on unmount --- apps/web/src/components/terminal.tsx | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/apps/web/src/components/terminal.tsx b/apps/web/src/components/terminal.tsx index f418772..e126688 100644 --- a/apps/web/src/components/terminal.tsx +++ b/apps/web/src/components/terminal.tsx @@ -229,7 +229,10 @@ export const TerminalComponent: React.FC = ({ fitAddonRef.current.fit(); const { cols, rows } = termRef.current; if (cols !== oldCols || rows !== oldRows) { - termRef.current.refresh(0, rows - 1); + // Delay refresh to next frame so renderer can process resize first + requestAnimationFrame(() => { + termRef.current?.refresh(0, rows - 1); + }); } if (ws.readyState === WebSocket.OPEN) { ws.send(JSON.stringify({ type: "resize", cols, rows })); @@ -290,6 +293,19 @@ export const TerminalComponent: React.FC = ({ }); resizeObserver.observe(container); + // Also listen for window resize as fallback (ResizeObserver might miss some cases) + let windowResizeTimeout: ReturnType; + const handleWindowResize = () => { + clearTimeout(windowResizeTimeout); + windowResizeTimeout = setTimeout(() => { + requestAnimationFrame(() => { + if (!container.isConnected) return; + fitTerminal(); + }); + }, 250); + }; + window.addEventListener("resize", handleWindowResize); + // Refit after mobile header auto-hides (3s delay + 0.3s transition) const headerHideTimeout = setTimeout(() => { fitTerminal(); @@ -322,8 +338,10 @@ export const TerminalComponent: React.FC = ({ return () => { clearTimeout(resizeTimeout); + clearTimeout(windowResizeTimeout); clearTimeout(headerHideTimeout); resizeObserver.disconnect(); + window.removeEventListener("resize", handleWindowResize); document.removeEventListener("visibilitychange", handleVisibilityChange); if (ws) { ws.close();