-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Fix #1983: avoid workspace creation crash after restore #1985
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1020,14 +1020,12 @@ class TerminalController { | |
|
|
||
| // Wire batched port scanner results back to workspace state. | ||
| PortScanner.shared.onPortsUpdated = { [weak self] workspaceId, panelId, ports in | ||
| MainActor.assumeIsolated { | ||
| guard let self, let tabManager = self.tabManager else { return } | ||
| guard let workspace = tabManager.tabs.first(where: { $0.id == workspaceId }) else { return } | ||
| let validSurfaceIds = Set(workspace.panels.keys) | ||
| guard validSurfaceIds.contains(panelId) else { return } | ||
| workspace.surfaceListeningPorts[panelId] = ports.isEmpty ? nil : ports | ||
| workspace.recomputeListeningPorts() | ||
| } | ||
| guard let self, let tabManager = self.tabManager else { return } | ||
| guard let workspace = tabManager.tabs.first(where: { $0.id == workspaceId }) else { return } | ||
|
Comment on lines
1022
to
+1024
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Resolve port-scan updates by Line 1023/Line 1024 still route through Suggested fix- PortScanner.shared.onPortsUpdated = { [weak self] workspaceId, panelId, ports in
- guard let self, let tabManager = self.tabManager else { return }
- guard let workspace = tabManager.tabs.first(where: { $0.id == workspaceId }) else { return }
+ PortScanner.shared.onPortsUpdated = { workspaceId, panelId, ports in
+ guard let workspace = AppDelegate.shared?.workspaceFor(tabId: workspaceId) else { return }
let validSurfaceIds = Set(workspace.panels.keys)
guard validSurfaceIds.contains(panelId) else { return }
workspace.surfaceListeningPorts[panelId] = ports.isEmpty ? nil : ports
workspace.recomputeListeningPorts()
}Based on learnings: 🤖 Prompt for AI Agents |
||
| let validSurfaceIds = Set(workspace.panels.keys) | ||
| guard validSurfaceIds.contains(panelId) else { return } | ||
| workspace.surfaceListeningPorts[panelId] = ports.isEmpty ? nil : ports | ||
| workspace.recomputeListeningPorts() | ||
| } | ||
|
|
||
| // Accept connections in background thread | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Detach the old workspace before tearing its panels down.
Unlike
closeWorkspace(_:), this helper runs after the old workspace has already been removed fromtabs.Workspacecan still call back intoowningTabManager?.closeWorkspaceWithConfirmation(self)during panel teardown (seeSources/Workspace.swift, Lines 9747-9750), so leavingowningTabManagerset throughteardownAllPanels()lets restore cleanup re-enterTabManageragainst the restored tab list. That can prompt or close the wrong workspace/window. Nil the manager before teardown.🛠️ Proposed fix
private func releaseRestoredAwayWorkspace(_ workspace: Workspace) { // Session restore replaces the bootstrap workspace objects with freshly // restored ones. Tear the old graph down after the atomic swap so late // panel/socket callbacks cannot keep mutating hidden pre-restore state. AppDelegate.shared?.notificationStore?.clearNotifications(forTabId: workspace.id) + workspace.owningTabManager = nil workspace.teardownAllPanels() workspace.teardownRemoteConnection() - workspace.owningTabManager = nil }🤖 Prompt for AI Agents