Skip to content

sidebar scrollbar always visible — should only appear when content overflows - #3277

Closed
lawrencecchen wants to merge 1 commit into
mainfrom
loader/issue-3241-sidebar-scrollbar-video18
Closed

lawrencecchen wants to merge 1 commit into
mainfrom
loader/issue-3241-sidebar-scrollbar-video18

Conversation

@lawrencecchen

@lawrencecchen lawrencecchen commented Apr 29, 2026 •

Copy link
Copy Markdown
Contributor

Addresses #3241

Generated by cmux-loader.

Recorded videos:

  • repro-before: .runner/videos/repro-before.mov (ok)
  • fixed-after: .runner/videos/fixed-after.mov (ok)

Run artifacts: https://github.com/manaflow-ai/cmux-loader/actions/runs/25089637151

Codex final message:

Implemented in branch loader/issue-3241-sidebar-scrollbar-video18 for #3241.

Summary

I narrowed the fix to the workspace sidebar scroll container in Sources/ContentView.swift:

  • Added .scrollIndicators(.automatic) on the sidebar ScrollView.
  • Updated the sidebar scroll resolver callback to always set:
    • autohidesScrollers = true
    • scrollerStyle = .overlay
  • Updated SidebarScrollViewResolverView.resolveScrollView() to compute content/viewport heights and set:
    • hasVerticalScroller = contentHeight > visibleHeight + 1
      This prevents a vertical scroller when sidebar rows fit in the viewport.

Verification performed

  • Built tagged debug app (no test suite run):
    ./scripts/reload.sh --tag loader
    ./scripts/reload.sh --tag loader --launch
  • Approved app for GUI automation:
    ./.cmux-loader/approve-computer-use-app "/Users/runner/Library/Developer/Xcode/DerivedData/cmux-loader/Build/Products/Debug/cmux DEV loader.app"
  • Confirmed app was running as cmux DEV loader and inspected GUI state via computer-use after rebuild.
  • Recorded required videos (both succeeded):
    • ./.cmux-loader/record-video start repro-before 180 → ./.cmux-loader/record-video stop repro-before (status=ok)
    • ./.cmux-loader/record-video start fixed-after 180 → ./.cmux-loader/record-video stop fixed-after (status=ok)

Recorded videos

  • repro-before.mov
  • fixed-after.mov

If you want, I can also keep the change minimal by removing the overflow-height guard and relying only on .overlay + autohide, but this may reintroduce the one-item visible-track behavior on some macOS settings.


Summary by cubic

Fixes the workspace sidebar so its scrollbar only shows when content overflows. Uses overlay, autohiding indicators to remove the always-visible track.

  • Bug Fixes
    • Set .scrollIndicators(.automatic) on the sidebar ScrollView.
    • Force autohidesScrollers = true and scrollerStyle = .overlay on the sidebar NSScrollView.
    • Toggle hasVerticalScroller based on content vs. visible height to prevent a scroller when items fit.

Written for commit 39313d6. Summary will update on new commits. Review in cubic

Summary by CodeRabbit

  • Bug Fixes
    • Improved sidebar scroll view behavior with automatic scroll indicator visibility and overlay-style auto-hiding scrollers.
    • Enhanced vertical scroller rendering based on content dimensions.

Generated by cmux-loader.
@vercel

vercel Bot commented Apr 29, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
cmux Ready Ready Preview, Comment Apr 29, 2026 3:57am
cmux-staging Building Building Preview, Comment Apr 29, 2026 3:57am

@coderabbitai

coderabbitai Bot commented Apr 29, 2026 •

Copy link
Copy Markdown

Caution

Review failed

Pull request was closed or merged during review

📝 Walkthrough

Walkthrough

The sidebar scroll view configuration is enhanced with dynamic behavior: the SwiftUI sidebar gains automatic scroll indicator visibility, while the resolver configures the underlying NSScrollView with overlay-style autohiding scrollers. The vertical scroller now conditionally enables based on content height comparison. Auto-scroll controller attachment is guarded by scroll view availability.

Changes

Cohort / File(s) Summary
Sidebar Scroll View Configuration
Sources/ContentView.swift
Dynamic resolver-driven scroll view setup with conditional vertical scroller enabling based on document vs. visible height, overlay-style scrollers with autohide, and guarded auto-scroll controller attachment.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

