cmux NEXT: a tab Home opens to the right opens only where it lands
Leo, 2026-10-29, word for word:
"What the f*** are the actual fing fixes for animations? Gosh-darn new tabs. Why the f? I'm pretty good about this because guys apparently can't fing listen. I open a link, or whatever the f, and it opens up on the right by default. Then just open it up on the fing right. Stop playing the animation that it's opening up a new tab on the main pane. Likewise, when new workspaces are being fing created, you fing just make it on the bottom, or you put it right next to it. What the f is this conflicting situation?"
(The 10-21 complaint, "the new-tab animation starts on the left", was misread as link routing in #22822 and reverted in #23886. This PR changes no placement: only which strip and which sidebar slot the open animation plays in.)
Tabs: the open plays only in the pane where the tab lands
The Chief/Home pane is a pinned dock that takes tabs. When nothing is on its right, a link it opens takes LinkOpener's .besideDock route: the tab is made in Home's own pane, then moved to a new column on the right. Every other route to the side (split, column, a lone chat docking left) already kept that round trip out of the source strip (OutboundTab, #23969). .besideDock did not. Home's strip listed the tab, its tab bar came back and the tab grew in on the main pane, then the tab moved right and its open played again there.
Now every path that makes a tab in Home's dock only to move it beside the dock leaves it out of the dock's strip until it has moved:
LinkOpener.open.besideDock: links, files and pages Home opens.HomeDockOpens.placing: the creators' sharedthenfor a tab aimed at Home's dock.PaneBrowserTabOpener's beside path: a browser tab aimed at Home's dock. It is also made unselected there (activate: !background && !beside). The move focuses it on the right, as before.
moveBeside takes the OutboundTab through to move, which already finishes it: the hold lasts until the move lands or fails, and a failed move lists the tab where it is. Where the tab ends up is unchanged.
Workspaces: not in this PR
A first try at the workspace half of the ask failed the fleet run: CmdNInGroupRowSlotTests (top, terminal) and RapidWorkspaceCreateTests (fifty and five quick Cmd-N) both fail at its head and pass at base. The try kept a new row's placeholder at its slot until the real row was listed there. With several creates in flight, top re-resolves each one's slot against the newer rows, so it misordered them. It is out of this PR and goes to a follow-up PR that must pass those frame tests.
Risk: low and contained. The Home dock paths can only hide their own new tab, and only until the move answers (OutboundTab's existing limits: 2 s unnamed, 60 s backstop).
Tests
SideOpenStripTests.aLinkFromHomesDockNeverShowsInTheDocksStrip(new): a link from Home's dock alone never lists in the dock's strip, before or after its answer.- Existing frame-level guards:
CmdNRowSlotTests,CmdNInGroupRowSlotTests,ColdCmdNRowSlotTests,RapidWorkspaceCreateTests,HomeLoneDockTests,LinkOpenPlacementTests.
Before / after (fleet capture, cmux-ci capture, Home alone, New Browser Tab from Home)
The capture traces every tab cell in the window once per display frame (debug.motion trace_start/trace_stop, 60 Hz on the capture mini), from the press to the landing.
| Home's strip during the open | Where the tab lands | |
|---|---|---|
Before (base e7ab659e) | At 1550 ms a second cell (the new tab) is listed in Home's strip at x=200, width 200. It then shrinks 200 → 54 → 33 → 15 → 9 → 3 → 0 px over the next ~185 ms while the right column opens: a new-tab animation on the main pane. | the column right of Home |
After (head 70c4e181) | No new cell in Home's strip on any of 195 frames: Home's strip only narrows (857 → 446 px) as the right column comes in. | the column right of Home (unchanged) |
Landed state, the same in both (the 2 fps stills miss the 200 ms flash; the trace above catches it):
| Before | After |
|---|---|
![]() | ![]() |
Fleet: app compile check passed (job 3e35999e71e99e2c8d0f0753, 108 s). Test runs are below.
🤖 Generated with Claude Code
Agent session: agent session

