From d9688781ee26165aae57ffbb16ff6538d0dbc1b8 Mon Sep 17 00:00:00 2001 From: Alan Wizemann Date: Fri, 24 Apr 2026 00:06:57 +0200 Subject: [PATCH] fix(app): windowResizability(.contentMinSize) so window stops auto-resizing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Root cause of the "window grows whenever I switch to Chat / the v2.3 Sessions tab" bug. Prior commits (4baa3d4 sessions-tab clamp, 9aad905 chat+projects detail-area clamp) were defensive but not sufficient — with the actual window policy treating content's ideal height as a BINDING (not a minimum), those clamps only kept things inside the view, not inside the window. scarfApp's WindowGroup had .defaultSize(width: 1100, height: 700) but no explicit .windowResizability(...) modifier. On macOS, a non-Settings WindowGroup defaults to .automatic, which evaluates to .contentSize — meaning every layout pass rebinds the window to the currently-displayed detail view's ideal height. Explains every symptom: - Switching to Chat / Sessions grows the window to content size - User drag-to-resize snaps back on next layout - Sections with ScrollView-bounded content (Dashboard, Insights) "work" because their ideal height is their visible slot - Resize while in a bounded section looks sticky because the rebind target doesn't push back - Coming back to Chat reasserts the bind and the window grows again — sometimes past the screen Switched to .windowResizability(.contentMinSize). Content's ideal height is now a minimum FLOOR — user resize works freely, the window persists across section switches, and it still can't shrink below a section's minimum render (so tool bars, input fields, etc. stay visible). Pre-existing pre-v2.3 bug; v2.3's new content-heavy surfaces (per-project Sessions list) just made it much more obvious. The earlier clamp commits stay in — they're still correct for intra-view layout, just not the window-level fix. 80/80 Swift tests still pass. No test change; behavior is platform-layout-policy level. Co-Authored-By: Claude Opus 4.7 (1M context) --- scarf/scarf/scarfApp.swift | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/scarf/scarf/scarfApp.swift b/scarf/scarf/scarfApp.swift index ea0836f..6a35920 100644 --- a/scarf/scarf/scarfApp.swift +++ b/scarf/scarf/scarfApp.swift @@ -86,6 +86,19 @@ struct ScarfApp: App { registry.defaultServerID } .defaultSize(width: 1100, height: 700) + // Without an explicit resizability, `WindowGroup` defaults to + // `.automatic` which on macOS evaluates to `.contentSize` — + // meaning the window is BOUND to its content's ideal size + // rather than bounded-below by it. Any section whose content's + // intrinsic height changes (Chat's message list, the v2.3 + // per-project Sessions tab, Insights charts) would resize the + // window on every section switch, snap back against user + // resize, and sometimes push the whole window past the + // screen. `.contentMinSize` turns the content's ideal height + // into a minimum floor: user resize works freely, the window + // stays put across section switches, and it still can't shrink + // smaller than a section's minimum render. + .windowResizability(.contentMinSize) .commands { CommandGroup(after: .appInfo) { Button("Check for Updates…") { updater.checkForUpdates() }