Skip to content

Minimal mode follow-up review fixes - #1762

Closed
lawrencecchen wants to merge 2 commits into
mainfrom
feat-minimal-mode-review-followups
Closed

lawrencecchen wants to merge 2 commits into
mainfrom
feat-minimal-mode-review-followups

Conversation

@lawrencecchen

@lawrencecchen lawrencecchen commented Mar 18, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • preserve minimal mode for legacy hidden-titlebar installs and scope notifications popover visibility per window
  • route debug shortcut writes through KeyboardShortcutSettings and clear hidden-titlebar accessory layout state when restoring chrome
  • harden Bonsplit and notifications UI coverage against stale setup state, locale-dependent selectors, and leaked raw drags

Test Plan

  • xcodebuild -project GhosttyTabs.xcodeproj -scheme cmux -destination 'platform=macOS' -derivedDataPath /tmp/cmux-feat-minimal-mode-review-followups-green build-for-testing -only-testing:cmuxUITests/BonsplitTabDragUITests -only-testing:cmuxUITests/MultiWindowNotificationsUITests\n- ./scripts/reload.sh --tag feat-minimal-mode-review-followups\n- GitHub Actions: test-e2e.yml with BonsplitTabDragUITests and MultiWindowNotificationsUITests\n

Summary by cubic

Preserves Minimal mode for legacy hidden-titlebar setups and persists it to UserDefaults, and scopes the notifications popover per window to prevent cross-window leaks. Also routes debug shortcut updates through KeyboardShortcutSettings and improves UI test stability.

  • Bug Fixes
    • Notifications popover is now window-scoped: visibility posts carry the window, views filter by matching window, and isNotificationsPopoverShown(in:) checks per-window.
    • Clears all titlebar accessory layout caches when restoring chrome to avoid stale sizing.
    • Initializes and stores WorkspacePresentationMode from the legacy hidden-titlebar preference when unset; otherwise defaults to Standard.
    • Hardened UI tests: added a stable empty-state identifier and fixed drag sequencing to avoid leaked drags.

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

Summary by CodeRabbit

  • Bug Fixes

    • Improved notification popover visibility tracking for multi-window scenarios.
    • Fixed workspace presentation mode initialization to properly fall back to legacy titlebar preferences.
    • Simplified sidebar visibility logic during app startup.
  • Tests

    • Added tests for per-window notification popover scoping.
    • Enhanced UI tests for improved accessibility detection.

@vercel

vercel Bot commented Mar 18, 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 Mar 25, 2026 4:14am

@greptile-apps greptile-apps Bot left a comment

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.

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

@coderabbitai

coderabbitai Bot commented Mar 18, 2026 •

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

This pull request implements per-window notification popover visibility tracking, refactors shortcut storage through a centralized API instead of direct UserDefaults access, fixes sidebar visibility logic inversion, improves workspace presentation mode initialization with titlebar handling, and updates corresponding UI and unit tests.

Changes

Cohort / File(s) Summary
Per-Window Notification Popover Tracking
Sources/Update/UpdateTitlebarAccessory.swift
Introduces host window tracking in TitlebarControlsViewModel with setHostWindow(_:) and helper function titlebarControlsShouldHandlePopoverVisibilityChange(). Updates popover presentation/dismissal to store/clear per-window host references and post visibility changes with correct window context. Extends controllers with per-window isNotificationsPopoverShown(in:) lookup.
Sidebar & Popover Visibility
Sources/AppDelegate.swift
Inverts sidebar visibility logic from conditional assignment to direct negation. Adds public method isNotificationsPopoverShown(in:) that delegates to titlebarAccessoryController.
Shortcut Storage Refactoring
Sources/TerminalController.swift
Replaces direct UserDefaults access (defaultsKey) with action-based KeyboardShortcutSettings API. Updates save/reset/clear paths to use KeyboardShortcutSettings.setShortcut() and resetShortcut() instead of manual defaults manipulation.
Workspace Presentation Mode Initialization
Sources/cmuxApp.swift
Adds initializeStoredModeIfNeeded() helper to establish consistent stored presentation mode during startup. Updates mode(defaults:) with fallback to .minimal when titlebar is hidden and no stored value exists. Augments migration logic in WorkspaceButtonFadeSettings.
Unit Test Updates
cmuxTests/AppDelegateShortcutRoutingTests.swift, cmuxTests/UpdatePillReleaseVisibilityTests.swift
Renames and refactors existing test to verify legacy titlebar preference fallback behavior. Adds new test testWorkspaceMinimalModeDefaultsToStandardPresentationWithoutLegacyPreference. Introduces test testPopoverVisibilityNotificationsAreScopedToMatchingWindow to verify per-window notification scoping.
UI Test Updates
cmuxUITests/BonsplitTabDragUITests.swift, cmuxUITests/MultiWindowNotificationsUITests.swift
Replaces static text reference "No notifications yet" with accessibility identifier "notificationsPopover.emptyState" for more robust empty state detection. Adjusts drag test timing for drop indicator verification.

Sequence Diagram(s)

