Clean up panel branch state when closing a pane
This commit is contained in:
parent
c533ebe5e5
commit
e9da15d563
2 changed files with 52 additions and 1 deletions
|
|
@ -330,6 +330,9 @@ final class Workspace: Identifiable, ObservableObject {
|
|||
/// Deterministic tab selection to apply after a tab closes.
|
||||
/// Keyed by the closing tab ID, value is the tab ID we want to select next.
|
||||
private var postCloseSelectTabId: [TabID: TabID] = [:]
|
||||
/// Panel IDs that were in a pane when a pane-close operation was approved.
|
||||
/// Bonsplit pane-close does not emit per-tab didClose callbacks.
|
||||
private var pendingPaneClosePanelIds: [UUID: [UUID]] = [:]
|
||||
private var isApplyingTabSelection = false
|
||||
private var pendingTabSelection: (tabId: TabID, pane: PaneID)?
|
||||
private var isReconcilingFocusState = false
|
||||
|
|
@ -1880,7 +1883,36 @@ extension Workspace: BonsplitDelegate {
|
|||
}
|
||||
|
||||
func splitTabBar(_ controller: BonsplitController, didClosePane paneId: PaneID) {
|
||||
_ = paneId
|
||||
let closedPanelIds = pendingPaneClosePanelIds.removeValue(forKey: paneId.id) ?? []
|
||||
|
||||
if !closedPanelIds.isEmpty {
|
||||
for panelId in closedPanelIds {
|
||||
panels[panelId]?.close()
|
||||
panels.removeValue(forKey: panelId)
|
||||
panelDirectories.removeValue(forKey: panelId)
|
||||
panelGitBranches.removeValue(forKey: panelId)
|
||||
panelTitles.removeValue(forKey: panelId)
|
||||
panelCustomTitles.removeValue(forKey: panelId)
|
||||
pinnedPanelIds.remove(panelId)
|
||||
manualUnreadPanelIds.remove(panelId)
|
||||
panelSubscriptions.removeValue(forKey: panelId)
|
||||
surfaceTTYNames.removeValue(forKey: panelId)
|
||||
surfaceListeningPorts.removeValue(forKey: panelId)
|
||||
PortScanner.shared.unregisterPanel(workspaceId: id, panelId: panelId)
|
||||
}
|
||||
|
||||
let closedSet = Set(closedPanelIds)
|
||||
surfaceIdToPanelId = surfaceIdToPanelId.filter { !closedSet.contains($0.value) }
|
||||
recomputeListeningPorts()
|
||||
|
||||
if let focusedPane = bonsplitController.focusedPaneId,
|
||||
let focusedTabId = bonsplitController.selectedTab(inPane: focusedPane)?.id {
|
||||
applyTabSelection(tabId: focusedTabId, inPane: focusedPane)
|
||||
} else {
|
||||
scheduleFocusReconcile()
|
||||
}
|
||||
}
|
||||
|
||||
scheduleTerminalGeometryReconcile()
|
||||
scheduleFocusReconcile()
|
||||
}
|
||||
|
|
@ -1893,9 +1925,11 @@ extension Workspace: BonsplitDelegate {
|
|||
if let panelId = panelIdFromSurfaceId(tab.id),
|
||||
let terminalPanel = terminalPanel(for: panelId),
|
||||
terminalPanel.needsConfirmClose() {
|
||||
pendingPaneClosePanelIds.removeValue(forKey: pane.id)
|
||||
return false
|
||||
}
|
||||
}
|
||||
pendingPaneClosePanelIds[pane.id] = tabs.compactMap { panelIdFromSurfaceId($0.id) }
|
||||
return true
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1002,6 +1002,23 @@ final class WorkspacePanelGitBranchTests: XCTestCase {
|
|||
XCTAssertEqual(branches.map(\.branch), ["main", "feature/left", "feature/right"])
|
||||
XCTAssertEqual(branches.map(\.isDirty), [true, false, false])
|
||||
}
|
||||
|
||||
func testClosingPaneDropsBranchesFromClosedSide() {
|
||||
let workspace = Workspace()
|
||||
guard let leftPanelId = workspace.focusedPanelId,
|
||||
let leftPaneId = workspace.paneId(forPanelId: leftPanelId),
|
||||
let rightPanel = workspace.newTerminalSplit(from: leftPanelId, orientation: .horizontal) else {
|
||||
XCTFail("Expected left/right split panes")
|
||||
return
|
||||
}
|
||||
|
||||
workspace.updatePanelGitBranch(panelId: leftPanelId, branch: "branch1", isDirty: false)
|
||||
workspace.updatePanelGitBranch(panelId: rightPanel.id, branch: "branch2", isDirty: false)
|
||||
|
||||
XCTAssertEqual(workspace.sidebarGitBranchesInDisplayOrder().map(\.branch), ["branch1", "branch2"])
|
||||
XCTAssertTrue(workspace.bonsplitController.closePane(leftPaneId))
|
||||
XCTAssertEqual(workspace.sidebarGitBranchesInDisplayOrder().map(\.branch), ["branch2"])
|
||||
}
|
||||
}
|
||||
|
||||
final class SidebarBranchOrderingTests: XCTestCase {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue