cmux NEXT: every new window opens clean; pins stay per window (#26632)

AU
3d ago
+528-17

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, and fast gates.
  • ios-tests was 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:

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

  1. Open tag 26632-clean-new-window from the Tag Opener.
  2. In the first window, pin a workspace, a tab and a page.
  3. Make a group, pin it, then close its workspace.
  4. 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