sequenceDiagram
    participant Window as NSWindow
    participant TitlebarControls as TitlebarControlsViewModel
    participant NotificationPopover as TitlebarControlsAccessoryViewController
    participant Controller as UpdateTitlebarAccessoryController
    participant Delegate as AppDelegate

    Window->>TitlebarControls: setHostWindow(window)
    TitlebarControls->>TitlebarControls: Update hostWindow & hostWindowNumber
    
    Note over NotificationPopover: User triggers popover
    NotificationPopover->>NotificationPopover: Store popoverHostWindow = window
    NotificationPopover->>Controller: Post cmuxNotificationsPopoverVisibilityDidChange<br/>(object: window)
    
    Controller->>Controller: Receive notification with window context
    Controller->>Controller: titlebarControlsShouldHandlePopoverVisibilityChange<br/>(hostWindowNumber, notificationObject)
    
    alt Window Matches
        Controller->>Controller: Update isNotificationsPopoverShown = true
    else Window Mismatch
        Controller->>Controller: Ignore notification
    end
    
    Delegate->>Controller: isNotificationsPopoverShown(in: window)
    Controller-->>Delegate: Return per-window visibility state
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

🐰 A window's secrets now unfold,
Pop-overs tracked in windows bold,
Per-pane awareness, side-by-side,
State and shortcuts unified with pride!
Shortcuts settled, modes refined—
Multi-window harmony aligned! 🪟✨

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 3.57% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ⚠️ Warning The pull request description provides a summary of changes and test plan, but lacks critical sections from the template including testing details, demo video, and review trigger. Add the Testing section with manual verification details, include a demo video link (if applicable), provide the Review Trigger comment block, and complete the Checklist items to meet the required template structure.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Minimal mode follow-up review fixes' accurately describes the core changes: it addresses follow-up fixes related to minimal mode functionality including notification popover scoping, legacy preference handling, and test hardening.

✏️ 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 feat-minimal-mode-review-followups

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 8 files

@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 the current code and only fix it if needed.

Inline comments:
In `@Sources/Update/UpdateTitlebarAccessory.swift`:
- Around line 1459-1466: isNotificationsPopoverShown(in:) can miss popovers
anchored externally; update the per-window check to also consider the popover's
external anchor window. In the predicate over controlsControllers.allObjects
(and using controller.popoverIsShownForTesting), treat a controller as shown for
the given window if controller.view.window === window OR if the controller's
popover has an externalAnchor whose window === window (e.g. check
controller.popover?.externalAnchor?.window). This ensures externally anchored
popovers are counted in the per-window visibility lookup.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d7931b07-3eae-48a0-84be-159ca4c10446

📥 Commits

Reviewing files that changed from the base of the PR and between 63e65a7 and 1e98296.

📒 Files selected for processing (8)
  • Sources/AppDelegate.swift
  • Sources/TerminalController.swift
  • Sources/Update/UpdateTitlebarAccessory.swift
  • Sources/cmuxApp.swift
  • cmuxTests/AppDelegateShortcutRoutingTests.swift
  • cmuxTests/UpdatePillReleaseVisibilityTests.swift
  • cmuxUITests/BonsplitTabDragUITests.swift
  • cmuxUITests/MultiWindowNotificationsUITests.swift

Comment on lines +1459 to +1466
func isNotificationsPopoverShown(in window: NSWindow?) -> Bool {
guard let window else {
return isNotificationsPopoverShown()
}
return controlsControllers.allObjects.contains { controller in
controller.popoverIsShownForTesting && controller.view.window === window
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Per-window visibility lookup can be wrong for externally anchored popovers.

isNotificationsPopoverShown(in:) checks controller.view.window === window, but popovers may be shown in externalAnchor.window (which can differ from the controller’s window). That causes false negatives when seeding per-window popover state.

Suggested fix
@@
 final class TitlebarControlsAccessoryViewController: NSTitlebarAccessoryViewController, NSPopoverDelegate {
@@
     var popoverIsShownForTesting: Bool { notificationsPopover.isShown }
+    func isNotificationsPopoverShown(in window: NSWindow?) -> Bool {
+        guard notificationsPopover.isShown else { return false }
+        guard let window else { return true }
+        return popoverHostWindow === window || view.window === window
+    }
@@
     func isNotificationsPopoverShown(in window: NSWindow?) -> Bool {
         guard let window else {
             return isNotificationsPopoverShown()
         }
         return controlsControllers.allObjects.contains { controller in
-            controller.popoverIsShownForTesting && controller.view.window === window
+            controller.isNotificationsPopoverShown(in: window)
         }
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Sources/Update/UpdateTitlebarAccessory.swift` around lines 1459 - 1466,
isNotificationsPopoverShown(in:) can miss popovers anchored externally; update
the per-window check to also consider the popover's external anchor window. In
the predicate over controlsControllers.allObjects (and using
controller.popoverIsShownForTesting), treat a controller as shown for the given
window if controller.view.window === window OR if the controller's popover has
an externalAnchor whose window === window (e.g. check
controller.popover?.externalAnchor?.window). This ensures externally anchored
popovers are counted in the per-window visibility lookup.

…iew-followups

# Conflicts:
#	Sources/TerminalController.swift
@lawrencecchen lawrencecchen added the stale-revisit Closed after 30+ days without activity; preserved for possible revisit or reopening. label Sep 23, 2026
@github-project-automation github-project-automation Bot moved this from Todo to Done in cmux backlog Sep 23, 2026

This branch was successfully deployed

1 active deployment
Preview — ee831085 Deployed Mar 25, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

stale-revisit Closed after 30+ days without activity; preserved for possible revisit or reopening.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants