Skip to content

cmux NEXT multi-view: a drop on a workspace shown beside goes to that workspace (Debug toggle) - #23924

Merged
teamleaderleo merged 2 commits into
feat-cmux-nextfrom
fix/multiview-drop-beside
Oct 22, 2026
Merged

teamleaderleo merged 2 commits into
feat-cmux-nextfrom
fix/multiview-drop-beside

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Oct 22, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

With the Debug toggle sidebar.multiView on, a window can show workspaces side by side (#23651). Until now, every drop target only looked at the focused workspace. A drop on a workspace shown beside it was pulled onto the focused workspace's layout, or did nothing. Now the drop goes to the workspace under the pointer:

  • A sidebar row dropped on a pane edge of a workspace beside goes on that side of that workspace. The focused workspace keeps the focus.
  • A sidebar row over one of its panes previews a merge into that pane.
  • A tab over one of its panes or tab strips targets that pane. Releasing the tab focuses that workspace first, the way a press does. With Option, which files the tab away, the focus stays where it was and the tab still lands there.

How it works: WindowController.content(atScreen:) picks the workspace on screen under a point. LayoutTabDropTarget, the drag's strip targets, WorkspaceMerge.hit, placeBeside and the commit's strip, column and dock lookups all use it, or onScreenContents. With the toggle off, only the focused workspace is on screen, so every lookup behaves as before.

The test helpers that turn the toggle on now put back the value they found. Before, a test in one multi-view suite could reset the toggle while a test in the other was waiting on an await.

Testing

Five new tests are in SidebarMultiViewDropTests.swift, an extension of the serialized SidebarMultiViewWindowTests. The suite needs a display, so both runs are pinned to aws-m4pro-9, as #23651's were.

Red, on the test commit:

cmux-ci run --class light --script scripts/ci/package-test-lane.sh --ref d28a98044089f3e43a151cc9dee956971e7d3a8e --key mv1-before-d28a98044089 --target-worker aws-m4pro-9 --arg=suite --arg=Packages/macOS/CmuxNext --arg=SidebarMultiViewWindowTests --env CMUX_CI_XCODE_APP=/Applications/Xcode_26.6.app

Step cc0d866f2bbc1eab584be831 on aws-m4pro-9 failed. All five new tests fail: the outcome is .cancel, the focus stays on k0, and paneController(stripID:) finds no pane in the workspace beside. The suite's eight existing tests pass.

Green, at the head, with the neighbor suites:

cmux-ci run --class light --script scripts/ci/package-test-lane.sh --ref 08cc004c538e09c62aa803b7fcc5b4ebe42653db --key mv1-after-08cc004c538e --target-worker aws-m4pro-9 --arg=suite --arg=Packages/macOS/CmuxNext --arg=SidebarMultiViewWindowTests,SidebarMultiViewPressTests,DragGlassTests,WindowCloseNeighborTests --env CMUX_CI_XCODE_APP=/Applications/Xcode_26.6.app

Step 2cb052def9034063f5c84904 on aws-m4pro-9 passed: SidebarMultiViewWindowTests (13 tests), SidebarMultiViewPressTests (6), DragGlassTests (6) and WindowCloseNeighborTests (9).

Compile checks at the head:

  • cmux-ci compile-check --app passed (job 5424a170110d7ccce0564590).
  • The merge-compile-guard fleet-compile-check.yml run 39699938872 passed on attempt 2. Attempt 1 failed in runner setup: python3 is missing on the runner. That is infrastructure, not this change.

Observed / Not run

Observed:

  • The fleet runs above.
  • prepush-gate.py: no new violations.
  • check-no-godfiles.sh: the Swift part of the output matches the base's exactly, so TabDragSession is still at 1014 lines. On this loaded Mac the Rust tail of the check timed out. This change touches no Rust.

Not run:

  • A dogfood pass in a tagged build. The feature is behind an off-by-default Debug toggle.
  • A real tab move landing. The fixture's daemon is fake, so the tab tests check where the drop resolves and which workspace is focused, not the move itself.

Remaining limits:

  • A link drag still targets only the focused workspace.
  • A sidebar tab drop on a row shown beside takes the workspace but not its slot index.
  • A point over the title bar above a workspace beside resolves to the focused workspace. The preview and the drop still agree.
  • If a drop into a workspace beside is refused, that workspace stays focused, the same as after a press there.
  • A pane too narrow to split, such as one of two panes in a half-width workspace, takes a row on its edge as a merge, not a beside. This is the layout's room rule for splits.

Changelog

none

Proof

No capture: behind the off-by-default sidebar.multiView Debug toggle.

Agent session: cosmic-gray

🤖 Generated with Claude Code

teamleaderleo and others added 2 commits October 21, 2026 16:24
…at workspace (multi-view)

With sidebar.multiView a sidebar row dropped on a pane edge of a workspace beside the focused one goes beside
that workspace; a row over one of its panes previews a merge into that pane; a tab over one of its panes or
strips targets it and, released, focuses that workspace, unless Option files it away. The tests run in the
serialized SidebarMultiViewWindowTests, and both multi-view suites' toggle helpers put back the value they found.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15ba7-3152-78b2-bfdf-bb6eb0d5a053&host=cosmic-gray
…to that workspace

With sidebar.multiView every drop target read only the focused workspace. Now:
- the layout drop target takes the workspace on screen under the pointer (WindowController.content(atScreen:));
- the drag's strip targets include the panes of the workspaces beside;
- a sidebar row dropped on a pane edge there goes beside that workspace;
- the commit's strip, column and dock lookups search every workspace on screen;
- a tab drop or a workspace merge into a workspace beside focuses it first, as a press does, unless Option files
  it away.
With the toggle off only the focused workspace is on screen, so every lookup is the one before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15ba7-3152-78b2-bfdf-bb6eb0d5a053&host=cosmic-gray
@teamleaderleo teamleaderleo added the risk:normal Risk tier (docs/ci/risk-tiers.md) label Oct 22, 2026
@github-actions

Copy link
Copy Markdown
Contributor

cmux status (one comment, edited in place; each line is updated by the job that owns it)

Review 08cc004: HQ feed card · gallery before/after runs · checks

App of this head (app.zip, kept 1 day)

gh workflow run reload-build.yml -R manaflow-ai/cmux --ref feat-cmux-next -f tag=pr23924 -f ref=fix/multiview-drop-beside -f platform=macos -f backend_mode=local

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Owned by claude-sr2/sidebar-drag-bugs on cosmic-gray · session

@blacksmith-sh

blacksmith-sh Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

Found 2 test failures on Blacksmith runners:

Failures

Test View Logs
nightly cmux-tui resolve/nightly cmux-tui resolve View Logs
test_the_repository_highlights_validate (main.DigestTests.test_the_repository_highl
ights_validate)/
test_the_repository_highlights_validate (main.DigestTests.test_the_repository_highl
ights_validate)
View Logs

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

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Bead cx-dxn93 created for this PR by the cmux coordinator.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (independent review subagent, cmux-review skill + REVIEW.md, correctness first): SHIP at 08cc004

Low notes, not blocking: focus is not rolled back when a drop into a workspace beside is later refused (same as a press there); a point over the title bar above a workspace beside falls back to the focused workspace (preview and commit agree). Both are listed in the description.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Red checks at 08cc004, classified:

  • nightly-guards / workflow-guard-tests / release-notary (and its Guard status wrapper) is a base finding. test_the_repository_highlights_validate fails on release-notes/next/highlights/restored-terminals-come-back.md ("needs a tryIt action/deeplink or a docs link"). cmux NEXT: a restored terminal pane comes back without a key press #23145 (03c70e7) added that file on feat-cmux-next, and this branch doesn't touch it. "nightly cmux-tui resolve" in the same job reads the published nightly tree, not this change.
  • cmux-next app compile (build fleet), cmux-next fast tier, cmux-next web bundles and fleet/test-compile (advisory) are infrastructure. Runner cmux21 failed in setup: "xcode-select: Failed to locate 'python3'", exit 72. I've rerun them at the same SHA. The app does compile at this head: cmux-ci compile-check --app job 5424a170110d7ccce0564590 passed, and the merge-compile-guard fleet-compile-check.yml run 39699938872 passed.

@teamleaderleo
teamleaderleo merged commit 5363032 into feat-cmux-next Oct 22, 2026
@teamleaderleo
teamleaderleo deleted the fix/multiview-drop-beside branch October 22, 2026 01:32
teamleaderleo added a commit that referenced this pull request Oct 22, 2026
… the pointer

After #23924 a drop targets the workspace under the pointer, a workspace shown beside the focused one too:
`besideEdge` reads that workspace (`content(atScreen:)`), so a row dropped on the far edge of a workspace beside
goes next to that one, as `placeBeside` already places it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15ba7-3152-78b2-bfdf-bb6eb0d5a053&host=cosmic-gray
@github-actions

github-actions Bot commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

teamleaderleo added a commit that referenced this pull request Oct 26, 2026
…ows its workspace beside Home (Debug toggle) (#24067)

* test(next): a row dropped on Home's right or bottom edge shows its workspace beside Home, multi-view (red)

Leo-ask sr2-01a1608f-66bb. The #23651 dogfood found Home (Chief) edge drops broken with sidebar.multiView on:
the right edge over Home's pinned dock did nothing, and the bottom edge cut Home off. SidebarMultiViewHomeTests
shows Home as the daemon lists it (its page tab in a pinned chat dock, alone) and drags a row to its right edge
and to its bottom edge (the pane's split zone and the screen's bottom dock band): each must place the workspace
beside Home, keep its tabs, and leave Home laid out in its half.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15ba7-3152-78b2-bfdf-bb6eb0d5a053&host=cosmic-gray

* fix(next): multi-view on by default; a row dropped on Home's right or bottom edge shows its workspace beside Home

Leo-ask sr2-01a1608f-66bb. Home's pinned dock takes no tab drop, so a row over its right edge found no pane target
and did nothing; over the bottom edge the screen's edge dock band answered first and made a new dock of Home
instead of a place beside it. With sidebar.multiView on, a drag over the shown workspace now goes beside it at the
nearest edge (within a quarter of its size) wherever the layout has no split edge: a pane that takes no drop, or
an edge dock band (`WindowController.besideEdge`, `WorkspaceDragResolver.outcome`). Center and column drops
still merge.

sidebar.multiView is on by default (Debug Settings keeps the toggle to turn it off).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15ba7-3152-78b2-bfdf-bb6eb0d5a053&host=cosmic-gray

* test(next media): a multi-view tour; debug.mouse drags a sidebar row by name onto an edge of the shown workspace

The multi-view tour makes two workspaces and drags one's sidebar row onto the other's right edge through the
app's own event path, so a capture shows the two side by side with both rows lit. debug.mouse takes `row` (a
workspace's name or id: its sidebar row's center) and a drag's `to_edge` (10% in from that edge of the shown
workspace), so the tour works on any capture window size. DEBUG only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15ba7-3152-78b2-bfdf-bb6eb0d5a053&host=cosmic-gray

