cmux-next: a link from a lone chat opens its split without re-animating the chat

Merged
TE
16d ago
+172-6

Leo's bug (screenshots): in a workspace with one agent chat and no splits, clicking a link in the chat first plays an opening animation on the chat itself, which shrinks or re-animates, and only then does the link's tab show in a right split.

Cause. With a lone chat, AgentBesidePlacement keeps the new tab in the chat's own pane and moves the chat into a new left dock column (TabMoves.toNewDockColumn). The layout only sees panes, so it played the change as a split: the new dock (now holding the chat) grew in from the left edge while the old pane (now holding the link) shrank to the right.

Fix. Before docking, the placement names the chat's pane with LayoutModel.handOffContent(of:), a one-shot hint that expires after 3 s. The next structural change that adds a pane beside it plays as a hand-off (PaneArrival.handoff):

  • The added pane (the chat) shows at its final frame from the first frame. It doesn't grow in and doesn't fade.
  • The old pane (the link) goes to its final size at once and slides in from the screen edge across from the chat, which is the right edge here. Its content lays out once, not on every frame.
  • With pane animations off or Reduce Motion on, both snap, as before. All of this stays under the panes motion category (ui.paneAnimations).

Test

ChatDockLinkSplitMotionTests.theChatStaysAndOnlyTheLinksPaneSlidesInFromTheRight steps 120 frames at 120 Hz. It checks that:

  • the chat's host frame takes one value, its final one, and its alpha stays 1 the whole time
  • the link's pane keeps its final width in every frame, starts past the right edge, never moves back right, and rests right of the chat

Red commit: 4ca0ec2f71c (test, plus the hint stored but unread). Fix: 394a8265f58, then 9bf6812714e (review follow-ups: the slide side compares both panes where they show, the hint is spent only on the giver's screen and dropped when the dock fails, and a hand-off's new dividers start in place).

Changelog

  • Fixed: Clicking a link in a lone agent chat no longer re-animates the chat; only the link's new pane slides in from the right.

Observed / Not run

  • Observed, red on 4ca0ec2f71c (fleet step 97e2312a, cmux-ci run --class light --script scripts/ci/run-swift-testing-suites.sh --arg Packages/macOS/CmuxNext --ref 4ca0ec2f71c --red): ChatDockLinkSplitMotionTests fails 4 expectations. The chat's frame width goes 0, 9, 33, 67, 106 ... 597 (the dock grows in from the left), the link's pane starts at minX 0 instead of past the right edge (1200), and its width changes while it comes in. That step ran the whole package; its 26 other failed suites (e.g. ActionSurfaceParityTests, ClassicUpgradeHugeSimulationTests, SettingsSchemaExportTests) are on the base commit and untouched here.
  • Observed: prepush-gate.py reports no new violations on every commit.
  • Observed on fc03897d (base merge of e9d76306): the fleet app compile and link (cmux-ci compile-check --app) passes. ChatDockLinkSplitMotionTests (1) and SplitSpringMotionTests (12) pass on the fleet (step a.k.a. docksplit-s2) at fc03897d plus the base's compile fix f5bbdfe1 (#23281): the head alone does not compile its tests, because of the base's PageEnginePolicyTests and ChiefAppAcpmuxTests breaks. CI reds are base or infrastructure: cmux-next checks (Tier routing; "Pushed commits add no violations"), generated drift (files this PR did not cause), action export areas and merge freeze (API rate limit, reran). Capture: media-tour.
  • Not run: CI's own Release compile and cmux-next swift test were still queued at merge (fleet backlog); its swift test would build against the base before #23281.
  • Green on the head: from this PR's CI CmuxNextAppTests and Swift compile (see below once in).
  • Base red, not this PR: cmux-next guards / defaults-snapshot lists mobile.allowIPhoneConnections, sessions.allowFullAccess, sidebar.priorityView.* and ui.calm, none of which this PR touches.
  • Not run: the agent-pane webview remounting its content on the move (the "content never replays its entrance" half). The layout test covers the native host (one frame, opaque); I have not checked whether the webview's own entrance replays when the chat's view moves to the new host.

Agent session: huge-blue

🤖 Generated with Claude Code


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.


Summary by cubic

Fixes an animation bug where clicking a link in a lone agent chat replayed the chat's opening animation before the link's panel appeared. The chat now stays in place and only the link's panel slides in from the right edge, using a one-shot hand-off hint that lapses after a few seconds and is dropped if the dock move fails. The hint only fires for a structural change on the giver's screen, so later or unrelated splits still play as splits. With pane animations off or Reduce Motion enabled, both panes snap as before. Adds a frame-stepping test covering the motion.