Skip to content

Fix #2791: preserve window position across sleep/wake with multiple monitors - #3882

Merged
austinywang merged 10 commits into
mainfrom
issue-2791-window-sleep-wake-position
May 12, 2026
Merged

austinywang merged 10 commits into
mainfrom
issue-2791-window-sleep-wake-position

Conversation

@austinywang

@austinywang austinywang commented May 12, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #2791

Summary

  • Enroll cmux main windows in AppKit frame autosave so macOS owns screen-topology frame restoration.
  • Stop using the cmux lastWindowGeometry fallback as a competing main-window frame source.
  • Add a regression test that real main windows register non-colliding AppKit autosave names.

Verification

  • git diff --check
  • Local tests/build not run per repo policy and user instruction; CI is the verification gate.

Note

Medium Risk
Changes main-window placement and persistence by switching from cmux-owned geometry to AppKit frame autosave, which could affect window restore/positioning across multi-window scenarios. Includes new autosave-name promotion/cleanup logic that needs validation across edge cases (multiple windows, close ordering, sleep/wake).

Overview
Main window geometry persistence is switched to AppKit frame autosave: new windows now register a stable primary autosave name (cmux.mainWindow.primary) and UUID-scoped names for additional windows, and AppKit-saved frames are applied when not restoring from a session snapshot or source window.

The PR removes the lastWindowGeometry fallback path (including snapshot persistence/debug plumbing) and expands legacy cleanup to delete both v1 and v2 geometry keys, making AppKit the single frame source.

On window close, ephemeral autosave entries are removed and, if the primary window closes, a surviving window is promoted into the stable autosave slot without changing its on-screen frame. Tests are expanded to cover autosave name registration, legacy-key cleanup/ignoring, ephemeral cleanup, and primary-slot promotion.

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


Summary by cubic

Fixes #2791: Preserves main‑window position across sleep/wake and monitor changes by using AppKit frame autosave with a stable primary slot and frame‑neutral promotion on close. Removes cmux‑owned geometry so AppKit is the single source of truth.

  • Bug Fixes
    • Main windows register AppKit frame autosave on creation (cmux.mainWindow.primary for the first live window; UUID‑scoped for others); AppKit‑saved frames apply when not restoring from a snapshot or source window.
    • On close, unregisters the window; if it held the primary name, clears it, promotes a survivor into cmux.mainWindow.primary, seeds the primary slot with the survivor’s frame, restores that frame if AppKit reloads, then retires the survivor’s old UUID key only after promotion succeeds.
    • Secondary windows clear their autosave name before removing the saved frame so UUID‑scoped keys don’t persist.
    • Removed all lastWindowGeometry read/write paths (including snapshot plumbing) and expanded legacy cleanup to delete both v1 and v2 keys.
    • Tests cover autosave registration, ignoring legacy geometry, legacy‑key cleanup, secondary cleanup, primary promotion with safe handoff, and proving the primary autosave payload matches the survivor frame.

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

Summary by CodeRabbit

  • Refactor

    • Modernized window sizing/restoration and AppKit autosave-name handling for main windows
    • Simplified session snapshot persistence and removed legacy geometry payloads
    • Updated window teardown to clear ephemeral autosave names and promote primary autosave as needed
  • Tests

    • Added coverage for legacy-geometry cleanup, autosave-name registration/promotion, and teardown behavior

Review Change Stack

The sleep/wake regression needs a behavior-level guard that real cmux main windows enroll in AppKit frame autosave and do not share a live autosave name. Current main-window construction leaves frameAutosaveName empty, so this test is expected to fail before the implementation commit.

Constraint: Regression-test commit must contain no production fix so CI can prove the issue first goes red.

Confidence: high

Scope-risk: narrow

Tested: Not run locally per repository testing policy.

Not-tested: Local xcodebuild and app launch intentionally skipped for the failing-test-only commit.
Main windows now register AppKit frame autosave names as soon as they are created. The first standalone main window uses a stable primary name when available, while additional live windows use UUID-scoped names so AppKit accepts every autosave registration.