* revert(next): keep sidebar.multiView off by default; the multi-view tour turns it on

Coordinator, for ask-c7aeeb3219: Leo asked where the feature is, not for a default change. The Home edge
fixes stay; the tour sets Debug Settings sidebar.multiView on before it drags.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15ba7-3152-78b2-bfdf-bb6eb0d5a053&host=cosmic-gray

* fix(next): a Home edge drop goes beside the workspace on screen under the pointer

After #23924 a drop targets the workspace under the pointer, a workspace shown beside the focused one too:
`besideEdge` reads that workspace (`content(atScreen:)`), so a row dropped on the far edge of a workspace beside
goes next to that one, as `placeBeside` already places it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15ba7-3152-78b2-bfdf-bb6eb0d5a053&host=cosmic-gray

* test(next): the Home bottom-edge drop in the dock band is 8 pt in, where the layout offers a new dock (red without the dock-band fix)

Review: 4% in missed the 24 pt bottom dock band, so the dock-band half of the fix had no red. The case now drops
8 pt from the bottom, where the layout proposes a new bottom dock of Home.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15ba7-3152-78b2-bfdf-bb6eb0d5a053&host=cosmic-gray

* test(next media): the multi-view tour drops api beside Home with plain $ prompts; debug.mouse names `row` in its error

