Skip to content

Sidebar: hide scrolled rows under the traffic lights (minimal titlebar) - #24073

Merged
teamleaderleo merged 9 commits into
feat-cmux-nextfrom
live-qa-sidebar-top-mask
Oct 29, 2026
Merged

teamleaderleo merged 9 commits into
feat-cmux-nextfrom
live-qa-sidebar-top-mask

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Oct 22, 2026 •

Copy link
Copy Markdown
Collaborator

With the default minimal titlebar, scrolling the left sidebar list slid rows up under the window's traffic lights, and they stayed visible there. On nightly 1.0.0-nightly.3965802926201 (3a63d6d) the "Agents" group header pill sat beside the lights.

Cause: since 94f7db0 (minimal titlebar) the sidebar's header row is Metrics.tabStripHeight tall (28 in compact, WindowRootView.applyTokens), so the list starts level with the panes' content. The traffic lights reach about y=22 and the titlebar row ends at Metrics.titlebarHeight (32 in compact). The list's 18 pt top edge fade (ScrollEdgeFadeView) starts at the list's top, so a scrolled row from y=28 down was only partly faded, right below the lights.

Decision (claude-sr2), verbatim: "Miss 6: keep the list starting level with the panes at rest. When the list is scrolled, extend the top mask so content scrolling under the traffic lights is clipped and faded below the lights (y≈titlebarHeight). Don't use max(tabStripHeight, titlebarHeight) at rest."

Change:

  • ScrollEdgeFadeView (CmuxNextDesign) gets a topClip in points. Its gradient's first stop moves down to topClip. While content is hidden above, the top color is clear, so the mask hides everything from the list's top down to topClip and the usual 18 pt fade starts below it. At rest the top color is opaque, so the mask is the same as before. topClip defaults to 0, so the other users (palette, extensions menu, priority panel) don't change.
  • SidebarView sets each scrolling band's clip (the list, and the top item band when it shows) to the part above Metrics.titlebarHeight, but only when the traffic lights are over this sidebar (headerHasWindowControls; a right sidebar gets 0). With the full titlebar the list already starts at titlebarHeight, so the clip is 0.
  • The list doesn't move. There are no sticky headers, the minimal titlebar is still the default, and no component is removed.
  • Motion: no new animation. When the top edge starts hiding content, the clear band appears through the existing Motion.feedback hover crossfade on the mask colors. With animation off it applies in one frame. Changing the geometry (topClip, locations) never animates.
  • Observers: none added. The scroll position comes from ScrollEdgeFadeView's existing clip-view bounds/frame and document frame observers, which its deinit removes. No per-row work: the clip is set in SidebarView.layout, and a scroll only changes the mask's colors, as before.

Test: SidebarTopMaskTests (CmuxNextAppTests), committed before the fix. It reads the mask's gradient the way Core Animation draws it and checks:

  • At rest with a clip, the mask stays opaque at the top.
  • Scrolled, it is clear down to the clip, half-faded in the middle of the fade, and opaque after it.
  • With no clip, the fade still starts at the top.
  • In the sidebar with the minimal header row, each band's clip ends at max(bandTop, Metrics.titlebarHeight) and the band is not moved up.
  • With the full titlebar or no window controls, the clip is 0.

Changelog

Fixed: Sidebar rows no longer show under the window's traffic lights when the list is scrolled with the minimal titlebar.

Observed / Not run

  • Ran python3 scripts/cmux-next/prepush-gate.py: no new violations.
  • Focused suite on the fleet: cmux-ci run --class light --script scripts/ci/package-test-lane.sh --arg=suite --arg=Packages/macOS/CmuxNext --arg=SidebarTopMaskTests. Red at 0ccf766 (test only) and green at the head: results pending, to be added here when the steps finish.
  • Not run: the app itself. I didn't look at a scrolled sidebar in a build. The 4 pt clip in compact (28 to 32) comes from the token values, not from a measurement on screen.

No capture: the before/after capture follows from the next nightly (scrolled sidebar state).

Agent session: cmux16
🤖 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 sidebar rows staying visible under the window's traffic lights when scrolled with the minimal titlebar.

  • ScrollEdgeFadeView gains a topClip that hides content down to the titlebar's bottom and starts the top fade below it; at rest the mask is unchanged.
  • The sidebar sets each scrolling band's clip only when traffic lights are over it (headerHasWindowControls); full titlebar and right sidebar behavior is unchanged.
  • Adds SidebarTopMaskTests covering the mask at rest, scrolled, with no clip, and with full titlebar or no window controls.
  • Logs the fix in the sidebar owner note, since the fix commit reached its branch without a Sidebar-Look trailer.

