Repository navigation
Restore modern macOS Settings chrome (regression from #4975) - #5073
austinywang wants to merge 4 commits into
Conversation
Asserts that SettingsWindowPresenter.configure(window:) applies the modern macOS Settings chrome (unified compact toolbar, full-size content view, transparent titlebar, attached NSToolbar). Fails on main because the chrome is never applied after the #4975 Settings rewrite switched from the SwiftUI Settings { } scene to a generic Window(...) scene. Regression from #4975. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughThe PR applies modern macOS Settings window chrome (unified compact toolbar, transparent titlebar, full-size content view). A new presenter helper configures AppKit window properties; the presenter invokes it during setup and the SwiftUI scene sets the toolbar style modifier. ChangesSettings window modern chrome
Sequence Diagram: sequenceDiagram
participant Scene as SwiftUI Scene
participant Presenter as SettingsWindowPresenter
participant Window as NSWindow
participant Toolbar as NSToolbar
Scene->>Presenter: provide NSWindow
Presenter->>Window: applyModernSettingsChrome(window)
Presenter->>Toolbar: ensure toolbar exists
Presenter->>Window: set toolbarStyle and separator
🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs:
🚥 Pre-merge checks | ✅ 17 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (17 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
The #4975 Settings rewrite switched the Settings scene from SwiftUI's `Settings { }` (which gets the modern unified-compact Settings chrome for free on macOS 14+) to a generic `Window(...)` scene, which defaults to the legacy titled-window chrome. Path A (chosen over Path B): keep the `Window(...)` scene so the existing multi-instance / window-ID deep-link hooks (`openWindow(id: SettingsWindowPresenter.windowID)`) keep working, and apply the chrome explicitly: - Add `.windowToolbarStyle(.unifiedCompact)` to the SwiftUI Window scene. - Extend `SettingsWindowPresenter.configure(window:)` to insert `.fullSizeContentView`, set `titlebarAppearsTransparent`/`titleVisibility`, attach an `NSToolbar`, and set `toolbarStyle = .unifiedCompact` on the AppKit window. Fixes #5071. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
f61ae25 to
ab023e7
Compare
Greptile SummaryThis PR restores the modern macOS Settings window chrome (unified compact toolbar, transparent/hidden titlebar, full-size content view, no titlebar separator) that was implicitly provided by the SwiftUI
Confidence Score: 5/5Presentation-only chrome restoration with no impact on app state, data, or auth; all five AppKit properties are idempotently applied and fully covered by the new test. The change is narrowly scoped to window chrome: five AppKit properties set idempotently in a private helper, a single SwiftUI scene modifier, and a test that asserts every property. No logic, state, or data flow is touched. No files require special attention. Important Files Changed
Sequence DiagramsequenceDiagram
participant Scene as cmuxApp Window Scene
participant WA as WindowAccessor
participant SWP as SettingsWindowPresenter
participant NSW as NSWindow
Scene->>NSW: Create Window("Settings", id: "settings")
Scene->>NSW: .windowToolbarStyle(.unifiedCompact)
NSW-->>WA: window callback
WA->>SWP: configure(window:)
SWP->>NSW: applyModernSettingsChrome()
Note over SWP,NSW: styleMask.insert(.fullSizeContentView)<br/>titlebarAppearsTransparent = true<br/>titleVisibility = .hidden<br/>NSToolbar (if window.toolbar == nil)<br/>toolbarStyle = .unifiedCompact<br/>titlebarSeparatorStyle = .none
SWP->>NSW: clampToVisibleAreaIfNeeded()
SWP->>NSW: attachToPreferredParent()
Reviews (3): Last reviewed commit: "Migrate SettingsWindowPresenterTests to ..." | Re-trigger Greptile |
| if window.toolbar == nil { | ||
| let toolbar = NSToolbar(identifier: toolbarIdentifier) | ||
| toolbar.allowsUserCustomization = false | ||
| window.toolbar = toolbar | ||
| } | ||
| window.toolbarStyle = .unifiedCompact | ||
| } |
There was a problem hiding this comment.
On macOS 12+,
NSWindow.titlebarSeparatorStyle is the authoritative control for the separator line drawn between the titlebar area and the scrolling content. toolbar.showsBaselineSeparator = false suppresses the toolbar's own baseline separator but does not affect the window-level separator that titlebarSeparatorStyle controls. Without setting .none here, the window may render a shadow/line under the toolbar when content scrolls beneath it, which the original Settings { } scene suppressed automatically. The test does not assert titlebarSeparatorStyle, so this would not be caught by CI.
| if window.toolbar == nil { | |
| let toolbar = NSToolbar(identifier: toolbarIdentifier) | |
| toolbar.allowsUserCustomization = false | |
| window.toolbar = toolbar | |
| } | |
| window.toolbarStyle = .unifiedCompact | |
| } | |
| if window.toolbar == nil { | |
| let toolbar = NSToolbar(identifier: toolbarIdentifier) | |
| toolbar.allowsUserCustomization = false | |
| toolbar.showsBaselineSeparator = false | |
| window.toolbar = toolbar | |
| } | |
| window.toolbarStyle = .unifiedCompact | |
| window.titlebarSeparatorStyle = .none |
There was a problem hiding this comment.
Agreed — fixed. Added window.titlebarSeparatorStyle = .none (the non-deprecated, window-level control) instead of showsBaselineSeparator, and added a test assertion for it so CI covers the property. Pushed in efa7b82.
— Claude Code
| XCTAssertEqual(settingsWindow.toolbarStyle, .unifiedCompact) | ||
| XCTAssertTrue(settingsWindow.styleMask.contains(.fullSizeContentView)) | ||
| XCTAssertTrue(settingsWindow.titlebarAppearsTransparent) | ||
| XCTAssertNotNil(settingsWindow.toolbar) |
There was a problem hiding this comment.
The test validates four of the five properties set by
applyModernSettingsChrome, but omits an assertion for titleVisibility == .hidden. Adding it closes the coverage gap and ensures that property stays wired up if applyModernSettingsChrome is refactored later.
| XCTAssertEqual(settingsWindow.toolbarStyle, .unifiedCompact) | |
| XCTAssertTrue(settingsWindow.styleMask.contains(.fullSizeContentView)) | |
| XCTAssertTrue(settingsWindow.titlebarAppearsTransparent) | |
| XCTAssertNotNil(settingsWindow.toolbar) | |
| XCTAssertEqual(settingsWindow.toolbarStyle, .unifiedCompact) | |
| XCTAssertTrue(settingsWindow.styleMask.contains(.fullSizeContentView)) | |
| XCTAssertTrue(settingsWindow.titlebarAppearsTransparent) | |
| XCTAssertEqual(settingsWindow.titleVisibility, .hidden) | |
| XCTAssertNotNil(settingsWindow.toolbar) |
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
There was a problem hiding this comment.
Done — added XCTAssertEqual(settingsWindow.titleVisibility, .hidden) (and also titlebarSeparatorStyle == .none for the new property). Pushed in efa7b82.
— Claude Code
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 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 `@cmuxTests/SettingsWindowPresenterTests.swift`:
- Around line 18-30: This XCTest-based test must be converted to Swift Testing:
change import XCTest to import Testing, change final class
SettingsWindowPresenterTests: XCTestCase to be annotated `@Suite` `@MainActor` final
class SettingsWindowPresenterTests, rename func
testConfigureWindowAppliesModernSettingsChrome() to `@Test` func
configureWindowAppliesModernSettingsChrome(), replace assertions
(XCTAssertEqual/XCTAssertTrue/XCTAssertNotNil) with `#expect`(...) forms (e.g.
`#expect`(settingsWindow.toolbarStyle == .unifiedCompact),
`#expect`(settingsWindow.styleMask.contains(.fullSizeContentView)),
`#expect`(settingsWindow.titlebarAppearsTransparent),
`#expect`(settingsWindow.toolbar != nil)), and ensure test cleanup calls
SettingsWindowPresenter.resetForTests() via a defer in the test; keep use of
makeWindow(...) and SettingsWindowPresenter.configure(window:) and the defer
that orderOut(nil).
In `@Sources/App/SettingsWindowPresenter.swift`:
- Around line 259-263: The toolbar created in SettingsWindowPresenter.swift (the
NSToolbar instance constructed using toolbarIdentifier and assigned to
window.toolbar) is missing the no-baseline-separator setting; after creating the
toolbar in the block where you set window.toolbar = toolbar, set
toolbar.showsBaselineSeparator = false on that NSToolbar instance so the
Settings chrome matches the modern macOS appearance.
🪄 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: 1f890b2f-48cc-48cd-baa3-560e1ebbc299
📒 Files selected for processing (3)
Sources/App/SettingsWindowPresenter.swiftSources/cmuxApp.swiftcmuxTests/SettingsWindowPresenterTests.swift
Address review feedback: NSToolbar.showsBaselineSeparator (deprecated in
macOS 15) does not control the window-level separator. Set
window.titlebarSeparatorStyle = .none — the authoritative, non-deprecated
API — so the titlebar stays seamless when content scrolls, matching the
old Settings { } scene. Extend the regression test to assert titleVisibility
and titlebarSeparatorStyle so both stay wired up.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Per the repo coding guidelines (Swift Testing for all new/touched unit tests), convert the suite from XCTest to Swift Testing: import Testing, @suite struct with @test methods, #expect/#require assertions. Add .serialized because every test mutates SettingsWindowPresenter's shared static state and resets it on exit, which Swift Testing's default parallel execution would otherwise race. tearDown's resetForTests() is now a per-test defer; the XCTSkip-on-no-screen guard becomes an early return. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Summary
After the Settings rewrite in #4975, the Settings window rendered with the legacy macOS titled-window chrome instead of the modern macOS Settings chrome on macOS 14+/Tahoe. The rewrite switched the Settings scene from SwiftUI's
Settings { }(which gets the modern unified-compact Settings chrome for free) to a genericWindow(...)scene, which defaults to the legacy titled-window look. Neither the SwiftUI scene norSettingsWindowPresenter.configure(window:)applied the chrome explicitly.Fix — Path A (chosen over Path B)
Path A preserves the
Window(...)scene and applies the chrome explicitly. I chose it over Path B (reverting toSettings { }) because theWindow(...)form backs the existing multi-instance / window-ID deep-link hooks —openWindow(id: SettingsWindowPresenter.windowID)(Sources/cmuxApp.swift:251) and thewindowIdentifier-based focus/reuse logic inSettingsWindowPresenter. The dedicatedSettings { }scene lacks thoseopenWindow(id:)hooks, so switching scenes would be a larger, riskier change. Path A is the smaller, safer fix.Changes:
Sources/cmuxApp.swift— add.windowToolbarStyle(.unifiedCompact)to the SettingsWindow(...)scene.Sources/App/SettingsWindowPresenter.swift—configure(window:)now applies.fullSizeContentView,titlebarAppearsTransparent = true,titleVisibility = .hidden, attaches a non-customizableNSToolbarwith no baseline separator, and setstoolbarStyle = .unifiedCompacton the AppKit window.Regression test
Two-commit structure so CI proves the test catches the bug:
testConfigureWindowAppliesModernSettingsChromeincmuxTests/SettingsWindowPresenterTests.swiftdrivesconfigure(window:)and assertstoolbarStyle == .unifiedCompact,styleMask.contains(.fullSizeContentView),titlebarAppearsTransparent == true, andtoolbar != nil.Fixes #5071.
🤖 Generated with Claude Code
Note
Low Risk
UI-only window chrome and test harness changes; existing Settings window ID, focus, and parenting behavior are unchanged.
Overview
Restores modern macOS Settings window chrome after the Settings scene moved from SwiftUI
Settings { }to a genericWindow(...), which regressed to legacy titled-window styling.SettingsWindowPresenter.configure(window:)now callsapplyModernSettingsChrome, setting full-size content view, transparent/hidden titlebar, a fixed non-customizableNSToolbar, unified compact toolbar style, and no titlebar separator. The SettingsWindowscene incmuxAppalso applies.windowToolbarStyle(.unifiedCompact)so SwiftUI and AppKit stay aligned.Tests in
SettingsWindowPresenterTestsmigrate from XCTest to Swift Testing (serialized suite for shared static state) and add coverage that configuration applies the modern chrome flags.Reviewed by Cursor Bugbot for commit 152c881. Bugbot is set up for automated code reviews on this repo. Configure here.
Need help on this PR? Tag
@codesmithwith what you need. Autofix is disabled.Summary by CodeRabbit
New Features
Tests