ReviewOS

also looking at this

craft-native/craft

feat(window): --frame-autosave, so windows come back where they were

#56
Merged glennmichael123 wants to merge feat/window-frame-autosave into main
8 files +181 -0
11 days ago

Closes #52.

There was no setFrameAutosaveName: anywhere in the tree — the only setAutosaveName: calls were for the tray status item and split-view dividers. So every craft window forgot its size and position on every launch, and an app that wanted the standard behaviour had to wire onResize/onMove to its own storage and restore on next start, reimplementing badly what AppKit does in one call.

--frame-autosave <NAME>, frameAutosave in craft.json, window.frameAutosave on AppConfig. Wired into all six window-creation sites (windowed, tray, and both native-sidebar variants).

The semantics the issue asked for fall out of the call order

--width/--height/--x/--y act as first-launch defaults rather than as an override. That works because of two facts I measured rather than assumed:

  • setFrameUsingName: returns NO and leaves the window alone when nothing has been saved yet.
  • setFrameAutosaveName: does not write the current frame when it is set.

So: centre/position → restore → enable. Restore after centring means a frame the user chose wins over being centred, which is the point.

Verified through the real code path

Not the flag parser — createWindowWithStyle itself, webview and all:

first launch:  400x332 at 120,140    (the explicit geometry survives)
               defaults -> <absent>  (nothing is saved until it actually moves)
after moving:  defaults -> 700 400 640 480 0 0 1512 949
second launch: 640x480 at 700,400    (the remembered frame wins over the flags)
no flag:       400x332 at 120,140    (unchanged)

Off by default, deliberately: silently starting to persist frames would move existing apps' windows on upgrade.

What isn't covered by a test

The AppKit half. Restoring a frame needs a real NSWindow, and a windowing test on a CI runner is a flakiness source I'd rather not add — the four lines above are the evidence, reproduced against the shipped path. What is tested is the flag reaching the binary intact and the geometry flags surviving alongside it, on both the Zig and TypeScript sides; control-checked, deleting either wiring fails the new tests.

zig build test clean, bun test 472 pass, tsc --noEmit clean, pickier clean.

8 changed files on the files tab, with 0 review threads.

Sign in to comment on this pull request.