Skip to content

Fix minimal-mode sidebar titlebar icon alignment - #4481

Merged
austinywang merged 8 commits into
mainfrom
issue-4475-minimal-mode-sidebar-icon-offset
May 21, 2026
Merged

austinywang merged 8 commits into
mainfrom
issue-4475-minimal-mode-sidebar-icon-offset

Conversation

@austinywang

@austinywang austinywang commented May 21, 2026 •

Copy link
Copy Markdown
Contributor

Closes #4475.

What changed

  • Minimal-mode sidebar titlebar controls now derive their host frame from the live macOS close-button traffic-light frame instead of the old fixed leftControlsTopInset.
  • The SwiftUI visible controls and the AppKit click target now share the same minimal-mode frame calculation, including a one-backing-pixel optical compensation for the existing TitlebarControlsView icon padding.
  • Added a regression test that installs the minimal-mode click target in a real AppKit window and asserts the host center follows the traffic-light center plus the optical compensation.

Regression source

Likely introduced by the minimal-mode toolbar removal path:

  • d13674f93 Hide window toolbar in minimal mode to eliminate titlebar gap
  • f17415702 Remove toolbar entirely in minimal mode instead of just hiding

Those commits moved minimal mode onto a separate overlay path while the standard titlebar accessory still used native titlebar metrics.

Sibling #4469 / #4471 coordination