Written for commit e582cd8. Summary will update on new commits.

View guided diff Turn on auto-fix

teamleaderleo and others added 2 commits October 21, 2026 19:23
With the minimal titlebar the sidebar list starts at the tab strip's
height (28 in compact), above the titlebar's bottom (32), and rows that
scroll up sit under the traffic lights in view. Pins the rule: at rest
the top mask is unchanged; scrolled, the list's top is hidden down to
Metrics.titlebarHeight and fades in below it. Red on base: the top clip
does not exist yet.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a16047-2854-7333-9aff-632422c609d7&host=cmux16
With the minimal titlebar (94f7db0) the sidebar list starts at the tab
strip's height (28 in compact) so it sits level with the panes' content,
while the traffic lights reach about y=22 and the titlebar row ends at
Metrics.titlebarHeight (32). Scrolled, rows slid up under the lights and
the 18 pt top fade left them visible there.

ScrollEdgeFadeView gets a topClip: while content is hidden above, the
mask is clear down to it and the top fade starts below it. At rest the
top color is opaque, so the mask is unchanged. The sidebar sets each
scrolling band's clip to the part above Metrics.titlebarHeight when the
traffic lights are over it. The list does not move; the band's fade-in
rides the existing Motion.feedback crossfade.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a16047-2854-7333-9aff-632422c609d7&host=cmux16
@teamleaderleo teamleaderleo added the risk:normal Risk tier (docs/ci/risk-tiers.md) label Oct 22, 2026
@github-actions

github-actions Bot commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

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

Review e582cd8: 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=pr24073 -f ref=live-qa-sidebar-top-mask -f platform=macos -f backend_mode=local

red: cmux-next checks (god files, concurrency, crash safety, l10n); no finished base run on 90e1666 to compare; do not merge until green; see lane-rules

@blacksmith-sh

blacksmith-sh Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

Found 6 test failures on Blacksmith runners:

Failures

Test View Logs
/tmp/tmpscxl1eeu/summary-fail.json (live):/summary-fail.json (live): View Logs
/tmp/tmpspktw20d/summary-missing.json (live):/summary-missing.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

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

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Orphaned: no activity for 17 h, and no lane holds a lease on it. Adopted by the orphan sweep: merged feat-cmux-next in at 8ddd55d. A later pass queues it for the merge hub if it is reviewed, small and red only on base reds.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

cmux-next crash-class rules / cmux-next crash-class rules is red on 12 of 12 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.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (codex gpt-6-astra xhigh, next-review): SHIP at 8ddd55d

No blocking findings.

@cursor

cursor Bot commented Oct 26, 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

high-signal review link / link is red on 17 of 21 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.

@cursor

cursor Bot commented Oct 27, 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 an agent session · took over from an earlier session · session

…ebar-top-mask

# Conflicts:
#	Packages/macOS/CmuxNext/Sources/CmuxNextDesign/ScrollEdgeFade.swift
#	Packages/macOS/CmuxNext/Sources/CmuxNextSidebar/Views/SidebarView.swift
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (codex gpt-6-astra high, review-router): SHIP at 88fe218

No blocking findings at this head (base merge plus conflict resolution reviewed with the full diff). Two non-blocking P3 notes on test strength.

Agent session: agent session

The traffic-light clip commit reached its branch without a Sidebar-Look
trailer. Rewriting it would need a force push, so it is reviewed and logged
here, as the gate allows for such commits (dcd4316, 8b5cafb).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-ab1f035a409b977caceb
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (codex-review-box/gpt-6-astra high, lane-place): SHIP at e582cd8

SHIP

No findings.

@teamleaderleo teamleaderleo removed the risk:normal Risk tier (docs/ci/risk-tiers.md) label Oct 29, 2026
@github-actions github-actions Bot added the risk:normal Risk tier (docs/ci/risk-tiers.md) label Oct 29, 2026
@teamleaderleo
teamleaderleo merged commit 4367c16 into feat-cmux-next Oct 29, 2026
184 of 187 checks passed
@teamleaderleo
teamleaderleo deleted the live-qa-sidebar-top-mask branch October 29, 2026 18:41
@github-actions

github-actions Bot commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

