Skip to content

Fix window position restore on relaunch - #2129

Merged
austinywang merged 3 commits into
mainfrom
issue-2126-window-position-restore
Mar 25, 2026
Merged

austinywang merged 3 commits into
mainfrom
issue-2126-window-position-restore

Conversation

@austinywang

@austinywang austinywang commented Mar 25, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • preserve the exact saved main-window frame on relaunch when the window is still reachable on-screen, instead of unnecessarily clamping it after small visible-frame changes
  • keep the existing off-screen recovery path for truly inaccessible saved frames
  • add regression coverage for the accessible-frame restore case
  • Fixes Window does not restore to its previous position on relaunch #2126

Testing

  • built a tagged Debug app with ./scripts/reload.sh --tag issue-2126
  • did not run automated tests locally per repo policy
  • produced the tagged app bundle for manual verification

Demo Video

For UI or behavior changes, include a short demo video (GitHub upload, Loom, or other direct link).

  • Video URL or attachment: None

Review Trigger (Copy/Paste as PR comment)

@codex review
@coderabbitai review
@greptile-apps review
@cubic-dev-ai review

Checklist

  • I tested the change locally
  • I added or updated tests for behavior changes
  • I updated docs/changelog if needed
  • I requested bot reviews after my latest commit (copy/paste block above or equivalent)
  • All code review bot comments are resolved
  • All human review comments are resolved

Summary by cubic

Restores the main window to the exact saved position on relaunch when it’s still reachable, improving behavior after small display/visible-frame changes. Fixes #2126.

  • Bug Fixes
    • Preserves the saved frame when the title bar/top strip remains reachable; clamps only when it would reopen inaccessible.
    • Keeps the existing off-screen recovery path.
    • Adds a unit test covering the accessible-frame restore scenario.

Written for commit 8cf2e6f. Summary will update on new commits.

Summary by CodeRabbit

  • Bug Fixes

    • Improved window frame restoration on display changes. The app now preserves your exact window geometry when the window remains accessible on the target display, rather than forcibly resizing or repositioning it.
  • Tests

    • Added test coverage for window frame preservation during display transitions.

@vercel

vercel Bot commented Mar 25, 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 8:55am

@chatgpt-codex-connector

Copy link
Copy Markdown

To use Codex here, create a Codex account and connect to github.

@coderabbitai

coderabbitai Bot commented Mar 25, 2026 •

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9f4b2838-a352-4cb5-9331-eb84b49af456

📥 Commits

Reviewing files that changed from the base of the PR and between da70f3f and 8cf2e6f.

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

📝 Walkthrough

Walkthrough

The changes improve window-frame restoration by introducing logic to preserve exact saved geometry when the window remains accessible across display configuration changes. A new accessibility check validates that the top portion of the saved frame stays sufficiently visible before returning the original frame, otherwise falling back to clamping behavior.

Changes

Cohort / File(s) Summary
Window Frame Restoration Logic
Sources/AppDelegate.swift
Added shouldPreserveAccessibleFrame(...) helper function to validate if saved window frame remains sufficiently visible when display configuration differs. Integrated into resolvedWindowFrame(...) to conditionally preserve exact frame geometry rather than always clamping to the new display's visible area.
Test Coverage
cmuxTests/SessionPersistenceTests.swift
Added test testResolvedWindowFramePreservesExactGeometryWhenDisplayChangesButWindowRemainsAccessible to validate that window geometry is preserved exactly when the saved display has reduced visible height but the window remains accessible.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Poem

🐰 A window that wanders no more,
Remembers its place on the floor,
Through display shifts and screen dance,
It holds its ground, given a chance!
Frame restoration—our quest is now won! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
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 (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Fix window position restore on relaunch' directly and specifically describes the main change—preserving window position on relaunch to address #2126.
Description check ✅ Passed The PR description covers all key sections: a clear summary of changes, testing approach with build verification, and a mostly-filled checklist. Required sections are present and adequately detailed.
Linked Issues check ✅ Passed The PR implementation fully addresses #2126 by preserving exact window frame when accessible, validating visibility, and restoring saved position on relaunch with regression test coverage.
Out of Scope Changes check ✅ Passed All changes are directly scoped to #2126: AppDelegate fix preserves accessible frames, test validates the restore logic, and no unrelated modifications are present.

✏️ 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 issue-2126-window-position-restore

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

@greptile-apps

greptile-apps Bot commented Mar 25, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes issue #2126 by stopping the unnecessary clamping of saved window frames when display geometry changes only slightly (e.g., dock or menu bar height adjusts by a few pixels). It inserts a new shouldPreserveAccessibleFrame helper between the existing visibleFrame.intersects guard and the clampFrame call: if a sufficient portion of the window's title bar (top 64 pt strip) is still reachable inside the current display's visible frame, the saved frame is returned exactly. Frames whose title bar has slipped off-screen still fall through to the existing clampFrame / remappedFrame recovery paths unchanged.

Key highlights:

  • shouldPreserveAccessibleFrame validates that at least 120 × 24 pt of the top strip is visible — sensible defaults for a draggable title bar region.
  • The regression test follows the CLAUDE.md two-commit structure (30b2c8af adds the failing test, f2bc1392 adds the fix), so CI history proves the test was red before the fix.
  • The guard inside shouldPreserveAccessibleFrame uses targetDisplay.frame (physical bounds) rather than targetDisplay.visibleFrame; since the call-site already guarantees visibleFrame.intersects(frame), this guard is always satisfied — a minor redundancy but not a bug.
  • Off-screen recovery behavior (remap / center) is unchanged.

Confidence Score: 5/5

  • Safe to merge — the fix is well-scoped, regression-tested, and leaves the existing off-screen recovery path intact.
  • The logic is correct: the title-bar-strip check accurately distinguishes accessible frames from inaccessible ones. The two-commit test structure provides CI-verified regression coverage. The only open item is a style-level redundancy in the guard condition that does not affect correctness.
  • No files require special attention.

Important Files Changed

Filename Overview
Sources/AppDelegate.swift Adds shouldPreserveAccessibleFrame helper and wires it into resolvedWindowFrame. Logic is correct: checks the top strip of the window against the display's visible frame with sensible thresholds. One minor style note: the guard uses targetDisplay.frame instead of targetDisplay.visibleFrame, making it always-true at the current call-site.
cmuxTests/SessionPersistenceTests.swift New test correctly exercises the accessible-frame preserve path: adjustedDisplay has visibleFrame shifted by 40 pts (simulating dock height change), the saved frame's title bar remains well within that visible frame, and the test asserts the exact frame is returned unchanged. The two-commit regression structure required by CLAUDE.md is properly followed.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[resolvedWindowFrame public entry] --> B{targetDisplay found?}
    B -- Yes --> C{shouldPreserveExactFrame - same displayID and geometry unchanged}
    C -- Yes --> D[Return frame as-is]
    C -- No --> E[resolvedWindowFrame private inner]
    E --> F{visibleFrame intersects frame?}
    F -- Yes --> G{shouldPreserveAccessibleFrame - 120x24pt of top strip visible}
    G -- Yes --> H[Return frame as-is - NEW]
    G -- No --> I[clampFrame within visibleFrame]
    F -- No --> J{displaySnapshot available?}
    J -- Yes --> K[remappedFrame from saved to current display]
    J -- No --> L[centeredFrame in targetDisplay]
    B -- No --> M{Any display intersects frame?}
    M -- Yes --> N[clampFrame within that display]
    M -- No --> O[remap or center in fallbackDisplay]
Loading

Reviews (1): Last reviewed commit: "Merge branch 'main' of https://github.co..." | Re-trigger Greptile

Comment thread Sources/AppDelegate.swift
standardizedFrame.height.isFinite,
standardizedFrame.width > 0,
standardizedFrame.height > 0,
standardizedFrame.intersects(targetDisplay.frame) else {

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 Guard checks targetDisplay.frame instead of targetDisplay.visibleFrame

The outer resolvedWindowFrame call-site already guarantees targetDisplay.visibleFrame.intersects(frame) before reaching shouldPreserveAccessibleFrame. Because visibleFrame ⊆ frame in macOS, this guard is always true when called from the only existing call-site — so it never early-returns.

The actual risk-check that matters is whether the top strip sits inside the visibleFrame (line 3127), which is correctly implemented. The guard here provides no extra protection.

This isn't a runtime bug today, but if someone later calls shouldPreserveAccessibleFrame without the prior visible-frame intersection check, the guard will still pass for a frame that only touches the menu-bar/dock shadow areas (between frame and visibleFrame), and the subsequent topStrip.intersection(targetDisplay.visibleFrame) will correctly catch that case anyway.

Consider changing the guard to targetDisplay.visibleFrame to make the intent self-documenting:

Suggested change
standardizedFrame.intersects(targetDisplay.frame) else {
standardizedFrame.intersects(targetDisplay.visibleFrame) else {

@austinywang
austinywang merged commit 0ea16b1 into main Mar 25, 2026
15 checks passed
@austinywang
austinywang deleted the issue-2126-window-position-restore branch March 25, 2026 09:05
Jesssullivan added a commit to Jesssullivan/cmux that referenced this pull request Mar 26, 2026
Ingests all upstream fixes since 2026-03-22 including:
- Fix Cmd+N crash: retain snapshot workspaces (manaflow-ai#2183, manaflow-ai#2181, manaflow-ai#2178, manaflow-ai#2173)
- Fix browser pane restore after reopen (manaflow-ai#2141)
- Fix Ghostty resize_split keybind (manaflow-ai#1899)
- Reduce shell integration prompt latency (manaflow-ai#2109)
- Fix command palette focus after terminal find (manaflow-ai#2089)
- Add Codex CLI hooks (manaflow-ai#2103)
- Add cmux.json custom commands (manaflow-ai#2011)
- Fix window position restore on relaunch (manaflow-ai#2129)

Conflict resolution:
- BrowserPanel.swift: accepted upstream configureWebViewConfiguration()
  refactor (already includes our forMainFrameOnly:true CAPTCHA fix from PR manaflow-ai#1877)

Fork-specific files preserved:
- Sources/Panels/WebAuthn{Coordinator,BridgeJavaScript}.swift
- Sources/FIDO2/module.modulemap
- vendor/ctap2 submodule
- cmux.entitlements (with camera/audio-input removed)
- cmux.embedded.entitlements
- .github/workflows/fork-{ci,release}.yml
bn-l pushed a commit to bn-l/cmux that referenced this pull request Apr 3, 2026
* test: cover accessible window frame restore

* fix: preserve accessible window frame on relaunch

This branch was successfully deployed

1 active deployment
Preview — 8cf2e6f3 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

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Window does not restore to its previous position on relaunch

1 participant