fix: keep terminal titles unique across session restore
The 终端 N counter lives only in memory, so after a restore it restarted at zero and the next new terminal duplicated a restored title. Broadcast keys targets by session id so duplicate titles never broke the fan-out itself, but the target list became indistinguishable. Seed the counter past the restored maximum on session restore / template apply, and retitle duplicates already baked into existing snapshots.
This commit is contained in:
1 parent
f09bed06b5
commit
28d8af6982
1 file changed
+27
@@ -71,6 +71,18 @@ function nextTerminalTitle(): string {
|
|||||||
return `终端 ${titleSeqHolder.__otTitleSeq}`
|
return `终端 ${titleSeqHolder.__otTitleSeq}`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lift the counter past every "终端 N" currently on screen. The counter lives
|
||||||
|
* only in memory, so after a session restore / template apply it is behind the
|
||||||
|
* restored titles and the next new terminal duplicates one (`终端 2` twice).
|
||||||
|
*/
|
||||||
|
function syncTitleSeq(titles: Iterable<string | undefined>): void {
|
||||||
|
for (const title of titles) {
|
||||||
|
const n = title?.match(/^终端 (\d+)$/)?.[1]
|
||||||
|
if (n) titleSeqHolder.__otTitleSeq = Math.max(titleSeqHolder.__otTitleSeq ?? 0, Number(n))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function sessionIdOf(panel: IDockviewPanel | undefined): string | undefined {
|
function sessionIdOf(panel: IDockviewPanel | undefined): string | undefined {
|
||||||
return (panel?.params as TerminalParams | undefined)?.sessionId
|
return (panel?.params as TerminalParams | undefined)?.sessionId
|
||||||
}
|
}
|
||||||
@@ -861,6 +873,18 @@ export default function Workspace({ onOpenSettings }: WorkspaceProps): React.JSX
|
|||||||
const renames = new Map([...terminalLayout.renames, ...sshLayout.renames])
|
const renames = new Map([...terminalLayout.renames, ...sshLayout.renames])
|
||||||
await rebindSessionPanels(terminal, snapshot, true, renames)
|
await rebindSessionPanels(terminal, snapshot, true, renames)
|
||||||
await rebindSessionPanels(ssh, snapshot, true, renames)
|
await rebindSessionPanels(ssh, snapshot, true, renames)
|
||||||
|
const allPanels = [...(terminal?.panels ?? []), ...(ssh?.panels ?? [])]
|
||||||
|
syncTitleSeq(allPanels.map((p) => p.title))
|
||||||
|
// Retitle duplicates left over from the counter bug (the snapshot the bug
|
||||||
|
// wrote keeps colliding titles forever otherwise): first panel keeps the
|
||||||
|
// title, later ones get a fresh number past the restored maximum.
|
||||||
|
const seenTitles = new Set<string>()
|
||||||
|
for (const p of allPanels) {
|
||||||
|
const t = p.title ?? ''
|
||||||
|
if (!t) continue
|
||||||
|
if (seenTitles.has(t)) p.setTitle(nextTerminalTitle())
|
||||||
|
else seenTitles.add(t)
|
||||||
|
}
|
||||||
lastLocalCwdRef.current = snapshot.lastLocalCwd ?? lastLocalCwdRef.current
|
lastLocalCwdRef.current = snapshot.lastLocalCwd ?? lastLocalCwdRef.current
|
||||||
useWorkspaceModeStore.getState().setMode(snapshot.mode)
|
useWorkspaceModeStore.getState().setMode(snapshot.mode)
|
||||||
recountAll()
|
recountAll()
|
||||||
@@ -908,6 +932,9 @@ export default function Workspace({ onOpenSettings }: WorkspaceProps): React.JSX
|
|||||||
// Fresh sessions for every restored terminal panel in both workspaces.
|
// Fresh sessions for every restored terminal panel in both workspaces.
|
||||||
if (terminalApiRef.current) await rebindRestoredPanels(terminalApiRef.current)
|
if (terminalApiRef.current) await rebindRestoredPanels(terminalApiRef.current)
|
||||||
if (sshApiRef.current) await rebindRestoredPanels(sshApiRef.current)
|
if (sshApiRef.current) await rebindRestoredPanels(sshApiRef.current)
|
||||||
|
syncTitleSeq(
|
||||||
|
[...(terminalApiRef.current?.panels ?? []), ...(sshApiRef.current?.panels ?? [])].map((p) => p.title)
|
||||||
|
)
|
||||||
|
|
||||||
// Old sessions are unreachable after the layout swap — kill them.
|
// Old sessions are unreachable after the layout swap — kill them.
|
||||||
for (const sid of previousSessions) killSession(sid)
|
for (const sid of previousSessions) killSession(sid)
|
||||||
|
|||||||
Reference in new issue
Block a user