🐰 Scrolls now glide with grace and care,
Overlay bars that fade to air,
Heights compared with gentle measure,
Guards and guards for pixel pleasure,
Precision flows through sidebar's dream! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title directly describes the main change: fixing the sidebar scrollbar to only appear when content overflows, which aligns with the core objective of the PR.
Description check ✅ Passed The description is comprehensive and includes a detailed summary of changes, verification steps, and recorded videos. However, it lacks explicit responses to the template's 'Testing' section structure and the standard review trigger checklist.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch loader/issue-3241-sidebar-scrollbar-video18

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
Review rate limit: 3/8 reviews remaining, refill in 37 minutes and 18 seconds.

Comment @coderabbitai help to get the list of available commands and usage tips.

@lawrencecchen

Copy link
Copy Markdown
Contributor Author

Closing this loader dogfood PR because the downloaded videos show cmux behind the macOS FileVault confirmation sheet. The setup helper now clears the earlier panes, but it switches to hide mode during the Codex run, so late Setup Assistant sheets are not dismissed. I am changing the Codex-run helper to keep clicking Setup Assistant prompts and will rerun from a fresh branch.

@lawrencecchen
lawrencecchen deleted the loader/issue-3241-sidebar-scrollbar-video18 branch April 29, 2026 03:52
@greptile-apps

greptile-apps Bot commented Apr 29, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes the sidebar scrollbar always being visible by configuring the underlying NSScrollView to use overlay style with auto-hide, and conditionally disabling hasVerticalScroller when the content fits within the viewport. The changes are isolated to the workspaceScrollArea SwiftUI view and the SidebarScrollViewResolverView AppKit bridge.

Confidence Score: 4/5

Safe to merge; the fix is self-contained and verified with recorded videos, with only minor style concerns.

Only P2 findings: redundant property assignments across two call sites, and a theoretical conflict between .scrollIndicators(.automatic) and manual hasVerticalScroller under non-default system scroll-bar preferences. No logic breakage observed in the verified flow.

Sources/ContentView.swift — specifically the resolveScrollView() method and the onResolve callback

Important Files Changed

Filename Overview
Sources/ContentView.swift Adds .scrollIndicators(.automatic) to the sidebar ScrollView and directly configures the underlying NSScrollView's hasVerticalScroller, autohidesScrollers, and scrollerStyle in resolveScrollView() and the onResolve callback; the two sites duplicate autohidesScrollers/scrollerStyle assignment, and the SwiftUI modifier may conflict with the manual hasVerticalScroller approach under some system scroll-bar preferences.

Sequence Diagram

sequenceDiagram
    participant SwiftUI as SwiftUI ScrollView
    participant Resolver as SidebarScrollViewResolverView
    participant NSScroll as NSScrollView

    SwiftUI->>Resolver: updateNSView / viewDidMoveToWindow
    Resolver->>Resolver: resolveScrollView() [async main]
    Resolver->>NSScroll: hasVerticalScroller = contentHeight > visibleHeight + 1
    Resolver->>NSScroll: autohidesScrollers = true
    Resolver->>NSScroll: scrollerStyle = .overlay
    Resolver->>SwiftUI: onResolve(scrollView)
    SwiftUI->>NSScroll: autohidesScrollers = true (duplicate)
    SwiftUI->>NSScroll: scrollerStyle = .overlay (duplicate)
    SwiftUI->>NSScroll: dragAutoScrollController.attach(scrollView)
Loading

Reviews (1): Last reviewed commit: "Address https://github.com/manaflow-ai/c..." | Re-trigger Greptile

Comment thread Sources/ContentView.swift
Comment on lines +9816 to +9817
scrollView.autohidesScrollers = true
scrollView.scrollerStyle = .overlay

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Redundant autohidesScrollers/scrollerStyle configuration

autohidesScrollers = true and scrollerStyle = .overlay are set here in the onResolve callback, but resolveScrollView() already sets those same two properties before calling onResolve. Since the callback runs after resolveScrollView(), these lines simply overwrite values that were just written — harmless but confusing and easy to get out of sync if one site is updated without the other.

Comment thread Sources/ContentView.swift
minHeight: geometryProxy.size.height
)
}
.scrollIndicators(.automatic)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Potential conflict between .scrollIndicators(.automatic) and manual hasVerticalScroller

.scrollIndicators(.automatic) on macOS defers scroll indicator visibility to the system preference (System Settings → Appearance → Show scroll bars). When the user has that preference set to "Always," SwiftUI may keep hasVerticalScroller = true internally and could re-assert it after resolveScrollView() sets it to false. This might cause the scroller to reappear for users with the legacy "Always show" setting, undermining the fix. Consider using .scrollIndicators(.never) paired with the overlay-style scroller as the safe default, or verifying behavior under the "Always show" scroll bar preference.

This branch was successfully deployed

1 active deployment
Preview – cmux — 39313d64 Deployed Apr 29, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant