Skip to content

fix(ui): persist named desktop window frames - #10246

Closed
proggeramlug wants to merge 2 commits into
mainfrom
codex/issue-10170-window-frame
Closed

proggeramlug wants to merge 2 commits into
mainfrom
codex/issue-10170-window-frame

Conversation

@proggeramlug

@proggeramlug proggeramlug commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

Closes #10170.

Adds App({ frameAutosaveName: "main", ... }) to restore desktop window geometry across launches. Saved settings override width, height, and windowState; omitted/empty names preserve existing behavior. Keys are scoped to the executable path and window name.

  • macOS uses AppKit frame autosave and no longer centers a restored frame. Fullscreen Space restoration is not promised.
  • Win32 and WinUI share native placement persistence, preserve the normal frame while fullscreen, and reopen minimized windows in their last non-minimized state. A small Reactor hook restores placement before activation.
  • GTK4 restores normal size and maximized/fullscreen state. Position remains compositor-controlled because GTK4 has no global positioning API.
  • Includes mobile no-op exports, TypeScript declarations, documentation/example, and a changelog fragment. No version bump.

Validation:

  • Compiler App-option regression suite: 5 passed. The two persistence witnesses fail with the base implementation and pass with this change.
  • Production storage/Win32 modules compiled in an isolated Rust harness: 5 passed, including a real hidden-window close/reopen test, fullscreen normal-frame preservation, minimized-state handling, key isolation, and invalid-file fallback.
  • cargo check -p perry-ui-windows and cargo check -p perry-ui-macos --target aarch64-apple-darwin passed.
  • Documentation fence lint, test registration, workspace architecture, node-version consistency, GC store inventory, address classification, local binding audit, changed-file formatting/line limits, and git diff --check passed.

Validation limits on this Windows host:

  • The broader codegen unit suite has the same 4 failures with the base implementation (1526 passed, 4 failed, 1 ignored in both runs).
  • Full WinUI checking is blocked by the existing missing widgets::reorder_child referenced by ffi/widget_layout_extras.rs; neither file changes here. Standalone UI unit linking also has existing unresolved runtime FFI symbols, hence the isolated persistence harness.
  • GTK4 and macOS interactive launch/relaunch testing requires those native environments. The complete quick-check wrapper could not run cleanly under Git Bash (Windows command-length/Python alias issues); the relevant checks listed above were run directly.

Initial CI also reports a pre-existing TLS policy failure in crates/perry-runtime/src/regex/perex_owner.rs (raw thread_local! declaration). That file is unchanged by this PR.

Summary by CodeRabbit

  • New Features

    • Added opt-in desktop window frame persistence through frameAutosaveName.
    • Window size, position, and applicable maximized or fullscreen state can be restored across launches on macOS, Windows, and Linux.
    • Saved settings take precedence over launch dimensions and window state; empty or omitted names disable persistence.
    • Added TypeScript declarations and a working example.
  • Documentation

    • Documented configuration, platform support, fallback behavior, and persistence scope.

@coderabbitai

coderabbitai Bot commented Sep 14, 2026

Copy link
Copy Markdown

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: c27dd646-5b99-49a1-b924-a10da4f0d43b

📥 Commits

Reviewing files that changed from the base of the PR and between 9fda98d and 54b7ac8.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (28)
  • changelog.d/10246-window-frame-persistence.md
  • crates/perry-codegen/src/lower_call/native/native_ui_appshell_branch.rs
  • crates/perry-codegen/tests/app_window_config_options.rs
  • crates/perry-ui-android/src/ffi/tabbar_layout.rs
  • crates/perry-ui-gtk4/src/app.rs
  • crates/perry-ui-gtk4/src/ffi/app_window.rs
  • crates/perry-ui-gtk4/src/frame_persistence.rs
  • crates/perry-ui-gtk4/src/lib.rs
  • crates/perry-ui-ios/src/ffi/dialogs_lifecycle.rs
  • crates/perry-ui-macos/src/app.rs
  • crates/perry-ui-macos/src/lib_ffi/core_widgets.rs
  • crates/perry-ui-tvos/src/ffi/app_keychain.rs
  • crates/perry-ui-visionos/src/ffi_system.rs
  • crates/perry-ui-watchos/src/lib.rs
  • crates/perry-ui-windows-winui/src/app.rs
  • crates/perry-ui-windows/src/app.rs
  • crates/perry-ui-windows/src/ffi/app_window.rs
  • crates/perry-ui-windows/src/frame_persistence.rs
  • crates/perry-ui-windows/src/lib.rs
  • crates/perry-ui/Cargo.toml
  • crates/perry-ui/src/frame.rs
  • crates/perry-ui/src/lib.rs
  • docs/examples/ui/overview/frame-persistence.ts
  • docs/src/ui/overview.md
  • third_party/windows-winui/VENDORED.md
  • third_party/windows-winui/windows-reactor/src/app.rs
  • third_party/windows-winui/windows-reactor/src/winui/host.rs
  • types/perry/ui/index.d.ts