The old cmux lastWindowGeometry fallback was a competing frame owner: it could remap or persist frames independently of AppKit's screen topology logic. Session snapshots still store window layout with workspace content, but the standalone fallback no longer reads or writes frame data for new-window placement.

Constraint: Do not add sleep/wake timers or screen-change repair hooks; use the platform frame autosave mechanism Apple exposes for this window state.

Rejected: Add didWake/screensDidChange repositioning | would introduce another lifecycle repair path and preserve split ownership.

Confidence: medium

Scope-risk: moderate

Tested: git diff --check

Not-tested: Local tests and local build intentionally skipped per repo policy and user instruction; CI will run after PR push.
@vercel

vercel Bot commented May 12, 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 12, 2026 2:49am
cmux-staging Building Building Preview, Comment May 12, 2026 2:49am

@coderabbitai

coderabbitai Bot commented May 12, 2026 •

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

AppDelegate switches from writing custom persisted window-geometry payloads to using AppKit frame-autosave names: windows register per-window autosave names, autosaved frames are applied conditionally during creation, session snapshot persistence no longer includes geometry data, and teardown clears ephemeral autosave names. Tests added for autosave and legacy-key cleanup.

Changes

AppKit Frame Autosave Migration

Layer / File(s) Summary
Remove legacy persisted-geometry helpers
Sources/AppDelegate.swift
Deleted helpers and startup fallback logic that encoded/used legacy persisted window geometry.
Per-window autosave naming and cleanup helpers
Sources/AppDelegate.swift
Added constants and helpers to compute non-primary per-window autosave names, promote a surviving window to the primary autosave name, remove ephemeral autosave names when windows unregister, and DEBUG helpers for legacy key listing/cleanup.
Window creation sizing and autosave registration
Sources/AppDelegate.swift
createMainWindow now prefers source-window content rect or defaultContentRect when no restored frame exists; registers computed frameAutosaveName; applies AppKit-saved frame via setFrameUsingName only when no restored frame and no source window; cascade-point updates and DEBUG label adjusted.
Session snapshot persistence without geometry payloads
Sources/AppDelegate.swift, Sources/App/SessionSnapshotDebugBenchmark.swift
stop generating/attaching encoded persisted-window-geometry data; persistSessionSnapshot and debug benchmark path updated to persist only the session snapshot; SessionSnapshotDebugBenchmark.run signature simplified accordingly.
Unregister main window autosave cleanup
Sources/AppDelegate.swift
unregisterMainWindow no longer writes persisted geometry for fallback placement; it clears ephemeral autosave names, handles primary-name promotion/clearing, and preserves cascade-point reset behavior.
Test coverage for autosave behavior and legacy geometry cleanup
cmuxTests/AppDelegateBareSpaceShortcutRoutingTests.swift
Replaced legacy-geometry test with testCreateMainWindowIgnoresLegacyPersistedGeometryWhenNoSourceWindow, adjusted legacy payload shape, and added tests verifying legacy UserDefaults key cleanup, distinct per-window autosave names, ephemeral autosave clearing and UserDefaults removal, and primary promotion; added helper to compute AppKit autosave UserDefaults key.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • manaflow-ai/cmux#2129: Modifies AppDelegate main-window restored-frame/autosave handling similar to this PR.
  • manaflow-ai/cmux#2306: Touches persisted window-geometry schema and legacy-key migration/cleanup related to this change.
  • manaflow-ai/cmux#3419: Modifies unregisterMainWindow and session-persistence logic overlapping with this PR.

Poem

🐰 I hopped through frames both old and new,