The first capture showed the capture mini's user and host in a shell prompt and was refused by the privacy check.
Both workspaces now set a plain `$` prompt before the drag, and the tour drops api on Home's right edge (the
fixed path) with Home shown alone first.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15ba7-3152-78b2-bfdf-bb6eb0d5a053&host=cosmic-gray

* test(next): the Home multi-view suite's daemon has edge docks, so the 8 pt bottom drop meets the dock band

Review: the fixture daemon advertised no capabilities, so the layout had no edge dock bands and the dock-band
case took the same path as the split-zone one. The fixture takes capabilities; the Home suite passes
edge-docks-v1 and requires the layout's edge dock drops before the bottom-edge drag.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15ba7-3152-78b2-bfdf-bb6eb0d5a053&host=cosmic-gray

* fix(cmux-next): debug.mouse row points compile in the bench configuration

`DebugMouse+Rows.swift` was guarded by `#if DEBUG` alone, but `DebugMouse.swift`
compiles under `#if DEBUG || CMUX_BENCH_HOOKS` and its call sites at lines 62,
131 and 146 reach `dragTarget` and `rowPoint`. In the bench configuration
(`reload.sh --config bench` and `check-release-compile.sh --bench-hooks`:
Release with -DCMUX_BENCH_HOOKS -DCMUX_BLOCKING_CHECKS and no DEBUG) those
symbols were compiled out, so the app did not build.

