cmux NEXT: every new window opens clean; pins stay per window (#26632)
Fixes #26632 (the sidebar part; "Not in this PR" lists what stays open)
What changed
A new window, or a window opened on another macOS Space, listed the other windows' sidebar content. The sidebar document is one per home session, and each window drew all of it. Earlier fixes (https://github.com/manaflow-ai/cmux/pull/22783, https://github.com/manaflow-ai/cmux/pull/25782) hid only the items whose open workspaces another window lists. So a new window still showed:
- Pinned groups whose workspaces had closed
- pinned tabs and pages, and pins of closed workspaces
- empty workspace groups and links
Each document item a window can own now belongs to one window. These items are band items other than built-ins and apps, top-level Pinned, custom and machine groups, and machine links. Ownership is WindowBandOwnership in CmuxNextSidebar, saved as the window record's band_items.
How an item gets and keeps its window:
- A new item goes to the window whose sidebar or action made it. A drop counts for the window it lands in, even when another window is key.
- Failing that, it goes to the window that lists one of its workspaces, else to the front window.
- A new window owns nothing, so it opens clean.
- An item dragged to another window's sidebar moves to that window.
- An item that leaves the document and comes back (Undo, nest and un-nest) keeps its owner.
- When a window goes away, its items go to the front window. An incognito window's items stay hidden for the run.
- Records from older builds own nothing, so on upgrade their items go to the front window once.
A window leaves out the items another window owns, with exceptions:
- A group holding a workspace this window lists still shows, and so do the groups above it.
- An open workspace's pin still follows the window that lists the workspace.
- Home, the App Store and the footer list in every window.
The stored document is unchanged, and nothing is deleted.
Takes back #25782: its rule "a group with no open workspace lists in every window" is the behavior #26632 asks to remove. Such a group now lists only in its own window.
Tests
SidebarNewWindowCleanTests (CmuxNextAppTests) checks that:
- a new window lists none of another window's pins, groups or links, and the first window keeps them all
- a pin stays in the window it was made in, including a non-front acting window, after Undo, and after it leaves the document and comes back
- a stale acting window takes nothing
- a normal window never takes an incognito window's pins during the run
- another window's empty Pinned group stays out, even when the live rows carry it
- a nested Pinned group keeps its parent header
- ownership round-trips through the window records, and orphaned items go to the front window
Red: 5d5c45738f4 adds the test before the fix. At that commit, fleet step d153c4e8271e65103db94a41 (aws-m4pro-2) fails to compile: cannot find 'WindowBandOwnership' in scope, and there are no windowItems, hiddenItems or bandItems members.
Green: the CI job cmux-next swift test at the head; the result is in a comment below. The existing SidebarLayoutWindowScopeTests, SidebarNewWindowGroupsTests, SidebarRowsOwnershipRedrawTests and PinnedWorkspacePerSpaceTests run in the same suite.
Observed / Not run
Observed at merged head 7e02348d5e3:
- CI green:
cmux-next app compile (build fleet),cmux-next fleet Release compile,build / release-compile,cmux-next fast tier,cmux-next checks, the crash ratchet and crash-class rules, andfast gates. ios-testswas cancelled by the runner and has been rerun. This PR changes no iOS code.- The tagged dev build
26632-clean-new-window(fleet job 94c77702fe2367ec3092448f) is published. The Tag Opener lists it, and its direct backend answers at https://cmux-dev-backend-1.tail137216.ts.net:4626/. - A subagent ran three rounds of correctness review. Its final verdict is SHIP at 810eab0; the findings and their fixes are in a comment below.
Not run:
- Real-app screenshots.
cmux-ci capturewas given steps to pin a group, a workspace and a tab in window 1, then open a new window. Both attempts found no route: Blacksmith macOS had no runner (https://github.com/manaflow-ai/cmuxterm-hq/actions/runs/40634530930, https://github.com/manaflow-ai/cmuxterm-hq/actions/runs/40743423253), and the agent host has no fleet registry to lease a capture mini. That is whypr-capture-checkis red. No capture: the fleet capture routes were unavailable from this host. Verify by hand with the dogfood steps below. - The tagged app was not launched on the agent's Mac, so the user's display and focus were never taken.
Not in this PR (follow-ups on #26632)
- Home: the issue's "Home shows only the Chief chat and nothing else" is not changed here. Home's own content needs a design check against the issue.
- Incognito across a relaunch: incognito records are never saved, so after a relaunch a pin made in an incognito window has no owner and shows in the front normal window. Before this PR it showed in every window at once.
- A redraw-only local change, such as renaming a group, can leave the acting window set until the next item arrives from outside.
Dogfood
- Open tag
26632-clean-new-windowfrom the Tag Opener. - In the first window, pin a workspace, a tab and a page.
- Make a group, pin it, then close its workspace.
- Press Cmd-Shift-N, or open a window on another Space.
- Before: the new window listed the first window's Pinned group (as an empty header), its pins, and its empty groups and links.
- Expected: the new window shows only its own new workspace, Home and the footer, and the first window keeps all its pins.
Changelog
Fixed: A new window or Space opens with a clean sidebar; pins, pinned groups and links stay in the window they were made in.
🤖 Generated with Claude Code