From 9aad9051c4eb01d0b398997e6fb33dd9e7257711 Mon Sep 17 00:00:00 2001 From: Alan Wizemann Date: Fri, 24 Apr 2026 00:00:19 +0200 Subject: [PATCH] fix(chat,projects): clamp detail-column views so they don't grow the window MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two sibling fixes to the one landed in 4baa3d4 (Sessions tab height clamp). User reported that both the Chat section and the per-project Sessions tab expanded the window height past the screen once their content grew intrinsically. Root cause is the same for both: the outer VStack at the top of each view had no `.frame(maxHeight: .infinity)`. When NavigationSplitView's detail slot renders one of these, SwiftUI asks the child for its ideal height. Without a clamp, a tall enough child (RichChatView's message list; a long attributed- sessions list; a dashboard with a text widget containing a long README block) bubbles its intrinsic size all the way up and macOS grows the window to fit. ChatView: add `.frame(maxWidth: .infinity, maxHeight: .infinity)` to the outer VStack in `body`. Pre-existing issue that predated v2.3 — it just happened to be masked by the chat area having enough give until now. Surfaced as the user exercised the section more during v2.3 testing. ProjectsView: add the same modifier to the "dashboard is loaded" VStack branch in `dashboardArea`. The ContentUnavailableView branches (no dashboard / no projects / no selection) don't need it — ContentUnavailableView self-clamps. Both the widgetsTab (ScrollView) and the siteTab (explicit maxHeight) were already fine. The sessions tab picked up its fix in 4baa3d4. These two commits together cover every surface that lives in the detail column. 80/80 Swift tests still pass. Visual-only fix; no test change. Co-Authored-By: Claude Opus 4.7 (1M context) --- scarf/scarf/Features/Chat/Views/ChatView.swift | 7 +++++++ scarf/scarf/Features/Projects/Views/ProjectsView.swift | 10 ++++++++++ 2 files changed, 17 insertions(+) diff --git a/scarf/scarf/Features/Chat/Views/ChatView.swift b/scarf/scarf/Features/Chat/Views/ChatView.swift index 470ec1b..d1e42c4 100644 --- a/scarf/scarf/Features/Chat/Views/ChatView.swift +++ b/scarf/scarf/Features/Chat/Views/ChatView.swift @@ -15,6 +15,13 @@ struct ChatView: View { errorBanner chatArea } + // Clamp the outer VStack to the detail column's offered + // space. Without this, the chat area's intrinsic height (a + // RichChatView whose message list grows with content) can + // bubble up through NavigationSplitView's detail slot and + // push the whole window past the screen. Same pattern as + // the Sessions tab fix in the v2.3 branch. + .frame(maxWidth: .infinity, maxHeight: .infinity) .navigationTitle("Chat") .task { await viewModel.loadRecentSessions() diff --git a/scarf/scarf/Features/Projects/Views/ProjectsView.swift b/scarf/scarf/Features/Projects/Views/ProjectsView.swift index 37325e6..77424a3 100644 --- a/scarf/scarf/Features/Projects/Views/ProjectsView.swift +++ b/scarf/scarf/Features/Projects/Views/ProjectsView.swift @@ -367,6 +367,16 @@ struct ProjectsView: View { } } } + // Clamp the container VStack to the detail column's + // offered space. Without it, any tab whose content is + // taller than the window (long Sessions list, tall + // README block in a dashboard's text widget, etc.) can + // bubble its intrinsic height up through + // NavigationSplitView's detail slot and push the whole + // window past the screen. widgetsTab's own ScrollView + // and siteTab's explicit maxHeight both cooperate; the + // sessions tab needs this as well. + .frame(maxWidth: .infinity, maxHeight: .infinity) } else if let error = viewModel.dashboardError { ContentUnavailableView { Label("No Dashboard", systemImage: "square.grid.2x2")