I checked origin/issue-4469-fullscreen-titlebar-align before editing. That work has already landed on origin/main as 296060b95 Align titlebar controls with traffic lights (#4471). This PR layers on top of that and does not re-fix #4469; it fixes the remaining minimal-mode-only overlay path.

Screenshots

Sanitized titlebar crops captured from the tagged dev build:

  • Before: /tmp/cmux-issue-4475-screens/minimal-hover-before-titlebar.png
  • After: /tmp/cmux-issue-4475-screens/minimal-hover-after-titlebar.png

Full local captures are also available at:

  • /tmp/cmux-issue-4475-screens/minimal-hover-before.png
  • /tmp/cmux-issue-4475-screens/minimal-hover-after.png

I attempted to upload the cropped PNGs for inline PR rendering, but the available gh gist path rejects binary files and the unauthenticated upload fallbacks were unavailable. The after image was visually verified with the user before opening this PR.

Test approach

Failing-test-first structure:

  1. c78167d17 test: cover minimal titlebar control alignment
  2. 278cbb695 fix: align minimal titlebar controls to traffic lights

The regression test is in cmuxTests/WindowAndDragTests.swift and exercises the real WindowDecorationsController minimal click-target installation against AppKit traffic-light geometry.

Verification

  • Built with CMUX_SKIP_ZIG_BUILD=1 ./scripts/reload.sh --tag issue-4475-minimal-mode-sidebar-icon-offset --launch.
  • Visually checked standard mode and minimal mode in the tagged dev app.
  • Local XCTest was not run because the repo instructions say tests run in CI / GitHub Actions rather than locally.

View with Codesmith Autofix with Codesmith
Need help on this PR? Tag @codesmith with what you need. Autofix is disabled.


Note

Medium Risk
Changes minimal-mode titlebar control geometry and click-target placement based on live AppKit traffic-light frames, which could affect window interactions across macOS versions and scale factors.

Overview
Fixes minimal-mode sidebar titlebar icon/click-target alignment by deriving the controls host frame from the window’s live traffic-light (close button) geometry instead of a fixed top inset, with a one-backing-pixel optical Y compensation.

Centralizes the frame/top-inset calculation in shared helpers and reuses it in both the AppKit WindowDecorationsController click target and the SwiftUI VerticalTabsSidebar padding (now passed observedWindow). Adds a regression XCTest that creates a real NSWindow, installs the minimal-mode click target, and asserts its center aligns to the traffic-light center plus the optical offset.

Reviewed by Cursor Bugbot for commit 79adecf. Bugbot is set up for automated code reviews on this repo. Configure here.


Summary by cubic

Fixes #4475 by aligning minimal-mode sidebar titlebar controls to the macOS close button using live geometry. Click targets and padding now match at all scales, and window decoration updates run on the main actor.

  • Bug Fixes
    • Derive the host frame from live traffic-light bounds, handling flipped coordinates; fall back to the previous inset when unavailable, and apply a scale-aware one-pixel optical Y offset.
    • Centralize geometry in minimalModeSidebarTitlebarControlsFrame and reuse it for both the AppKit click target and SwiftUI padding; ContentView now passes observedWindow so VerticalTabsSidebar computes top padding via minimalModeSidebarTitlebarControlsTopInset(in:).
    • Share a minimalModeTrafficLightFrameInContentCoordinates helper to convert the close-button frame into content coordinates for both AppKit and tests.
    • Mark WindowDecorationsController and helpers @MainActor; add a self-contained regression test that asserts the host center tracks the traffic-light center plus the optical offset, without introducing new warnings.

Written for commit 79adecf. Summary will update on new commits. Review in cubic

Summary by CodeRabbit

  • Bug Fixes
    • Minimal-mode sidebar titlebar controls now align reliably with the window traffic‑light buttons across display scales and flipped/non‑flipped layouts; top padding and click targets are derived from the actual window geometry for consistent visual alignment and interaction.
  • Tests
    • Added a UI regression test validating minimal‑mode sidebar controls align with the traffic‑light button center in minimal presentation mode.

Review Change Stack

@vercel

vercel Bot commented May 21, 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 May 21, 2026 12:17pm
cmux-staging Building Building Preview, Comment May 21, 2026 12:17pm

@coderabbitai

coderabbitai Bot commented May 21, 2026 •

Copy link
Copy Markdown

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: b1b31b51-18a3-4da0-a463-ba155ecce787

📥 Commits

Reviewing files that changed from the base of the PR and between 9d89c4b and 79adecf.

📒 Files selected for processing (2)
  • Sources/WindowDecorationsController.swift
  • Sources/WindowDragHandleView.swift

📝 Walkthrough

Walkthrough

Compute an optical Y offset and window-aware controls frame for minimal-mode titlebar controls; apply that as top padding in VerticalTabsSidebar and use it in WindowDecorationsController click-target placement; add a regression test asserting alignment with the traffic-light button.

Changes

Minimal Mode Sidebar Icon Vertical Alignment

Layer / File(s) Summary
Layout metric functions and optical offset calculation
Sources/WindowDragHandleView.swift
New helpers: titlebarControlsOpticalYOffset(in:), minimalModeSidebarTitlebarControlsFrame(in:defaults:), minimalModeSidebarTitlebarControlsTopInset(in:defaults:), minimalModeSidebarTitlebarControlsFrame(contentBounds:..., ...), and minimalModeTrafficLightFrameInContentCoordinates(for:) implement backing-scale-derived optical offset, traffic-light conversion, and frame/top-inset computation.
Sidebar window observation and computed padding
Sources/ContentView.swift
VerticalTabsSidebar adds observedWindow: NSWindow? and minimalModeSidebarTitlebarControlsTopPadding (derives inset from window when available, falls back to metrics). ContentView passes observedWindow into the sidebar; minimal-mode padding uses the new computed value.
Window decorations controller frame update
Sources/WindowDecorationsController.swift
applyMinimalModeSidebarTitlebarClickTarget(to:) now sets the target frame via minimalModeSidebarTitlebarControlsFrame(...) using content bounds and flip state instead of direct NSRect computation from static metrics. File annotated @MainActor.
Alignment verification test
cmuxTests/WindowAndDragTests.swift
New testMinimalModeSidebarTitlebarControlsAlignWithTrafficLightCenter toggles minimal mode, creates an NSWindow with hidden titlebar, applies decorations, finds the minimal-mode control view, computes expected midY from the close-button frame plus optical offset (flip-aware), and asserts alignment within tolerance.

Sequence Diagram

sequenceDiagram
  participant ContentView
  participant VerticalTabsSidebar
  participant WindowDragHandleView
  participant WindowDecorationsController
  participant NSWindow

  ContentView->>VerticalTabsSidebar: pass observedWindow
  VerticalTabsSidebar->>WindowDragHandleView: request controls top inset/frame
  WindowDragHandleView->>NSWindow: minimalModeTrafficLightFrameInContentCoordinates(for:)
  NSWindow-->>WindowDragHandleView: traffic-light frame or nil
  WindowDragHandleView-->>VerticalTabsSidebar: return controls frame / top inset
  WindowDecorationsController->>WindowDragHandleView: compute click-target frame via minimalModeSidebarTitlebarControlsFrame(...)
  WindowDecorationsController-->>NSWindow: set target.frame
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Poem

🐰 I hop the pixels, scale in tow,
I seek the traffic light's mid-row,
A tiny offset, flipped or true,
Now icons and lights share the view —
A nibble of code, aligned anew.


Caution

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

  • Ignore

❌ Failed checks (1 error, 1 warning)

Check name Status Explanation Resolution
Cmux Swiftui State Layout ❌ Error PR introduces state mutation via DispatchQueue.main.async within render-time context (WindowAccessor closure), violating the rule against scheduling async state writes during body rendering. Replace the DispatchQueue.main.async state write within WindowAccessor with explicit lifecycle callback, .onChange modifier, or async sequence observer that executes outside render context.
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 (15 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: fixing minimal-mode sidebar titlebar icon alignment, which is the primary objective of the PR.
Description check ✅ Passed The description covers all required sections: What Changed, Testing approach, and includes verification steps and local build confirmation. Screenshots and test details are provided.
Linked Issues check ✅ Passed The PR successfully addresses #4475 by deriving controls from live traffic-light frames with optical compensation, ensuring minimal-mode icons align with traffic lights. It layers on top of #4471 (the sibling work already landed) without re-fixing #4469.
Out of Scope Changes check ✅ Passed All code changes are directly scoped to fixing minimal-mode titlebar alignment: geometry helpers, WindowDecorationsController updates, SwiftUI padding adjustments, and a focused regression test. No unrelated changes detected.
Cmux Swift Actor Isolation ✅ Passed No actor isolation issues. SwiftUI View holds NSWindow?, pure functions unisolated, @MainActor wrappers correct, WindowDecorationsController avoids class-wide MainActor to prevent warning regressions.
Cmux Swift Blocking Runtime ✅ Passed PR adds only pure geometry/calculation functions for minimal-mode titlebar controls with no blocking synchronization in production code. Test uses allowed deterministic RunLoop delay.
Cmux No Hacky Sleeps ✅ Passed PR contains only Swift files. The check applies only to TypeScript, JavaScript, shell, and non-Swift scripts; Swift timing is covered separately.
Cmux Swift Concurrency ✅ Passed No legacy async patterns introduced. Zero new DispatchQueue.global, ObservableObject/@published, completion handlers, or fire-and-forget Tasks. Proper @MainActor annotations added.
Cmux Swift @Concurrent ✅ Passed No violations found. PR contains only synchronous functions with @MainActor annotations, no async functions, no @concurrent usage, and pure geometry helpers only.
Cmux Swift File And Package Boundaries ✅ Passed PR adds 97 geometry helpers to existing 1593-line file (under 250-line threshold) and 9 lines to oversized ContentView. Focused bug fix with no mixed responsibilities or new oversized files.
Cmux Swift Logging ✅ Passed PR adds one NSLog guarded by #if DEBUG for feedback submission error diagnostics; all other logging uses cmuxDebugLog. Complies with swift-logging.md rules for debug-only logging.
Cmux User-Facing Error Privacy ✅ Passed PR adds internal titlebar geometry calculations without exposing vendor names, environment variables, credentials, or error details. Localized strings use proper APIs.
Cmux Full Internationalization ✅ Passed PR adds geometry/layout logic for minimal-mode sidebar alignment with no new user-facing strings. Existing localized UI text uses String(localized:defaultValue:).
Cmux Architecture Rethink ✅ Passed Adds pure geometry helpers from live traffic-light frame. No timing, observers, mutable state, or duplicate paths. Shared functions with documented invariants in regression test.
Cmux Swift Auxiliary Window Close Shortcuts ✅ Passed PR modifies titlebar geometry/layout in existing windows and adds a test-only fixture window. No production NSWindow/NSPanel/WindowGroup created without proper identifiers. Lint script passes.
✨ 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 issue-4475-minimal-mode-sidebar-icon-offset

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

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

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

No issues found across 4 files

Re-trigger cubic

Comment thread Sources/WindowDragHandleView.swift
@greptile-apps

greptile-apps Bot commented May 21, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

Fixes minimal-mode sidebar titlebar control misalignment (#4475) by replacing a fixed leftControlsTopInset with live macOS traffic-light geometry. Both the AppKit click target and the SwiftUI sidebar padding now derive from the same centralized minimalModeSidebarTitlebarControlsFrame helper, with a scale-aware one-backing-pixel optical Y compensation.

  • Geometry centralization: New file-scope helpers in WindowDragHandleView.swift compute the host frame from the close-button's converted content-coordinate frame; a fallback to the legacy inset is preserved when standardWindowButton(.closeButton) is unavailable.
  • SwiftUI/AppKit parity: ContentView now passes observedWindow to VerticalTabsSidebar, which derives its top padding via minimalModeSidebarTitlebarControlsTopInset(in:), ensuring the visible controls and the click target share the same geometry.
  • Regression test: A new XCTest creates a real NSWindow, applies WindowDecorationsController in minimal mode, and asserts the installed target center equals traffic-light center ± the optical offset (accuracy 0.25 pt).

Confidence Score: 5/5

Safe to merge; the geometry math is correct for both flipped and non-flipped coordinate systems, the legacy fallback is preserved, and a regression test validates the key invariant.

The centralized frame calculation correctly handles flipped vs. non-flipped AppKit coordinate systems, the optical adjustment applies symmetrically in both orientations, the nil-close-button fallback retains previous behavior, and the SwiftUI padding derives from the same helper as the AppKit click target so the two cannot drift apart.

No files require special attention; all four changed files are focused and internally consistent.

Important Files Changed

Filename Overview
Sources/WindowDragHandleView.swift Adds centralized geometry helpers and an optical-offset utility; coordinate math is correct for both flipped and non-flipped coordinate systems.
Sources/WindowDecorationsController.swift Replaces the fixed-inset AppKit click-target frame with a live traffic-light-derived frame; falls back to legacy inset when the close button is unavailable.
Sources/ContentView.swift Threads observedWindow into VerticalTabsSidebar so the SwiftUI top padding derives from the same live traffic-light geometry as the AppKit click target.
cmuxTests/WindowAndDragTests.swift Adds a regression test that creates a real NSWindow, applies WindowDecorationsController in minimal mode, and asserts the installed click-target center tracks the traffic-light center plus the optical Y offset.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["applyMinimalModeSidebarTitlebarClickTarget(to:)"] --> B["minimalModeTrafficLightFrameInContentCoordinates(window:contentView:)"]
    B --> C{closeButton found?}
    C -- Yes --> D["closeButtonSuperview.convert(frame, to: contentView)"]
    C -- No --> E["nil → fallback path"]
    D --> F["minimalModeSidebarTitlebarControlsFrame(contentBounds:contentViewIsFlipped:trafficLightFrameInContent:visualDownwardAdjustment:)"]
    E --> F
    F --> G["target.frame = NSRect centered on traffic-light midY ± opticalYOffset"]
    H["VerticalTabsSidebar.minimalModeSidebarTitlebarControlsTopPadding"] --> I["minimalModeSidebarTitlebarControlsTopInset(in: observedWindow)"]
    I --> J["minimalModeSidebarTitlebarControlsFrame(in: window)"]
    J --> F
    I --> K[".padding(.top, inset) on TitlebarControlsView"]
    style F fill:#d4edda,stroke:#28a745
    style G fill:#cce5ff,stroke:#004085
    style K fill:#cce5ff,stroke:#004085
Loading

Reviews (5): Last reviewed commit: "fix: share traffic light frame helper" | Re-trigger Greptile

Comment thread Sources/WindowDecorationsController.swift Outdated
Comment thread Sources/WindowDragHandleView.swift
Comment thread cmuxTests/WindowAndDragTests.swift

Copy link
Copy Markdown
Contributor

Addressed the remaining Greptile note in 9d89c4ba6: WindowDecorationsController is now @MainActor, and the minimal-mode click-target frame calls the isolated geometry helper directly instead of using MainActor.assumeIsolated. I did not run a local build after the latest user instruction; CI is the verifier for this update.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 9d89c4b. Configure here.

Comment thread Sources/WindowDecorationsController.swift Outdated

Copy link
Copy Markdown
Contributor

Follow-up pushed in 73165c7c4: the class-wide @MainActor annotation satisfied the review note but introduced new Swift warning-budget entries in tests-build-and-lag. I narrowed the fix so the controller no longer uses MainActor.assumeIsolated, and it feeds the shared pure frame calculator with the content bounds, flipped state, traffic-light frame, and backing-scale optical offset directly. No local build was run.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@Sources/WindowDecorationsController.swift`:
- Around line 415-431: Extract the duplicated traffic-light frame conversion
into a shared helper and call it from both WindowDecorationsController and
WindowDragHandleView: replace the inline closure assigned to
trafficLightFrameInContent in WindowDecorationsController with a call to a new
internal function trafficLightFrameInContentCoordinates(window:contentView:) (or
make minimalModeTrafficLightFrameInContentCoordinates internal) that
encapsulates the guard-for-closeButton + superview.convert(closeButton.frame,
to: contentView) logic, then pass its result into
minimalModeSidebarTitlebarControlsFrame; this removes the duplicate logic that
currently mirrors minimalModeTrafficLightFrameInContentCoordinates and keeps
behavior unchanged while avoiding `@MainActor` issues.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 0469b6e8-d87a-489f-b807-41eeb1c76aef

📥 Commits

Reviewing files that changed from the base of the PR and between 9d89c4b and 73165c7.

📒 Files selected for processing (2)
  • Sources/WindowDecorationsController.swift
  • Sources/WindowDragHandleView.swift

Comment thread Sources/WindowDecorationsController.swift Outdated

Copy link
Copy Markdown
Contributor

@coderabbitai review

The requested shared traffic-light frame helper has been pushed in 79adecf86, and the inline thread is resolved.

@coderabbitai

coderabbitai Bot commented May 21, 2026

Copy link
Copy Markdown

@lawrencecchen Sure! I'll review the latest changes including the shared traffic-light frame helper in 79adecf86 and the preceding commits.

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@austinywang
austinywang merged commit 9b36eed into main May 21, 2026
24 checks passed
@austinywang austinywang mentioned this pull request May 22, 2026

This branch was successfully deployed

1 active deployment
Preview – cmux — 79adecf8 Deployed May 21, 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

2 participants