Included review availability: Your plan provides up to 8 included reviews per hour; 4 remain after this review.


📝 Walkthrough

Walkthrough

Changes

The PR adds the opt-in frameAutosaveName option to App(). Desktop backends persist and restore window frames through shared storage or native APIs. Compiler lowering, FFI exports, platform stubs, tests, declarations, documentation, and a desktop example support the option.

Window frame persistence

Layer / File(s) Summary
Shared frame storage
crates/perry-ui/src/frame.rs, crates/perry-ui/Cargo.toml, crates/perry-ui/src/lib.rs
Adds validated frame data, executable-scoped keys, bounded loading, atomic saving, and storage tests.
App option and compiler lowering
crates/perry-codegen/..., types/perry/ui/index.d.ts, docs/src/ui/overview.md, docs/examples/ui/overview/frame-persistence.ts, changelog.d/..., crates/perry-ui-*/...
Adds frameAutosaveName, roots and forwards its string value, exposes platform FFI symbols, adds non-desktop no-op stubs, and updates tests and documentation.
Desktop backend restoration
crates/perry-ui-macos/..., crates/perry-ui-gtk4/..., crates/perry-ui-windows/..., crates/perry-ui-windows-winui/...
macOS, GTK4, Windows, and WinUI restore saved frames before presentation and save platform-specific frame state during window lifecycle events.
WinUI pre-activation integration
third_party/windows-winui/windows-reactor/..., third_party/windows-winui/VENDORED.md
Adds a window-created callback and native handle access before activation so WinUI placement can be restored while the window remains hidden.

Priority: ➖ Normal

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

Change: Feature · Severity of issue fixed: Medium

Sequence Diagram(s)

sequenceDiagram
  participant AppConfig
  participant AppLowering
  participant DesktopBackend
  participant FrameStore
  AppConfig->>AppLowering: read frameAutosaveName
  AppLowering->>DesktopBackend: call perry_ui_app_set_frame_autosave_name
  DesktopBackend->>FrameStore: load saved frame during startup
  FrameStore-->>DesktopBackend: return saved frame or no frame
  DesktopBackend->>DesktopBackend: restore frame before presentation
  DesktopBackend->>FrameStore: save frame during close or shutdown
Loading

Merge Risk: ⚪ Minimal · up to 54b7a

The frame-persistence feature has no remaining identified merge-blocking issue.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 67.65% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 68 functions across 24 files. (4 skipped:… 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 clearly and concisely describes the primary change: persistence of named desktop window frames.
Description check ✅ Passed The description covers the feature summary, platform-specific changes, related issue, validation steps, test limitations, documentation updates, and no version bump. It does not use every template hea…
Linked Issues check ✅ Passed The PR implements the coding requirements in #10170. frameAutosaveName provides opt-in persistence with empty or omitted names preserving existing behavior. macOS uses AppKit autosave. Windows and W…
Out of Scope Changes check ✅ Passed The changes remain within #10170. The shared frame-storage module, platform FFI exports, WinUI native hooks, backend no-op stubs, tests, declarations, documentation, example, and changelog support the…
Full details: Docstring Coverage

Explanation

Docstring coverage is 67.65% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 68 functions across 24 files. (4 skipped: 4 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 2
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/issue-10170-window-frame

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.

@proggeramlug

Copy link
Copy Markdown
Contributor Author

Landed via merge train #10256 (v0.5.1565): #10256. The train includes the audited PR changes and its integration fixes; merged main matches the validated train tree.

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.

No window frame persistence: desktop windows can't remember position/size across launches (macOS/Windows/GTK4)

1 participant