From 32f963869e698232358e50a3173bc908a88a3608 Mon Sep 17 00:00:00 2001 From: Samuel K Date: Mon, 6 Jul 2026 17:24:54 -0500 Subject: [PATCH] fix(desktop): guard terminal ResizeObserver against feedback loop The ResizeObserver callback unconditionally called fit(), refresh(), and the terminalResize IPC on every fire. Since fit() mutates the terminal's dimensions, it could re-fire the observer, sustaining a frame-rate loop that pins the renderer main thread at 100% CPU and freezes the window. Track the last propagated cols/rows and early-return when the grid size is unchanged, so the loop can no longer sustain itself. --- .../src/lib/components/terminal/Terminal.svelte | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/desktop/src/renderer/src/lib/components/terminal/Terminal.svelte b/desktop/src/renderer/src/lib/components/terminal/Terminal.svelte index d43950756..a34c61f8c 100644 --- a/desktop/src/renderer/src/lib/components/terminal/Terminal.svelte +++ b/desktop/src/renderer/src/lib/components/terminal/Terminal.svelte @@ -32,6 +32,8 @@ let containerEl: HTMLDivElement | undefined = $state() let term: Terminal | undefined let fitAddon: FitAddon | undefined let resizeObserver: ResizeObserver | undefined +let lastCols = -1 +let lastRows = -1 const darkTheme = { background: "#1e1e2e", @@ -187,11 +189,13 @@ onMount(async () => { } resizeObserver = new ResizeObserver(() => { - if (fitAddon && term) { - fitAddon.fit() - term.refresh(0, term.rows - 1) - terminalResize(sessionId, term.cols, term.rows) - } + if (!fitAddon || !term) return + fitAddon.fit() + if (term.cols === lastCols && term.rows === lastRows) return + lastCols = term.cols + lastRows = term.rows + term.refresh(0, term.rows - 1) + terminalResize(sessionId, term.cols, term.rows) }) resizeObserver.observe(containerEl) })