Skip to content

Fix window size - #220

Merged
graeme merged 3 commits into
mainfrom
fix-window-size
Sep 17, 2026
Merged

graeme merged 3 commits into
mainfrom
fix-window-size

Conversation

@graeme

@graeme graeme commented Sep 17, 2026 •

Copy link
Copy Markdown
Collaborator

What and why

The main window stopped reopening at the size it was last quit at; every launch came up at the default size.

SwiftUI autosaves a WindowGroup's frame under a UserDefaults key built from the root view's type name, modifier chain included. The crash report sheet added a file-private modifier to that chain, and Swift prints a file-private type's context as "(unknown context at $addr)". That address is the load address, which ASLR changes every launch, so each run saved its frame under a new key and never found the previous one. My defaults domain held 423 orphaned frame keys.

Making CrashReportSheetModifier internal gives it a stable name. The default window height also sat below the minimum since the floor moved to 680, so a first launch was clamped; it is now 720.

The -uiTesting seams inside BrewApp have moved to an extension under Homebrew/UITesting so the composition root reads as one thing. That commit is a pure move.

The new UI test resizes the window, quits with Cmd-Q, relaunches and expects the same size back. The runner is sandboxed and cannot clear the app's defaults, so a BREW_UITEST_RESET_WINDOW_STATE launch key asks the app to forget the NSWindow Frame and NSSplitView Subview Frames keys before it opens a window. Running the test resets the developer's own saved frame once.

Validation

macOS 26.5, Apple silicon, Xcode 26.5 (17F42), Swift 6.3.2.

  • scripts/test: 1094 package tests and 19 BrewUILint tests pass.

  • SwiftFormat, SwiftLint and BrewUILint ran through the pre-commit hook on all three commits.

  • scripts/test-ui, partial: WindowFrameUITests, LaunchSmokeUITests and the self-upgrade relaunch test pass. WindowFrameUITests fails with "Width was not restored" when the modifier is flipped back to private. The full UI suite was not run.

  • Manual: two launches of the built app wrote a single NSWindow Frame key with no "(unknown context)" segment, and a seeded 1240x900 frame survived a launch and quit.

  • Keyboard, VoiceOver and appearance were not checked, as nothing visible changed.

  • I followed the conventions and workflow, checked for duplicate PRs and kept this change focused.

  • I added regression coverage for bug fixes or explained why automated coverage is impractical, and reported the relevant validation above.

Screenshots

Not applicable. The only visible effect is the window reopening at its previous size; nothing in the window changes.

AI assistance

  • AI was used to generate or assist with generating this PR.

Claude Code (Claude Opus 5) found the root cause by inspecting the app's defaults domain, proposed the fix, wrote the UI test and its harness seam, and drafted this description. Claude ran the checks above; I reviewed the diff and will verify the UI test on my machine before merge.

馃 Generated with Claude Code

Fixes #174

graeme and others added 2 commits September 17, 2026 17:07
SwiftUI autosaves a WindowGroup's frame under a key built from the root
view's type name, modifier chain included. CrashReportSheetModifier was
file-private, and a private type's context prints as "(unknown context
at $addr)" where the address is the load address, which ASLR changes
every launch. So each run saved its frame under a fresh key and none
found the previous one. Making the type internal gives it a stable name.

The default height also sat below the minimum since 8c083f5 raised the
floor to 680, so a first launch was clamped rather than opening at the
size asked for. 720 keeps the two in agreement.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Every -uiTesting fallthrough lived between init and body, so the
composition root read as half test plumbing. They now sit in an
extension under Homebrew/UITesting alongside the launch configuration
they consume. Bodies are unchanged; the members drop private because a
cross-file extension cannot reach it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@graeme
graeme requested a review from MikeMcQuaid September 17, 2026 07:34
Resize, quit with Cmd-Q, relaunch, and expect the same size back. It
fails against the private modifier and passes with the fix.

The runner is sandboxed, so it cannot clear the app's defaults to get a
predictable starting window. A new BREW_UITEST_RESET_WINDOW_STATE
launch environment key asks the app to do it: both the NSWindow Frame
and NSSplitView Subview Frames keys go, because a new window with no
saved frame is sized to fit the split view's restored columns.

The drag lives in an XCUIElement extension. A click exactly on the edge
starts no resize; a few points inside the corner does. The window is
shrunk rather than grown: a default-size window can always shrink
towards the minimum, whereas growing needs screen room the 1024x768
CI display does not have.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@graeme
graeme merged commit fbc6a43 into main Sep 17, 2026
8 checks passed
@graeme
graeme deleted the fix-window-size branch September 17, 2026 10:17
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.

Bug: The app can't save size and placement

2 participants