autosave names stitched windows true.
Legacy keys I gently sweep,
so windows wake where rabbits sleep.
🥕✨


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 Swift @Concurrent ❌ Error finishSessionAutosaveTick: async on @MainActor class without @concurrent, calls file I/O-heavy loadIncludingProcessDetectedSnapshots(). Violates rule on file I/O async helpers from UI isolation. Add @concurrent annotation to finishSessionAutosaveTick or move file I/O work to explicit actor hop.
Docstring Coverage ⚠️ Warning Docstring coverage is 3.85% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (13 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The PR comprehensively addresses issue #2791 by implementing AppKit frame autosave with primary/UUID-scoped autosave names, removing cmux geometry fallbacks, and adding regression tests for autosave registration and promotion behavior.
Out of Scope Changes check ✅ Passed All changes are directly scoped to the stated objective of fixing window position restoration across sleep/wake by switching to AppKit autosave and removing cmux geometry handling; no extraneous modifications detected.
Cmux Swift Actor Isolation ✅ Passed AppDelegate (@MainActor) new autosave helpers properly isolated. SessionSnapshotDebugBenchmark (@MainActor). No implicit MainActor models, unsync'd Sendable, or background UI access issues.
Cmux Swift Blocking Runtime ✅ Passed No blocking/timing primitives. AppKit frame autosave integration only using synchronous APIs.
Cmux No Hacky Sleeps ✅ Passed Check not applicable. The rule covers only TypeScript, JavaScript, shell, and non-Swift runtime scripts. This PR modifies only Swift files (.swift), which are explicitly excluded per the rule scope.
Cmux Swift Concurrency ✅ Passed No new legacy async patterns. Simplifies method signatures by removing geometry data parameters. Existing dispatch/Task patterns unchanged.
Cmux Swift File And Package Boundaries ✅ Passed AppDelegate.swift net change: -12 lines (within 250-line threshold). Changes focus on window autosave—existing responsibility. Test file allowed. No boundary violations detected.
Cmux Swift Logging ✅ Passed PR complies with swift-logging.md rules: no print/debugPrint/dump/NSLog in production code; only change is DEBUG-guarded cmuxDebugLog message update; no file-scoped Logger issues; no secrets exposed.
Cmux Swiftui State Layout ✅ Passed No SwiftUI state violations detected. All modifications are AppKit window management, debug utilities, and tests. Zero @State/@Published/@Observable/SwiftUI state declarations introduced.
Cmux Architecture Rethink ✅ Passed Required AppKit frame autosave bridge fixing #2791. Synchronous AppKit calls, no timing/locks, no duplicate state, clear ownership. AppKit is single source of truth.
Cmux Swift Auxiliary Window Close Shortcuts ✅ Passed PR modifies only existing main workspace windows and test fixtures. Main workspace windows are explicitly exempted from auxiliary window close-shortcut rules.
Title check ✅ Passed The title directly addresses the main objective of the pull request—fixing window position preservation across sleep/wake with multiple monitors by adopting AppKit frame autosave.
Description check ✅ Passed The PR description includes all major template sections (Summary, Testing/Verification, Checklist) with appropriate details about the changes, risk assessment, and testing approach.
✨ 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-2791-window-sleep-wake-position

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.

@greptile-apps

greptile-apps Bot commented May 12, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

Switches main-window frame persistence from a cmux-owned lastWindowGeometry UserDefaults key to AppKit frame autosave (cmux.mainWindow.primary for the first live window, UUID-scoped names for others), so macOS handles sleep/wake and monitor-topology restores natively. The v2 legacy key is enrolled in the cleanup list, and window teardown now promotes a survivor into the primary autosave slot with a safe pre-seeding handoff.

  • AppDelegate.swift: Removes all persistedWindowGeometry read/write paths, adds mainWindowFrameAutosaveName, removeEphemeralMainWindowFrameAutosaveNameIfNeeded, and promotePrimaryMainWindowFrameAutosaveNameIfNeeded; close handler releases the primary name only after context unregistration, then triggers promotion.
  • SessionSnapshotDebugBenchmark.swift: Drops the now-removed persistedGeometryData parameter from the benchmark helper signature.
  • AppDelegateBareSpaceShortcutRoutingTests.swift: Renames the legacy-geometry test to assert the opposite (frame is not applied), and adds four new tests covering registration, secondary cleanup, legacy-key removal, and primary-slot promotion with frame-neutral handoff verification.

Confidence Score: 5/5

Safe to merge — the close-path ordering is correct, UUID autosave keys are cleaned up, and the survivor promotion handoff guards against AppKit frame reloads.

The critical sequencing decisions — releasing the primary name after context unregistration, pre-seeding the primary slot before setFrameAutosaveName, and correcting any AppKit-reloaded frame after promotion — are all handled correctly. Previous review findings about silent promotion failure and UUID key accumulation have been properly addressed. The only noteworthy gap is that removeLegacyPersistedWindowGeometry no longer runs at startup, so the v2 UserDefaults key lingers until the first session write after upgrade; since nothing reads the v2 key anymore this has no behavioral consequence.

No files require special attention. The AppDelegate close-path logic is the most complex part of the change, but the ordering has been validated by the promotion tests and the prior review iterations.

Important Files Changed

Filename Overview
Sources/AppDelegate.swift Core change: removes legacy geometry persistence, adds AppKit autosave enrollment, close-path name release, and survivor promotion. Logic is carefully ordered (primary name cleared after context unregistration, survivor pre-seeded before setFrameAutosaveName). One minor gap: removeLegacyPersistedWindowGeometry no longer runs at startup, so the v2 key lingers in UserDefaults until the first session save for upgrading users.
Sources/App/SessionSnapshotDebugBenchmark.swift Straightforward signature simplification: drops the persistedGeometryData parameter that no longer exists.
cmuxTests/AppDelegateBareSpaceShortcutRoutingTests.swift Test suite significantly expanded; defer blocks are correct, UserDefaults state is properly saved/restored, and the new promotion test verifies the survivor's frame under both the probe window and the live window after close.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[windowWillClose] --> B{window holds primary name?}
    B -- yes --> C[shouldReleasePrimary = true]
    B -- no --> D[removeEphemeralAutosaveName: clear UUID name + removeFrame]
    C --> E[removeEphemeralAutosaveName: no-op guarded by != primary]
    D --> F[unregisterMainWindowContext]
    E --> F
    F -- nil --> G[return early - name not cleared, no promotion]
    F -- context --> H{shouldReleasePrimary?}
    H -- yes --> I[setFrameAutosaveName empty - release primary slot]
    H -- no --> J[promotePrimary excluding window]
    I --> J
    J --> K{live primary owner excluding window?}
    K -- yes --> L[return - primary still live]
    K -- no --> M{survivor in registered contexts?}
    M -- no --> N[return - last window closing]
    M -- yes --> O[saveFrame to primary - seed slot before registering]
    O --> P{setFrameAutosaveName primary succeeds?}
    P -- no --> Q[return - UUID key not removed]
    P -- yes --> R{frame changed by AppKit?}
    R -- yes --> S[setFrame back to survivorFrame]
    R -- no --> T[saveFrame - confirm survivor frame]
    S --> T
    T --> U[removeFrame for survivor UUID key]
Loading

Reviews (6): Last reviewed commit: "Prove promoted autosave frame payload" | Re-trigger Greptile

Comment thread Sources/AppDelegate.swift Outdated
Comment thread cmuxTests/AppDelegateBareSpaceShortcutRoutingTests.swift
Secondary main windows need AppKit frame autosave during their lifetime, but their UUID-scoped autosave keys are not stable restore points. Closing those windows now removes the matching AppKit frame key while preserving the primary slot.

This also makes autosave registration explicit instead of hiding the side effect inside a boolean chain, and adds a regression that saves a secondary frame then verifies close removes it.

Constraint: Primary frame autosave must survive close because it is the stable main-window restore slot.

Rejected: Keep UUID autosave keys indefinitely | leaks per-window keys that are never read again.

Confidence: high

Scope-risk: narrow

Tested: git diff --check

Not-tested: Local tests/build intentionally skipped per repo policy and user instruction; CI will verify.
The production close path now removes UUID-scoped frame autosave names, and this test also removes the secondary name in teardown so the registration contract cannot dirty UserDefaults even if a future close path changes.

Constraint: Preserve the primary autosave slot across tests while cleaning per-window UUID slots.

Confidence: high

Scope-risk: narrow

Tested: git diff --check

Not-tested: Local tests/build intentionally skipped per repo policy and user instruction; CI will verify.
Comment thread Sources/AppDelegate.swift
Comment thread Sources/AppDelegate.swift
Cursor Bugbot flagged two cleanup gaps after the AppKit autosave migration: ephemeral windows could keep their autosave registration active during close, and the retired v2 cmux geometry key was not part of legacy cleanup. The fix keeps AppKit as the single frame owner by clearing UUID-scoped autosave names before removing their saved frame and deleting the retired v2 key alongside the v1 key.

Constraint: Local test execution is intentionally skipped per task instructions; CI owns verification for this PR.

Rejected: Keep only NSWindow.removeFrame for UUID windows | AppKit can still write through an active frameAutosaveName before teardown completes.

Confidence: high

Scope-risk: narrow

Tested: git diff --check

Not-tested: Local XCTest or app build, per explicit instruction to use CI and defer reload until CI is green.
coderabbitai[bot]
coderabbitai Bot previously requested changes May 12, 2026

@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: 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/AppDelegateBareSpaceShortcutRoutingTests.swift`:
- Around line 381-383: The helper appKitFrameAutosaveDefaultsKey(_ name:
NSWindow.FrameAutosaveName) reconstructs AppKit's internal UserDefaults key
format ("NSWindow Frame {name}") which is an undocumented implementation detail;
add a brief documentation comment above this function stating that the string
format intentionally mirrors AppKit's internal convention (and may be brittle
across OS versions) so future maintainers understand why the hard-coded format
is used.

In `@Sources/AppDelegate.swift`:
- Around line 6776-6793: The primary autosave slot can remain pointing at a
non-live window, so update
mainWindowFrameAutosaveName(windowId:wantsPrimarySlot:) to first check whether
any live NSApp.windows currently own Self.primaryMainWindowFrameAutosaveName
and, if none and wantsPrimarySlot is true, return
Self.primaryMainWindowFrameAutosaveName so the new window can be promoted;
additionally enhance removeEphemeralMainWindowFrameAutosaveNameIfNeeded(_:) to,
after clearing an ephemeral autosave name, check for a missing live primary
owner and if none assign the primary slot to the first suitable live main window
(via setFrameAutosaveName(Self.primaryMainWindowFrameAutosaveName)) so the
primary slot is always held by a live window.
🪄 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: a9be3322-0fa7-4b25-9488-89bd66eb3cce

📥 Commits

Reviewing files that changed from the base of the PR and between 0ce2a24 and 88a8947.

📒 Files selected for processing (2)
  • Sources/AppDelegate.swift
  • cmuxTests/AppDelegateBareSpaceShortcutRoutingTests.swift

Comment thread cmuxTests/AppDelegateBareSpaceShortcutRoutingTests.swift
Comment thread Sources/AppDelegate.swift Outdated
Comment thread Sources/AppDelegate.swift
Review feedback exposed a remaining lifecycle gap in the AppKit autosave handoff: the stable primary autosave name could outlive its window while another cmux window stayed open. The close path now promotes a surviving main window into the primary slot, saves its frame immediately, and retires its old UUID-scoped frame. The retired cmux geometry write plumbing is also removed so the legacy key is only ever cleaned up, not rewritten.

Constraint: AppKit frame autosave is the single source of truth for window frame persistence after this migration.

Rejected: Preserve the old persistedGeometryData parameter | it made a removed key look writable and kept a path back to competing frame persistence.

Confidence: high

Scope-risk: narrow

Tested: git diff --check

Not-tested: Local XCTest or app build, per explicit instruction to use CI and defer reload until CI is green.
Comment thread Sources/AppDelegate.swift
Greptile found that primary-slot promotion could run while the closing primary NSWindow still held the autosave name during windowWillClose. The close path now clears that registration before promotion, and promotion only removes the survivor's old UUID frame after AppKit accepts the primary name.

Constraint: The primary autosave UserDefaults frame must remain preserved while live ownership moves to a surviving cmux window.

Rejected: Keep ignoring setFrameAutosaveName's return value | it could remove the survivor's UUID frame after a failed promotion.

Confidence: high

Scope-risk: narrow

Tested: git diff --check

Not-tested: Local XCTest or app build, per explicit instruction to use CI and defer reload until CI is green.
The primary autosave name should be released only after the closing window is confirmed as a registered main window. This keeps the promotion fix precise: unregister the closing context, clear the primary autosave registration from that closing NSWindow, then promote a survivor into the stable primary slot.

Constraint: WindowWillClose still contains the closing NSWindow in NSApp.windows, so promotion must explicitly release the old autosave owner first.

Rejected: Clear the primary autosave name before unregistering | it mutates a window even if context unregister unexpectedly fails.

Confidence: high

Scope-risk: narrow

Tested: git diff --check

Not-tested: Local XCTest or app build, per explicit instruction to use CI and defer reload until CI is green.
Comment thread Sources/AppDelegate.swift
AppKit reloads an autosaved frame when a window adopts that name, so the primary-slot promotion now seeds the stable name with the survivor frame before registration and restores the survivor frame if AppKit applies anything during the transition.

Constraint: setFrameAutosaveName can reload the associated frame as part of registration

Rejected: Assign primary autosave name first and save afterward | that can capture the closed primary window frame after moving the survivor

Confidence: high

Scope-risk: narrow

Directive: Keep primary autosave promotion frame-neutral; do not register the survivor under a stale primary name before seeding the saved frame

Tested: git diff --check

Not-tested: Local XCTest/builds intentionally not run per project instruction; CI will run on PR

@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 3f7f03c. Configure here.

Comment thread Sources/AppDelegate.swift Outdated
coderabbitai[bot]
coderabbitai Bot previously requested changes May 12, 2026

@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 `@cmuxTests/AppDelegateBareSpaceShortcutRoutingTests.swift`:
- Around line 405-412: The test currently only checks that
primaryFrameAutosaveKey exists in UserDefaults and that secondWindow preserved
its onscreen frame, but it must verify the actual payload was promoted; read the
stored value for primaryFrameAutosaveKey from defaults, decode/convert it into a
CGRect/NSRect (matching how frames are archived in the app), and assert that the
decoded frame equals survivorFrameBeforePromotion (use same accuracy as existing
assertions). Use the same UserDefaults instance (`defaults`) and the same
reference values (`survivorFrameBeforePromotion`, `primaryFrameAutosaveKey`,
`secondWindow`) so the test fails if the stored primary autosave was not
updated.
🪄 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: f436e5bc-e54a-4e08-9db0-4cb920d56eb5

📥 Commits

Reviewing files that changed from the base of the PR and between 88a8947 and 3f7f03c.

📒 Files selected for processing (3)
  • Sources/App/SessionSnapshotDebugBenchmark.swift
  • Sources/AppDelegate.swift
  • cmuxTests/AppDelegateBareSpaceShortcutRoutingTests.swift

Comment thread cmuxTests/AppDelegateBareSpaceShortcutRoutingTests.swift
The promotion test now loads the stable primary autosave entry into a probe window so it proves the stored payload matches the survivor frame, not just that the key exists. The autosave-name helper also owns the live-primary check directly instead of accepting a redundant caller-computed flag.

Constraint: Review gate required proving AppKit's stored primary autosave frame, not only the live survivor frame

Rejected: Keep the key-presence assertion alone | it would still pass with a stale primary autosave payload

Confidence: high

Scope-risk: narrow

Directive: Primary autosave promotion tests must verify both live-frame preservation and the restorable autosave payload

Tested: git diff --check

Not-tested: Local XCTest/builds intentionally not run per project instruction; CI will run on PR
@austinywang
austinywang dismissed coderabbitai[bot]’s stale review May 12, 2026 03:06

Superseded by fbc7d24; the actionable inline thread was resolved with a probe-window autosave payload assertion, and the latest CodeRabbit check is passing.

@austinywang
austinywang merged commit d641868 into main May 12, 2026
30 checks passed

This branch was successfully deployed

1 active deployment
Preview – cmux — fbc7d247 Deployed May 12, 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 moves to wrong position after sleep/wake with multiple external monitors

1 participant