Skip to content

Fit main windows after display topology changes - #7308

Merged
austinywang merged 21 commits into
mainfrom
issue-7306-multi-monitor-window-cutoff
Jul 8, 2026
Merged

austinywang merged 21 commits into
mainfrom
issue-7306-multi-monitor-window-cutoff

Conversation

@austinywang

@austinywang austinywang commented Jul 4, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Add MainWindowVisibleFrameFitCore, a pure CmuxWindowing decision core that preserves frames already fully covered by the union of current visible displays and otherwise clamps/shrinks into the best current display.
  • Install a topology-signature-gated AppKit shell for didChangeScreenParametersNotification, so live display changes can rescue reachable-titlebar-but-cut-off main windows without reacting to Dock side/bottom resizes.
  • Route session restore through the same fit core after saved display geometry no longer matches the current arrangement, while preserving fully visible windows that span adjacent displays.
  • Trim three blank lines from WorkspaceDetailView.swift to clear an existing file-budget overage without touching unrelated code.
  • Merge current origin/main into the branch; the PR diff against main remains the focused window-fit change.

Fixes #7306

Related

Tests

  • Added a red/green regression pair: the first commit adds the failing restore regression, and the next implementation commit adds the fit core and integration fix.
  • Added follow-up regression coverage for nearest-visible-frame fallback, fully visible spanning windows, and restore-time spanning-window preservation.
  • Not run locally per task instruction: app build, local unit tests, XCUITests, reload scripts.
  • Ran ./scripts/check-pbxproj.sh.
  • Ran ./scripts/lint-pbxproj-test-wiring.sh.
  • Ran git diff --check origin/main...HEAD.
  • Ran python3 scripts/swift_file_length_budget.py.
  • Ran python3 scripts/check-package-resolved-policy.py.
  • Ran python3 scripts/check-workspace-package-groups.py --check.

Localization

No user-facing strings were added by this PR diff. New strings in the PR diff are test names, debug log identifiers, and Sentry breadcrumb metadata. After merging current origin/main, parsed web/messages/en.json and web/messages/ja.json successfully and verified the existing platform FAQ waitlist copy is present in both locales.


Note

Medium Risk
Changes window geometry on display topology changes and session restore; incorrect gating could move windows on Dock-only resizes or fail to rescue clipped frames, but logic is heavily unit-tested and gated separately from per-monitor config restore.

Overview
Adds MainWindowVisibleFrameFitCore in CmuxWindowing to decide when a main-window frame is already fully covered by current visible displays (no move) and otherwise clamp/shrink it onto the best display, including multi-monitor overlap and nearest-display fallback.

On live display changes, AppDelegate tracks a separate topology signature (stable display IDs, quantized frames, top menu-bar inset only—not Dock side/bottom resizes) and runs MainWindowVisibleFrameFitRescue only when that signature changes, alongside the existing titlebar-stranding reconcile pass.

Session restore now routes intersecting saved frames through the same fit core instead of preserving any frame with a reachable titlebar, while still leaving fully visible frames untouched (including windows spanning adjacent displays).

Also removes three blank lines in WorkspaceDetailView.swift for file-length budget and wires tests plus CmuxWindowing into the app/test targets.

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

Summary by CodeRabbit

  • New Features

    • Main windows now refit more intelligently to stay within the currently visible screen area when display arrangements change.
  • Bug Fixes

    • Improved clamping/restoration for offscreen or partially hidden windows so they reopen reliably within visible bounds.
    • Reduced unnecessary window movement when the effective visible display topology hasn’t changed.
  • Tests

    • Added unit coverage for visible-frame fitting, display-change detection, and window frame restoration behavior.

@vercel

vercel Bot commented Jul 4, 2026 •

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
cmux Canceled Canceled Jul 8, 2026 10:24pm
cmux-staging Building Building Preview, Comment Jul 8, 2026 10:24pm

@coderabbitai

coderabbitai Bot commented Jul 4, 2026 •

Copy link
Copy Markdown

Review Change Stack

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
📝 Walkthrough

Walkthrough

Adds a macOS visible-frame fitting core, a screen-change rescue pass, AppDelegate integration, project/test wiring, and iOS boundary edits.

Changes

Window frame fitting

Layer / File(s) Summary
Topology contract
Packages/macOS/CmuxWindowing/Sources/CmuxWindowing/Geometry/MainWindowVisibleFrameTopologySignatureEntry.swift, Packages/macOS/CmuxWindowing/Sources/CmuxWindowing/Summaries/SessionDisplayGeometry.swift, Packages/macOS/CmuxWindowing/Sources/CmuxWindowing/Geometry/MainWindowVisibleFrameFitCore.swift
Adds the display topology entry type, updates display-identity documentation, and adds the core APIs for topology signatures and fitted frames.
Fitting algorithm
Packages/macOS/CmuxWindowing/Sources/CmuxWindowing/Geometry/MainWindowVisibleFrameFitCore.swift
Implements frame validation, display selection, clamping, and full-coverage and equality checks used by the fitting core.
Display rescue pass
Sources/App/MainWindowVisibleFrameFitRescue.swift, Sources/AppDelegate.swift
Adds the rescue controller, installs it at startup, and routes resolved window-frame fitting through the new core.
Project wiring and tests
cmux.xcodeproj/project.pbxproj, cmuxTests/MainWindowVisibleFrameFitCoreTests.swift
Adds the framework and test file references to the project and includes unit tests for fitting and restore behavior.

Estimated code review effort: 4 (Complex) | ~60 minutes

iOS WorkspaceDetailView boundary edits

Layer / File(s) Summary
Boundary whitespace adjustments
Packages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/WorkspaceDetailView.swift
Adjusts placement around activeBrowser, iOS toolbar title scope, and detailSurfaceContent scope boundaries.

Estimated code review effort: 1 (Trivial) | ~3 minutes


Important

Pre-merge checks failed

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

❌ Failed checks (1 error, 1 warning)

Check name Status Explanation Resolution
Cmux Architecture Rethink ❌ Error Adds a second didChangeScreenParametersNotification observer and a Task.yield repair path in a new owner, duplicating AppDelegate's existing screen-change lifecycle handling. Fold visible-frame refitting into the existing screen-change/reconcile owner (or one window-frame coordinator) and remove the extra yield-based observer/path.
Description check ⚠️ Warning The description has summary and testing details, but it omits the required Demo Video, Review Trigger, and Checklist sections from the template. Add the missing Demo Video, Review Trigger, and Checklist sections, and ensure the checklist items are explicitly completed or marked not applicable.
✅ Passed checks (23 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The new fit core, topology-gated rescue, and restore-path clamping match #7306's requirement to refit stale offscreen or oversized main windows.
Out of Scope Changes check ✅ Passed The whitespace trim and project/test wiring are still aligned with the stated window-fit and file-budget work, with no clear unrelated changes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Cmux Swift Actor Isolation ✅ Passed The added Swift types are pure value models or explicit @MainActor UI coordination; no new implicit MainActor coupling or background UI access was introduced.
Cmux Swift Blocking Runtime ✅ Passed PASS: the new fit rescue uses only a non-blocking Task.yield deferral; no semaphores, sleeps, sync waits, polling, or locks were introduced.
Cmux Browser Automation Off-Main ✅ Passed PR only adds window-fit rescue/core/tests and a whitespace trim; it does not modify browser socket automation routing files or browser.* command handling.
Cmux Expensive Synchronous Load ✅ Passed No touched file adds or moves agent-history loads; the diff is display-fit geometry only, and scans found no new RestorableAgentSessionIndex.load/JSON parse paths.
Cmux Cache Substitution Correctness ✅ Passed The new cache is just an event-driven topology-signature guard seeded on install; restore still reads live display geometry, with no stale-cache substitution in a snapshot path.
Cmux No Hacky Sleeps ✅ Passed The only non-Swift change is Xcode project wiring; no TS/JS/shell/build/runtime code adds sleeps, timers, polling, or fixed delays.
Cmux Algorithmic Complexity ✅ Passed The new fitting logic scans windows once and screens per fit; the only nested work is over display geometries, a tiny bounded set, so no scalable nested scans were introduced.
Cmux Swift Concurrency ✅ Passed New async code is limited to an AppKit-notification task that’s stored/cancelled; no new background queues, Combine state, or internal completion-handler APIs were added.
Cmux Swift @Concurrent ✅ Passed PASS: The new async work in MainWindowVisibleFrameFitRescue is explicitly @MainActor UI-bound, and the PR adds no @concurrent misuse or nonisolated async helpers.
Cmux Swift File And Package Boundaries ✅ Passed PASS: core fitting logic lives in CmuxWindowing; app-target changes are only AppKit/session-restore glue, with no oversized or mixed-responsibility production file growth.
Cmux Swiftpm Lockfiles ✅ Passed No .gitignore or Package.resolved changes; the pbxproj diff only wires an existing local CmuxWindowing product into targets, without altering packageReferences or pins.
Cmux Swift Logging ✅ Passed The diff adds no print/debugPrint/dump/NSLog or file/stdout logging; the only new log is DEBUG-gated cmuxDebugLog and a sanitized breadcrumb.
Cmux User-Facing Error Privacy ✅ Passed The PR adds only geometry/rescue logic plus internal debug logs/breadcrumbs; no new user-facing errors, alerts, or recovery copy expose vendor/internal details.
Cmux Full Internationalization ✅ Passed Touched production files only add internal/debug strings and geometry code; no user-facing text, localized APIs, catalogs, or web messages were added.
Cmux Swiftui State Layout ✅ Passed WorkspaceDetailView only had three blank lines removed; no new SwiftUI state, geometry, lazy-row, or render-time mutation was introduced.
Cmux Swift Auxiliary Window Close Shortcuts ✅ Passed Only main-window fit/rescue geometry and tests changed; no standalone auxiliary windows, cmux.* ID assignments, or cmuxAuxiliaryWindowIdentifiers wiring were introduced.
Cmux Source Artifacts ✅ Passed All changed paths are intentional source/config/test files; none are logs, caches, temp folders, build output, or other forbidden artifacts.
Cmux No Test Or Debug Seam In Production Source ✅ Passed No new test-only accessor or debug seam was added in production Sources; the only new #if DEBUG code is diagnostic logging in real window-fit behavior.
Cmux No Ambient Global State ✅ Passed No ambient global state added: the new fit logic is instance-based, the rescue is a private AppDelegate-owned controller, and no new top-level free funcs or singletons were introduced.
Title check ✅ Passed The title clearly summarizes the main change: refitting main windows after display topology changes.
✨ 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-7306-multi-monitor-window-cutoff

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.

@greptile-apps

greptile-apps Bot commented Jul 4, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

Adds MainWindowVisibleFrameFitCore, a pure CmuxWindowing struct that decides whether a window frame is already fully covered by the union of current visible displays and otherwise clamps or shrinks it into the best-overlap display. This core is wired into two call sites: a topology-signature-gated runtime rescue in AppDelegate+MonitorMemory that fires after real display-layout changes (not Dock resizes), and the session-restore path in AppDelegate, which now routes intersecting saved frames through the full-display-list fit instead of single-display clamping.

  • MainWindowVisibleFrameFitCore.fittedFrame uses a rectangle-subtraction algorithm to detect spanning-display windows and a nearest-edge distance fallback for fully off-screen windows, replacing the older center-to-center heuristic.
  • The topology signature excludes side and bottom Dock insets, quantizes sub-point jitter, and is gated on every display having a stable identity — untrusted snapshots keep the previous baseline and schedule a retry via the existing screenChangeReconcileRetryLimit budget.
  • Three blank lines removed from WorkspaceDetailView.swift to clear a file-length budget overage.

Confidence Score: 5/5

Safe to merge; the new fit logic is gated on a real topology change, leaves fully-visible windows untouched, and complements rather than conflicts with the existing stranding-rescue pass.

The core is a pure, side-effect-free struct with thorough unit coverage including red/green regression pairs. The runtime wiring correctly sequences remembered-frame restore → titlebar stranding → visible-fit rescue, so each pass sees already-corrected frames. The only finding is a dead-code fallback that can never fire.

No files require special attention.

Important Files Changed

Filename Overview
Packages/macOS/CmuxWindowing/Sources/CmuxWindowing/Geometry/MainWindowVisibleFrameFitCore.swift New pure decision core for fitting window frames into visible displays — correct rect decomposition, nearest-edge distance fallback, topology signature with stable-ID gating and top-inset-only sensitivity.
Packages/macOS/CmuxWindowing/Sources/CmuxWindowing/Geometry/MainWindowVisibleFrameTopologySignatureEntry.swift New value type representing one display's contribution to the topology signature; quantizes coordinates and captures only the top inset so Dock side/bottom resizes are invisible to the gate.
Sources/App/MainWindowVisibleFrameFitRescue.swift Thin @mainactor shell that maps the fit core's output to NSWindow.setFrame calls; correctly guards full-screen windows and emits Sentry breadcrumbs.
Sources/AppDelegate+MonitorMemory.swift Adds a second topology-signature gate alongside the existing display-config gate; correctly sequences the stranding-rescue pass before the visible-fit rescue so each pass sees already-corrected frames.
Sources/AppDelegate.swift Routes session-restore through fittedFrame with the full display list, replacing the single-display clamp; adds three state vars for the new topology gate and seeds the baseline signature at launch.
cmuxTests/MainWindowVisibleFrameFitCoreTests.swift Comprehensive test suite covering the cut-off, oversized, spanning, nearest-fallback, and topology-signature cases; also validates restore-time clamping and spanning-display preservation through the AppDelegate entry point.
cmuxTests/AppDelegateDisplayConfigRestoreTests.swift Minimal patch to existing tests: zeroes the new visibleFrameFitTopologyRetryBudget in the shared cleanup block so pre-existing tests remain deterministic.
Packages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/WorkspaceDetailView.swift Removes three blank lines to clear an existing file-length budget overage; no functional change.
Packages/macOS/CmuxWindowing/Sources/CmuxWindowing/Summaries/SessionDisplayGeometry.swift Doc-comment update only: clarifies that stableID is now also used for topology-change gates, not just per-monitor geometry memory.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[NSNotification: didChangeScreenParameters] --> B[reconcileMainWindowFramesAfterScreenChange]
    B --> C{displayConfig\nsignatureChanged?}
    C -- yes --> D[restoreRememberedFrames\n→ resolvedWindowFrame\n→ fittedFrame multi-display]
    C -- no --> E[skip restore]
    D --> F
    E --> F[Titlebar stranding rescue loop\nreconciledFrameAfterScreenChange per window]
    F --> G{visibleFrameFit\ntopologyChanged?}
    G -- yes --> H[MainWindowVisibleFrameFitRescue\n.performFitIfNeeded]
    G -- no --> I[done]
    H --> J{fittedFrame per window}
    J -- nil: already fully visible --> K[no-op]
    J -- rect: needs clamp/shrink --> L[NSWindow.setFrame]
    K --> I
    L --> I

    subgraph fittedFrame logic
        M[isFullyCovered by union\nof visible displays?] -- yes --> N[return nil]
        M -- no --> O[targetDisplay:\nmax overlap area\nor nearest edge]
        O --> P[clampFrame within\ntargetDisplay.visibleFrame]
        P --> Q{approx equal\nto original?}
        Q -- yes --> N
        Q -- no --> R[return fitted]
    end
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
    A[NSNotification: didChangeScreenParameters] --> B[reconcileMainWindowFramesAfterScreenChange]
    B --> C{displayConfig\nsignatureChanged?}
    C -- yes --> D[restoreRememberedFrames\n→ resolvedWindowFrame\n→ fittedFrame multi-display]
    C -- no --> E[skip restore]
    D --> F
    E --> F[Titlebar stranding rescue loop\nreconciledFrameAfterScreenChange per window]
    F --> G{visibleFrameFit\ntopologyChanged?}
    G -- yes --> H[MainWindowVisibleFrameFitRescue\n.performFitIfNeeded]
    G -- no --> I[done]
    H --> J{fittedFrame per window}
    J -- nil: already fully visible --> K[no-op]
    J -- rect: needs clamp/shrink --> L[NSWindow.setFrame]
    K --> I
    L --> I

    subgraph fittedFrame logic
        M[isFullyCovered by union\nof visible displays?] -- yes --> N[return nil]
        M -- no --> O[targetDisplay:\nmax overlap area\nor nearest edge]
        O --> P[clampFrame within\ntargetDisplay.visibleFrame]
        P --> Q{approx equal\nto original?}
        Q -- yes --> N
        Q -- no --> R[return fitted]
    end
Loading

Reviews (11): Last reviewed commit: "Fit restored windows using all current d..." | Re-trigger Greptile

Comment on lines +141 to +145
private func distanceSquared(_ rect: CGRect, _ point: CGPoint) -> CGFloat {
let dx = rect.midX - point.x
let dy = rect.midY - point.y
return (dx * dx) + (dy * dy)
}

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 Center-to-center distance for no-overlap fallback

distanceSquared measures from the display's center (rect.midX/rect.midY) to the window's center. When a window is completely off all screens — the only case this fallback fires — a window parked far off the right edge of the main display could score farther from the nearby display's center than from a second display that happens to be centered closer, producing a counterintuitive target. Using the distance from the window center to the nearest point on each visible frame would give a geometrically correct answer regardless of display layout.

Comment on lines +9 to +19
final class MainWindowVisibleFrameFitRescue: NSObject {
private let coalescedFitNotification = Notification.Name("cmux.mainWindowVisibleFrameFitRescue.perform")
private let fitCore: MainWindowVisibleFrameFitCore
private var cachedSignature: [MainWindowVisibleFrameTopologySignatureEntry] = []
private var isInstalled = false

/// Owned and installed by `AppDelegate`.
init(fitCore: MainWindowVisibleFrameFitCore = MainWindowVisibleFrameFitCore()) {
self.fitCore = fitCore
super.init()
}

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 No removeObserver on deallocation

NotificationCenter.default.addObserver(self, ...) is called in install() but there is no deinit { NotificationCenter.default.removeObserver(self) }. Because AppDelegate owns this object for the full app lifetime this is not a practical leak, but if MainWindowVisibleFrameFitRescue were ever released early the NotificationCenter would hold a dangling reference to a deallocated object, which crashes on the next notification delivery. Adding a deinit now keeps the invariant explicit and prevents future surprises if the ownership changes.

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!

@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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
Packages/macOS/CmuxWindowing/Sources/CmuxWindowing/Geometry/MainWindowVisibleFrameFitCore.swift (1)

86-87: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Local constant shadows the private method name.

let targetDisplay = targetDisplay(...) shadows the targetDisplay(for:in:) method with a same-named local constant. It compiles correctly since the call is resolved before the binding completes, but it hurts readability at the call site.

♻️ Suggested rename
-        let targetDisplay = targetDisplay(for: standardizedFrame, in: usableDisplays)
+        let selectedDisplay = targetDisplay(for: standardizedFrame, in: usableDisplays)
             ?? usableDisplays[0]
         let fitted = clampFrame(
             standardizedFrame,
-            within: targetDisplay.visibleFrame,
+            within: selectedDisplay.visibleFrame,
             minimumWidth: minimumWidth,
             minimumHeight: minimumHeight
         )
🤖 Prompt for 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.

In
`@Packages/macOS/CmuxWindowing/Sources/CmuxWindowing/Geometry/MainWindowVisibleFrameFitCore.swift`
around lines 86 - 87, Rename the local binding in
MainWindowVisibleFrameFitCore’s target selection logic so it does not shadow the
private targetDisplay(for:in:) method. Update the let targetDisplay =
targetDisplay(...) binding to a clearer name like selectedDisplay or
resolvedDisplay, and adjust the subsequent uses in the same scope to match.
🤖 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.

Outside diff comments:
In
`@Packages/macOS/CmuxWindowing/Sources/CmuxWindowing/Geometry/MainWindowVisibleFrameFitCore.swift`:
- Around line 86-87: Rename the local binding in MainWindowVisibleFrameFitCore’s
target selection logic so it does not shadow the private targetDisplay(for:in:)
method. Update the let targetDisplay = targetDisplay(...) binding to a clearer
name like selectedDisplay or resolvedDisplay, and adjust the subsequent uses in
the same scope to match.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 0aa655f6-1caa-4849-8500-99e5ba840516

📥 Commits

Reviewing files that changed from the base of the PR and between 936d0e6 and cb16203.

📒 Files selected for processing (3)
  • Packages/macOS/CmuxWindowing/Sources/CmuxWindowing/Geometry/MainWindowVisibleFrameFitCore.swift
  • Sources/App/MainWindowVisibleFrameFitRescue.swift
  • cmuxTests/MainWindowVisibleFrameFitCoreTests.swift

…tor-window-cutoff

# Conflicts:
#	Sources/AppDelegate.swift
#	cmux.xcodeproj/project.pbxproj
Comment thread Sources/App/MainWindowVisibleFrameFitRescue.swift

@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
`@Packages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/WorkspaceDetailView.swift`:
- Around line 53-55: Make the SwiftUI view state private by narrowing the access
of the `@State` properties in WorkspaceDetailView. Update the terminalPickerRows
and isChatMode declarations so they are private to the view, keeping the state
implementation detail encapsulated and aligned with SwiftLint expectations.
🪄 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: f8d0625d-cd37-4457-b85e-187f5718b82a

📥 Commits

Reviewing files that changed from the base of the PR and between 4d0ce24 and ac9e58d.

📒 Files selected for processing (2)
  • Packages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/WorkspaceDetailView.swift
  • Packages/macOS/CmuxWindowing/Sources/CmuxWindowing/Geometry/MainWindowVisibleFrameFitCore.swift
💤 Files with no reviewable changes (1)
  • Packages/macOS/CmuxWindowing/Sources/CmuxWindowing/Geometry/MainWindowVisibleFrameFitCore.swift

@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.

Caution

Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.

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
`@Packages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/WorkspaceDetailView.swift`:
- Around line 53-55: Make the SwiftUI view state private by narrowing the access
of the `@State` properties in WorkspaceDetailView. Update the terminalPickerRows
and isChatMode declarations so they are private to the view, keeping the state
implementation detail encapsulated and aligned with SwiftLint expectations.
🪄 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: f8d0625d-cd37-4457-b85e-187f5718b82a

📥 Commits

Reviewing files that changed from the base of the PR and between 4d0ce24 and ac9e58d.

📒 Files selected for processing (2)
  • Packages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/WorkspaceDetailView.swift
  • Packages/macOS/CmuxWindowing/Sources/CmuxWindowing/Geometry/MainWindowVisibleFrameFitCore.swift
💤 Files with no reviewable changes (1)
  • Packages/macOS/CmuxWindowing/Sources/CmuxWindowing/Geometry/MainWindowVisibleFrameFitCore.swift
🛑 Comments failed to post (1)
Packages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/WorkspaceDetailView.swift (1)

53-55: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Make the SwiftUI state private.

terminalPickerRows and isChatMode are @State-backed view state; keeping them internal widens the surface unnecessarily. SwiftLint already flags this.

♻️ Suggested fix
-    `@State` var terminalPickerRows: [TerminalPickerMenuRow] = []
+    `@State` private var terminalPickerRows: [TerminalPickerMenuRow] = []
@@
-    `@State` var isChatMode = false
+    `@State` private var isChatMode = false
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

    `@State` private var terminalPickerRows: [TerminalPickerMenuRow] = []
    /// Chat-mode toggle for inline agent chat in place of the terminal.
    `@State` private var isChatMode = false
🧰 Tools
🪛 SwiftLint (0.65.0)

[Warning] 53-53: SwiftUI state properties should be private

(private_swiftui_state)


[Warning] 55-55: SwiftUI state properties should be private

(private_swiftui_state)

🤖 Prompt for 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.

In
`@Packages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/WorkspaceDetailView.swift`
around lines 53 - 55, Make the SwiftUI view state private by narrowing the
access of the `@State` properties in WorkspaceDetailView. Update the
terminalPickerRows and isChatMode declarations so they are private to the view,
keeping the state implementation detail encapsulated and aligned with SwiftLint
expectations.

Source: Linters/SAST tools

…tor-window-cutoff

# Conflicts:
#	.github/workflows/ci.yml
#	tests/test_ci_change_areas.py

@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 using default effort 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 23cd0ca. Configure here.

Comment thread Sources/AppDelegate.swift Outdated

This branch was successfully deployed

1 active deployment
Preview – cmux — c2ce925c Deployed Jul 8, 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.

Window cut off on multi-monitor setups: stale frame left partially offscreen / oversized after display changes

1 participant