@lawrencecchen

lawrencecchen commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

The "Sidebar look owner sweep" step of the cmux-next checks names this PR's commit on feat-cmux-next. It scans every commit since 342462c, so every PR's checks print this line (job 123695447456 on #27454):

4367c16e12c Sidebar: hide scrolled rows under the traffic lights (minimal titlebar (Packages/macOS/CmuxNext/Sources/CmuxNextSidebar/Views/SidebarView+TrafficLightsClip.swift and 1 more): no `Sidebar-Look:` trailer. Add `Sidebar-Look: <the user's words>` (and edit plans/cmux-next/sidebar-owner.md) or `Sidebar-Look: no visual change`.

The commit has landed, so a trailer is no longer possible. The fix is an entry for 4367c16 in plans/cmux-next/sidebar-owner.md. A question for Leo, the author: what text should the entry have? Your words for the look, or "no visual change". This is an ##[error] line, not a red check, so it blocks nothing.

@lawrencecchen

Copy link
Copy Markdown
Contributor

Why your entry is waited for: #27634 makes the "Pushed commits add no violations" step fail when the sidebar sweep finds a commit with no record. Today the step never fails, because its pipe has no pipefail. Without an entry for 4367c16 in plans/cmux-next/sidebar-owner.md, every push run of feat-cmux-next would go red. So #27634 is held, without ready-to-land, until your entries for 4367c16 and 6c1a5ab are in. Pull request runs already show this commit only as a warning (#27632).

teamleaderleo added a commit that referenced this pull request Oct 30, 2026
4367c16 (#24073), 6c1a5ab (#24295) and eb8105b (#27561)
reached feat-cmux-next as squash merges without a Sidebar-Look trailer;
their branch commits are already logged in sidebar-owner.md.

Sidebar-Look: no visual change

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-8ac862c5f65d08f98445
teamleaderleo added a commit that referenced this pull request Oct 30, 2026
…for the Sidebar-Look sweep

The CI sweep from 342462c names 4367c16, 6c1a5ab and
eb8105b: base's squash merges of PRs whose branch commits are
already logged. Log them by their squash sha.

Sidebar-Look: no visual change
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-8ac862c5f65d08f98445
teamleaderleo added a commit that referenced this pull request Oct 30, 2026
…bar-Look trailer (#28326)

4367c16 (#24073), 6c1a5ab (#24295) and eb8105b (#27561) reached
the base branch without a Sidebar-Look: trailer, so the sidebar owner sweep in
cmux-next checks fails every PR whose merge includes them. Logging their shas
in sidebar-owner.md is the gate's documented path for such a commit
(prepush-gate.py sidebar_owner: "reviewed once instead of failing every later
sweep").


Agent-Session: https://cmux.com/deeplink/agent?id=aid-159afad10a5ab45ea16c

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
lawrencecchen added a commit that referenced this pull request Oct 31, 2026
…mmits stay errors (#27632)

* test(prepush-gate): a pull request's sidebar sweep warns on a base commit and errors on its own

Red on the base: prepush-gate.py has no --own-range ('unrecognized arguments').
On 2026-10-29 two feat-cmux-next commits without a Sidebar-Look record (#24073,
#24295) put an ##[error] on every pull request's cmux-next checks, and
next-autoland read it as the PR's own red (#27454 and four more PRs).

* ci(cmux-next): a pull request's sidebar sweep names a base commit as a warning; its own commits stay errors

The "Pushed commits add no violations" step sweeps every commit since
342462c for a Sidebar-Look record. On a pull request run it printed
::error for base commits too: 4367c16 (#24073) and 6c1a5ab (#24295)
put an error on every feat-cmux-next pull request's checks, and next-autoland
read that line as the PR's own red, so #27454 and four more PRs stayed held.

prepush-gate.py --own-range BASE..HEAD (the sweep only): a finding on a commit
inside the range is an ::error and fails the sweep as before; one on a commit
outside it is a ::warning that names the commit and plans/cmux-next/sidebar-
owner.md. cmux-next.yml passes --own-range HEAD^1..HEAD on pull request runs
only. A push sweep of feat-cmux-next is unchanged: every commit without a
record is still an error there, so the base's debt stays visible on the branch.

risk_tier.py classify: normal. Test: test_cmux_next_prepush_gate's new case fails
on the base and passes; the whole file passes (40 tests).

* ci(cmux-next): own-range on pull_request runs only; the warning carries the whole finding (review of #27632)

A workflow_dispatch run (feat-cmux-next, next-batch/*, a PR branch) checks out a
branch tip, not GitHub's merge commit, so HEAD^1..HEAD there is the tip commit
only: the != push test turned the branch's own debt into warnings. Now
== pull_request, as the app-FFI pin step tests. The warning text is the whole
finding, % and newlines escaped for the workflow command.
cmux-bot Bot added a commit that referenced this pull request Oct 31, 2026
* test(sidebar): cover fold accessibility activation

Exercise Done and Show more through AXPress, including row reuse and hidden rows. Native execution is pending the fleet route; this lane has no Swift compiler.

Agent-Session: https://cmux.com/deeplink/agent?id=aid-75c97562a83401f2d167

* fix(sidebar): let VoiceOver activate Done and Show more

Route AXPress through the same fold action as mouse clicks, rebind the callback when rows are reused, and reject hidden or stale fold elements. Native red/green execution is pending the fleet route.

Sidebar-Look: no visual change
Agent-Session: https://cmux.com/deeplink/agent?id=aid-75c97562a83401f2d167

* test(sidebar): isolate recycled fold view from live registry

Sidebar-Look: no visual change
Agent-Session: https://cmux.com/deeplink/agent?id=aid-75c97562a83401f2d167

* test: cover keyboard activation of sidebar disclosure rows

Agent-Session: https://cmux.com/deeplink/agent?id=aid-c24cb66e0a77ead34e65

* fix: include sidebar disclosure rows in keyboard walk

Agent-Session: https://cmux.com/deeplink/agent?id=aid-c24cb66e0a77ead34e65

* test: use key codes for disclosure navigation events

Agent-Session: https://cmux.com/deeplink/agent?id=aid-c24cb66e0a77ead34e65

* fix: stabilize keyboard disclosure focus and tests

Agent-Session: https://cmux.com/deeplink/agent?id=aid-c24cb66e0a77ead34e65

* test(sidebar): a fold reload or click elsewhere drops the old fold's focus

Covers the two Sol findings on #27961: a removed disclosure that comes back
must not bring back its ring, and a click on another disclosure must move
keyboard focus off the ringed one so Space acts on the clicked row.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-8ac862c5f65d08f98445

* fix(sidebar): move fold focus to a clicked disclosure

A click on Done or Show more left keyboard focus and its ring on the
disclosure the keyboard had reached, so the next Space or Return toggled
that one. The click now moves focus to the clicked disclosure without a
ring (as a click on a group header does), and a fold row draws its ring only
when the keyboard moved focus there.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-8ac862c5f65d08f98445
Sidebar-Look: no visual change

* docs(sidebar): log the fold keyboard commits for the Sidebar-Look sweep

89e3362 and cefa3bc reached the branch without a Sidebar-Look
trailer; both are behavior changes that draw only the existing keyboard
focus ring on a fold row.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-8ac862c5f65d08f98445

* docs(sidebar): log base's squash commits of #24073, #24295 and #27561 for the Sidebar-Look sweep

The CI sweep from 342462c names 4367c16, 6c1a5ab and
eb8105b: base's squash merges of PRs whose branch commits are
already logged. Log them by their squash sha.

Sidebar-Look: no visual change
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-8ac862c5f65d08f98445

* test(sidebar): a tab click must take keyboard focus off a disclosure

Red test for the review finding: after the keyboard focuses Show more,
a click on a tab row leaves focusedFold set, so Return or Space still
toggles the old disclosure.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-8ac862c5f65d08f98445

* fix(sidebar): a click on a tab or any other row takes focus off a disclosure

The .tab mouse-down selected the tab but left focusedFold (and a clicked
group header's focus) set, so Return or Space toggled the old disclosure
and the arrows walked on from it. Every row kind but a group header or a
disclosure now clears the keyboard focus on press, as workspace and item
clicks already did: tab, section, empty section, empty group, folder,
block and status rows.

Sidebar-Look: no visual change

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-8ac862c5f65d08f98445

* test(sidebar): drop the tab-row fold test; base deleted sidebar tab rows

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-8ac862c5f65d08f98445

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: cmux-bot[bot] <348531757+cmux-bot[bot]@users.noreply.github.com>

This branch was previously deployed

1 inactive deployment
ci-routing-agent — e582cd83 Deployed Oct 29, 2026 by teamleaderleo via namespace autofix #6234
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.

2 participants