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:
@@ -11,7 +11,7 @@ control panel — **isolated per conversation session**.
|
||||
- Git: status / diff / stage / commit / branch / history(基础集)
|
||||
- 分栏工作台: VSCode 式拖拽分栏(拖 Tab 到分栏边缘即左右/上下拆分,拖到中间合并)、
|
||||
分隔线拖拽、面板宽度拖拽;折叠后右缘展开按钮常驻
|
||||
- Tab 栏: 最大宽度 160px、横向滚动、`+` 紧贴最右 Tab(溢出时吸附右缘)、`+` 菜单新建 Tab;空分栏显示可打开类型卡片(点击即开)
|
||||
- Tab 栏: 最大宽度 160px、横向滚动、`+` 紧贴最右 Tab(溢出时吸附右缘)、`+` 菜单新建 Tab;空分栏显示可打开类型卡片(点击即开);切换 Tab 不卸载内容(终端保持连接与回滚、编辑器保留未保存草稿)
|
||||
- 拦截: 对话"产出文件"行点击改为在侧边栏打开
|
||||
- 样式完全复用 `--dsw-*` 主题变量与 `@deepseek-ai/dsh-client-ui-primitives`
|
||||
|
||||
|
||||
@@ -205,7 +205,6 @@ export function Sidebar(props: { ctx: Context }) {
|
||||
|
||||
const renderTab = (tab: SidebarTab) => (
|
||||
<TabContent
|
||||
key={tab.id}
|
||||
tab={tab}
|
||||
sessionId={sessionId}
|
||||
cwd={cwd}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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} />
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user