Use the same conditional as the file it extends and as its sibling
`DebugMouse+Page.swift`. Every symbol it reaches is available there:
`InputJournal` and `InputJournalEntry` carry no `#if`, and
`SidebarListView.rowFrameOnScreen` is unguarded `public` in CmuxNextSidebar
(`DebugMouse+Page.swift` already calls `InputJournal.topLeftPoint` under this
guard). No behaviour change in DEBUG, and nothing new ships in a release app:
`check-no-bench-hooks.sh` keeps bench-hooks builds out of the release and
nightly pipelines.

Found by the independent Codex review of #24067 at 5ff6e19.

Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a17527-de24-7863-be96-1b1a8a3a97e1&host=huge-blue

* fix(cmux-next): SidebarMultiViewHomeTests names the edge-docks capability the way base does

The test fixture asked for the daemon's `edge-docks-v1` capability through
`DaemonCapabilities.shared.edgeDocks`. Base has neither member: `DaemonCapabilities`
is a namespace of four static wire-name forwards (sidebarDoc, sidebarLayout,
workspacePin, notificationAck) with a private init, and `edgeDocks` is not one of
them. So `CmuxNextAppTests` failed to compile with
"type 'DaemonCapabilities' has no member 'shared'", which took down both
`cmux-next swift test` and `cmux-next generated files`.

Use `DaemonCapability.edgeDocks.rawValue`, the same spelling the production code
uses (TabMoves.swift:175, ColumnDocking.swift:58, DockColumnHandlers.swift:59,
WorkspaceContentController.swift:250). `capabilities` is `[String]`, so the value
is unchanged: the wire name "edge-docks-v1".

This is the one thing the clean base merge hid: git merged without conflict, and
the static reviews read the production diff rather than resolving the test
fixture's API against base. Found by the Swift compile at 6f89807.

Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a17527-de24-7863-be96-1b1a8a3a97e1&host=huge-blue

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

This branch was previously deployed

1 inactive deployment
ci-routing-agent — 08cc004c Deployed Oct 22, 2026 by teamleaderleo
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk:normal Risk tier (docs/ci/risk-tiers.md)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant