Skip to content

cmux NEXT sidebar: multi-view prototype (navigate on release, drag without switching, on-screen rows lit) - #23437

Merged
teamleaderleo merged 4 commits into
feat-cmux-nextfrom
cmux/sidebar-multiview
Oct 21, 2026
Merged

teamleaderleo merged 4 commits into
feat-cmux-nextfrom
cmux/sidebar-multiview

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Oct 21, 2026 •

Copy link
Copy Markdown
Collaborator

Leo's sidebar item D (2026-10-21) asked to "do the Claude Code desktop multi-view better". This PR is a prototype behind the Debug Settings toggle sidebar.multiView (Sidebar section, "Navigate on release (multi-view prototype)"), off by default. With the toggle off, nothing changes.

With it on:

  • A press doesn't navigate. Mouse-down on a workspace row changes nothing: no selection, no fill, no workspace switch. The release on the same row is the click that navigates. A press released over another row navigates nowhere.
  • Hold-then-drag keeps your place. Dragging a row moves it in the list, and the shown workspace and the selection stay as they were, in every frame and after the drop. Today a drag first selects and shows the row it lifts. A sideways drag out of the sidebar still hands off to the window drag, which already drops a workspace into a pane edge with a drop indicator (WorkspaceMerge).
  • Every workspace on screen is lit. SidebarModel.onScreen lists the workspaces the window has on screen. Their rows draw the multi-selection's soft fill (Palette.secondarySelectionFill), and the focused row keeps the selection's fill. A change to the set repaints only the row fills (syncRowStates), without a reload.

The Chrome, Claude desktop and Codex comparison is in cmuxterm-hq#2746 (knowledge/inspiration/sidebars.md).

Not built yet:

  • A window can show only one workspace's panes today, and no window view holds panes of several workspaces. So nothing sets onScreen in the App yet; the model and the drawing are here and tested.
  • A drop on a pane edge still merges the dragged workspace's tabs into the shown one, instead of placing the workspace beside it.
  • The view doesn't remember its workspaces yet (the implicit group).

These need the multi-workspace content view first; that is the next step.

SidebarModel's selection methods moved unchanged to SidebarModel+Selection.swift so the file shrinks instead of growing.

Changelog

none (Debug-only prototype, off by default)

Tests

SidebarMultiViewPressTests is the per-frame test. After each mouse event it lays the list out and draws a frame, then checks the selection, the shown workspace and the filled rows. The red commit has the toggle, the model field and the row state with no behavior.

  • Command: cmux-ci run --class light --script scripts/ci/package-test-lane.sh --arg=suite --arg=Packages/macOS/CmuxNext --arg=SidebarMultiViewPressTests --env CMUX_CI_XCODE_APP=/Applications/Xcode_26.6.app --ref <sha>
  • Red on c2b8468 (step 9d244e3f3d9d57461a0596a1): 4 of 6 failed, 21 issues. Frame 0 (mouse-down) showed active=y where active=x was expected; the drag switched to the lifted row; no on-screen fills were drawn. The two toggle-off tests passed.
  • Green on 371e4d2 (step for key smv-press5-after): 6 of 6 passed.
  • SidebarPointerGestureTests (the existing click, drag and stale-drag behavior, toggle off) on the same head: 9 of 9 passed.

The base's CmuxNext test target doesn't compile right now (#23363 isReadOnly, #23386 PaletteMenuVocabularyTests). Both fleet runs had those two one-line fixes on top, on scratch refs (scratch/smv-before, scratch/smv-after). This branch itself carries neither.

No capture: nothing visible changes with the Debug toggle off, which is the default. With it on, the App doesn't fill the on-screen set yet, so the press and drag behavior is proven by the per-frame test above.

Observed / Not run

  • Observed: the suites above on the fleet; scripts/cmux-next/prepush-gate.py (no new violations); the god-file check against base (SidebarModel.swift shrank from 615 to 564 lines).
  • Not run: a live app capture. The App doesn't set onScreen yet, so a capture would only show the press and drag behavior. No full CmuxNext suite.

🤖 Generated with Claude Code

Agent session: cosmic-gray

teamleaderleo and others added 2 commits October 21, 2026 05:59
…view prototype (red)

Debug Settings sidebar.multiView (off): the tunable, SidebarModel.onScreen and the row's
isOnScreen state, with no behavior yet. SidebarMultiViewPressTests checks, frame by frame,
that a press changes no selection until mouse-up, that a hold-then-drag keeps the shown
workspace, and that every on-screen workspace row gets the soft fill.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ithout switching, on-screen rows highlighted

Behind Debug Settings sidebar.multiView (off by default), Leo's item D:
- a plain press on a workspace row selects nothing; the release on the same row navigates;
- a hold-then-drag moves the row and leaves the shown workspace and the selection as they are;
- every workspace in SidebarModel.onScreen draws the multi-selection's soft fill, the
  focused one the selection's.

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 21, 2026
@cursor

cursor Bot commented Oct 21, 2026

Copy link
Copy Markdown

Bugbot needs on-demand usage enabled

Bugbot uses usage-based billing for this team and requires on-demand usage to be enabled.

A team admin can enable on-demand usage in the Cursor dashboard.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

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

@github-actions

github-actions Bot commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

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

Review 39eeb11: 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=pr23437 -f ref=cmux/sidebar-multiview -f platform=macos -f backend_mode=local

Not verified: macOS jobs did not run: compile and app tests were skipped on 39eeb11b08; ci-status is green without them.

CI passes on 39eeb11b08 (run 39614746079 attempt 1).
macOS jobs did not run: compile and app tests were skipped: Fast static checks skipped (the macos job needs both to succeed). Re-run CI once they pass, before merging.

Written by scripts/ci/classify_failures.py (ci-failure-attribution.yml); signatures are its SIGNATURES table. A machine verdict is the runner's fault, not this PR's; yours means the failing file is one this PR changes, also red on main that main's latest full suite fails the same way, seen on other PRs that it failed on another pull request's run lately.

Tour of 39eeb11b08 (run): no media. The tour job failed before the tour ran (build or setup); the run log has the output. Both apps run cmux-tui from 48cfc9b (tree 5715f67083f1): the merge base's own tree 077ab7e6aca3 was not published yet.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

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

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

cmux-next guards / defaults-snapshot is red on 15 of 15 fresh feat-cmux-next PR heads in the last 2:00:00, so it is most likely a base red, not this PR's. The base-reds lane has it; a base merge picks up the fix once it lands.

@blacksmith-sh

blacksmith-sh Bot commented Oct 21, 2026

Copy link
Copy Markdown

Found 6 test failures on Blacksmith runners:

Failures

Test View Logs
/tmp/tmpflzai_29/summary-missing.json (live):/summary-missing.json (live): View Logs
/tmp/tmpk11hcv97/summary-fail.json (live):/summary-fail.json (live): View Logs
[new_workspaces] debug.new_workspace timed 0 of 50 new workspace rows/
[new_workspaces] debug.new_workspace timed 0 of 50 new workspace rows
View Logs
[new_workspaces] the window draws no frames/[new_workspaces] the window draws no frames View Logs
[tabs] debug.tab_switch timed 0 of 40 switches/
[tabs] debug.tab_switch timed 0 of 40 switches
View Logs
[tabs] the window draws no frames/[tabs] the window draws no frames 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

Independent review (codex exec, read-only, head 371e4d2): VERDICT: PASS. No blockers. With the toggle off, behavior is unchanged. With it on, mouse-down defers navigation, mouse-up on the same row navigates once, and a drag never selects. Cancel, Escape, focus loss, rename, placeholders, modifier clicks, tab rows and the window handoff all bypass or clear the deferred click. isOnScreen is reset on reuse, repainted on change and never drawn on the focused row. The selection extraction is a pure move. Compile-check app on the head: passed (job 7a193b512a6db7a8cd73979b).

…ebar-multiview

# Conflicts:
#	Packages/macOS/CmuxNext/Sources/CmuxNextSidebar/Logic/SidebarTunables.swift
@teamleaderleo
teamleaderleo merged commit 5f3f10b into feat-cmux-next Oct 21, 2026
@teamleaderleo
teamleaderleo deleted the cmux/sidebar-multiview branch October 21, 2026 16:31
@github-actions

github-actions Bot commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

teamleaderleo added a commit that referenced this pull request Oct 22, 2026
…ger switches to it

Leo 2026-10-21: "RIGHT CLICKING OR MOUSE DOWN DRAGGING ON A WORKSPACE SHOULDN'T BE
IMMEDIATELY FOCUSING".

- menu(for:) no longer clicks the right-clicked row: the menu is for that row (or the
  whole selection when the row is in it) and the shown workspace stays.
- A plain press on a workspace row selects nothing; the release on the same row
  navigates and a drag moves the row without switching (the navigate-on-release path
  #23437 added behind sidebar.multiView, now the default). A control-click selects nothing.
- Cmd/Shift-click keep changing the multi-selection on the press (they never switch
  the shown workspace).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a16040-fd0b-7dd0-9487-1a3a198d9f5c&host=cosmic-gray
teamleaderleo added a commit that referenced this pull request Oct 22, 2026
…ger switches to it (#23977)

* cmux NEXT sidebar: a right-click or a press on a workspace row no longer switches to it

Leo 2026-10-21: "RIGHT CLICKING OR MOUSE DOWN DRAGGING ON A WORKSPACE SHOULDN'T BE
IMMEDIATELY FOCUSING".

- menu(for:) no longer clicks the right-clicked row: the menu is for that row (or the
  whole selection when the row is in it) and the shown workspace stays.
- A plain press on a workspace row selects nothing; the release on the same row
  navigates and a drag moves the row without switching (the navigate-on-release path
  #23437 added behind sidebar.multiView, now the default). A control-click selects nothing.
- Cmd/Shift-click keep changing the multi-selection on the press (they never switch
  the shown workspace).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a16040-fd0b-7dd0-9487-1a3a198d9f5c&host=cosmic-gray

* cmux NEXT sidebar: Group Selected Workspaces acts on the right-clicked row's selection

Review of #23977: with a right-click no longer selecting its row, the menu of a row
outside a multi-selection showed Group Selected Workspaces and grouped the other rows.
The action now takes WindowMembershipHandlers.workspaces (the selection only when it
holds the target) for both its run and its visibility. The focus-loss drag test expects
the shown row's fill, since the press no longer selects; stale comments updated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a16040-fd0b-7dd0-9487-1a3a198d9f5c&host=cosmic-gray

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
lawrencecchen added a commit that referenced this pull request Oct 22, 2026
… a drag puts the shown workspace back

Lawrence 2026-10-21: "switching workspaces is very slow, we need to make it speed of light. on mousedown,
instantly switch." #23977 (1794aca, Leo) moved the switch to the release so a press that drags would
not switch; a click then waited for the mouse-up (about 80-150 ms of a person's click) before anything drew.

- A plain press switches now (SidebarPress.switchedOnPress); its release sends nothing more. A drag past the
  threshold puts back the item and selection shown before the press (restorePressSwitch), so Leo's rule
  holds: a drag moves the row and leaves the shown workspace. The parked content makes both swaps warm.
  sidebar.multiView keeps navigate-on-release (#23437).
- Off the switch path: SidebarLookedStore coalesces its JSON encode and defaults write (every switch wrote
  up to 256 stamps on main before the frame); showWorkspace's parked sweep asks the owner map, O(parked),
  not a Set of every member; sidebar arrow keys patch the two rows instead of reloading the list.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
lawrencecchen added a commit that referenced this pull request Oct 22, 2026
… a drag puts the shown workspace back

Lawrence 2026-10-21: "switching workspaces is very slow, we need to make it speed of light. on mousedown,
instantly switch." #23977 (1794aca, Leo) moved the switch to the release so a press that drags would
not switch; a click then waited for the mouse-up (about 80-150 ms of a person's click) before anything drew.

- A plain press switches now (SidebarPress.switchedOnPress); its release sends nothing more. A drag past the
  threshold puts back the item and selection shown before the press (restorePressSwitch), so Leo's rule
  holds: a drag moves the row and leaves the shown workspace. The parked content makes both swaps warm.
  sidebar.multiView keeps navigate-on-release (#23437).
- Off the switch path: SidebarLookedStore coalesces its JSON encode and defaults write (every switch wrote
  up to 256 stamps on main before the frame); showWorkspace's parked sweep asks the owner map, O(parked),
  not a Set of every member; sidebar arrow keys patch the two rows instead of reloading the list.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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