From bf8c0fd380333f0e3521ece0b339a04505295d1b Mon Sep 17 00:00:00 2001 From: Augustin Date: Fri, 24 Apr 2026 20:35:49 +0200 Subject: [PATCH] fix(terminal): improve terminal dimensions and fit timing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use min-height:0 on xterm-wrapper (flex child) instead of height:100% to properly fill available space in flex layout. Add delayed fit() calls after initialization to let the layout stabilize before calculating terminal cell dimensions. 💘 Generated with Crush Assisted-by: GLM-5.1 via Crush --- web/src/components/Shell.jsx | 14 ++++++++++---- web/src/styles/global.css | 8 ++++---- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/web/src/components/Shell.jsx b/web/src/components/Shell.jsx index 2ae3c00..c5ef38f 100644 --- a/web/src/components/Shell.jsx +++ b/web/src/components/Shell.jsx @@ -439,6 +439,12 @@ export default function Shell({ api }) { const entry = tabsRef.current[tab.id] if (entry) entry.fitAddon.fit() } + setTimeout(() => { + for (const tab of tabsRef.current._tabList || []) { + const entry = tabsRef.current[tab.id] + if (entry) entry.fitAddon.fit() + } + }, 150) }) }, [initTerminal]) @@ -472,11 +478,11 @@ export default function Shell({ api }) { requestAnimationFrame(() => { if (cancelled) return const entry = tabsRef.current[tab.id] - if (entry) entry.fitAddon.fit() + if (entry) { + entry.fitAddon.fit() + setTimeout(() => { if (!cancelled) entry.fitAddon.fit() }, 100) + } }) - } - - for (const tab of tabs) { if (!tabsRef.current[tab.id]) { tryInitTab(tab, 0) } diff --git a/web/src/styles/global.css b/web/src/styles/global.css index 2ccf368..7308dc1 100644 --- a/web/src/styles/global.css +++ b/web/src/styles/global.css @@ -276,8 +276,8 @@ input::placeholder { color: var(--text-disabled); } .sidebar-tab:hover { background: var(--bg-card); color: var(--text-primary); } .sidebar-tab.active { background: var(--accent); color: #fff; font-weight: 600; } -.shell-layout { display: flex; height: 100%; } -.shell-terminal-col { flex: 1; display: flex; flex-direction: column; min-width: 0; min-height: 0; overflow: hidden; } +.shell-layout { display: flex; height: 100%; overflow: hidden; } +.shell-terminal-col { flex: 1; display: flex; flex-direction: column; min-width: 0; overflow: hidden; } .shell-tabs-bar { display: flex; align-items: center; background: var(--bg-surface); @@ -382,7 +382,7 @@ input::placeholder { color: var(--text-disabled); } } .shell-menu-divider { height: 1px; background: var(--border); margin: 4px 6px; } -.shell-xterm-wrapper { flex: 1; height: 100%; background: var(--bg); overflow: hidden; position: relative; } +.shell-xterm-wrapper { flex: 1; min-height: 0; background: var(--bg); overflow: hidden; position: relative; } .shell-xterm-instance { position: absolute; inset: 0; @@ -402,7 +402,7 @@ input::placeholder { color: var(--text-disabled); } .shell-tab.ai-tab .shell-tab-name { color: var(--accent); } .shell-tab.ai-tab { border-bottom-color: var(--accent); } -.shell-ai-col { width: 320px; border-left: 1px solid var(--border); background: var(--bg-surface); display: flex; flex-direction: column; flex-shrink: 0; } +.shell-ai-col { width: 320px; max-width: 320px; border-left: 1px solid var(--border); background: var(--bg-surface); display: flex; flex-direction: column; flex-shrink: 0; overflow: hidden; } .ai-panel-header { padding: 12px 16px; border-bottom: 1px solid var(--border); font-weight: 700; font-size: 13px; color: var(--accent); display: flex; align-items: center; justify-content: space-between; } .shell-analyze-btn { display: flex; align-items: center; gap: 4px;