tabs: keep all tab content mounted (inactive hidden), so switching tabs never reloads a terminal

Switching tabs used to unmount the active view; a terminal's unmount sent
the tab-close frame, killing its pty, and switching back respawned a fresh
shell. Every tab now stays mounted and inactive ones are display:none: a
terminal keeps its WebSocket + pty + scrollback, an editor keeps its
CodeMirror view and unsaved draft, explorer/git keep their data. The close
frame now fires only when a tab is truly closed (close button, middle
click, pane removal). Re-shown terminals re-fit via the existing
ResizeObserver; editors re-measure via CodeMirror's own observer.
This commit is contained in:
Menghuan1918
2026-08-08 16:19:18 +08:00
parent e80c1f6625
commit f4b86770d0
4 changed files with 31 additions and 3 deletions
-1
View File
@@ -205,7 +205,6 @@ export function Sidebar(props: { ctx: Context }) {
const renderTab = (tab: SidebarTab) => (
<TabContent
key={tab.id}
tab={tab}
sessionId={sessionId}
cwd={cwd}
+13
View File
@@ -269,6 +269,19 @@
overflow: hidden;
}
/* One tab's mounted content; inactive tabs stay mounted but hidden so
switching never tears down terminals/editors (state survives). */
.paneTab {
flex: 1;
min-height: 0;
display: flex;
flex-direction: column;
}
.paneTabHidden {
display: none;
}
.paneEmptyCards {
flex: 1;
min-height: 0;
+17 -1
View File
@@ -173,7 +173,23 @@ function LeafView(props: {
}}
/>
{leaf.tabs.length > 0 ? (
<div className={css.paneContent}>{activeTab !== undefined ? renderTab(activeTab) : null}</div>
/*
Every tab stays MOUNTED (inactive ones hidden), so switching tabs
never tears down the content: a terminal keeps its pty connection
and scrollback, an editor keeps its CodeMirror view and unsaved
draft, explorer/git keep their loaded data. The unmount (and the
terminal's close frame) happens only when a tab is truly closed.
*/
<div className={css.paneContent}>
{leaf.tabs.map(tab => (
<div
key={tab.id}
className={clsx(css.paneTab, tab.id !== activeTab?.id && css.paneTabHidden)}
>
{renderTab(tab)}
</div>
))}
</div>
) : (
<PaneEmptyCards newTabOptions={newTabOptions} onNewTab={onNewTab} />
)}