Skip to content

refactor(connections): give each connection its own panes instead of rebuilding on switch - #2116

Merged
datlechin merged 8 commits into
mainfrom
refactor/per-workspace-panes
Aug 15, 2026
Merged

refactor(connections): give each connection its own panes instead of rebuilding on switch#2116
datlechin merged 8 commits into
mainfrom
refactor/per-workspace-panes

Conversation

@datlechin

Copy link
Copy Markdown
Member

Follow-up to #2097. One window now hosts every open connection, and switching between them used to tear the whole pane down and rebuild it from the incoming connection's state. That works, but the rebuilt views start from nothing: the grid returns scrolled to the top, the editor loses its cursor and selection, and a sheet the user was half way through filling in is gone.

Each connection now owns its own sidebar, detail and inspector hosting controllers for as long as it is open. A switch shows the ones that belong to the selected connection and hides the rest.

What changed

  • ConnectionWorkspace owns a WorkspacePanes holding its three hosting controllers, built once when the connection opens.
  • WorkspacePaneHost is the stable container that sits in each NSSplitViewItem. NSSplitViewItem.viewController cannot be reassigned once installed, so the container stays put and swaps its child.
  • Every hosting controller sets sizingOptions = [], which is what keeps tab content from pinning the window's split dividers (roles users #1872).
  • WindowManager splits into buildWindow, openStandaloneWindow and openInNewWindow. Open in New Window was joining the tab group it was supposed to leave, so the connection ended up as a second native tab of the same window; it now leaves the group.
  • A connection that finishes connecting while another is on screen repaints its own pane instead of the visible one.
  • Retry routes through the workspace reconnect that already existed rather than a second path beside it.
  • ConnectionWorkspaceHandoff, a global used to hand a moving connection to the window being built for it, is gone. The window takes the connection through its initializer.

Measured

Click-to-pixels on a switch, over 20 switches on a 4-connection window:

before after
displayed 120-190ms, with outliers past 300ms 96-115ms, no outliers
synchronous 60-90ms 34-50ms

The remaining synchronous cost is the toolbar rebuild (12-24ms) and the sidebar pane (9-18ms). The toolbar is worth its own change and is not in this one.

The speed is a real but modest improvement. The reason to make this change is state preservation: what the user had on screen is still there when they come back to it.

Tests

ConnectionWorkspaceRegistryTests, WindowLifecycleMonitorTests, WindowLifecycleMonitorRegistrationTests, WorkspaceRail* and ConnectionCloseActionTests pass. UI coverage is ConnectionCloseUITests and SingleWindowMenuContractUITests, both landed with #2097. There is no UI test for the strip's contextual menu.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@datlechin
datlechin merged commit 486458a into main Aug 15, 2026
4 checks passed
@datlechin
datlechin deleted the refactor/per-workspace-panes branch August 15, 2026 02:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant