Preserve Assistant minimum width when opening sidebar

This commit is contained in:
Kaede Akino committed 2026-09-18 08:44:34 +08:00
1 parent 6104c07b6f
commit 0e89afd1e1
3 files changed
+25 -25

No files matched your search

+5 -1
View File
@@ -57,6 +57,10 @@ struct RootView: View {
minHeight: Metrics.Window.detailMinHeight,
maxHeight: .infinity
)
.navigationSplitViewColumnWidth(
min: Metrics.Window.detailMin,
ideal: Metrics.Window.detailMin
)
}
.navigationSplitViewStyle(.balanced)
.environment(\.singleLinePasteAction, { SingleLineFieldEditing.paste() })
@@ -73,7 +77,7 @@ struct RootView: View {
}
.overlay { ExternalAuthWindowPresenter() }
.frame(
minWidth: Metrics.Window.minWidth,
minWidth: Metrics.Window.minWidth(showsSidebar: window.showsSidebar),
maxWidth: .infinity,
minHeight: Metrics.Window.minHeight,
maxHeight: .infinity
+2 -2
View File
@@ -151,8 +151,8 @@ struct TermindApp: App {
.restorationBehavior(ScreenshotDemoConfiguration.active == nil ? .automatic : .disabled)
#endif
.defaultSize(width: Metrics.Window.defaultWidth, height: Metrics.Window.defaultHeight)
// RootView publishes the calculated two-column floor. Active optional
// panes may raise it, but the window can never shrink below the base UI.
// The Assistant reading column sets the floor. Opening the sidebar
// lets the native split view grow a window that cannot fit both columns.
.windowResizability(.contentMinSize)
.commands { TermindCommands(app: app) }
+18 -22
View File
@@ -283,35 +283,31 @@ nonisolated enum Metrics {
}
enum Window {
/// The detail column's own floors. The window-level values below add
/// the chrome that sits beside or above it; keeping the two concepts
/// separate prevents layout floors from being counted twice.
static let detailMin: CGFloat = 320
/// Keep the complete Assistant surface, including its composer, at
/// least as wide as the transcript's reading column.
static let detailMin: CGFloat = Metrics.Chat.contentMaxWidth
static let detailMinHeight: CGFloat = 440
/// Space to the right of the navigation sidebar in Vault's complete
/// working layout: two dividers, the main surface, and an Edit/New
/// detail panel.
static let trailingContentMinWidth: CGFloat =
1
+ Metrics.VaultContent.min
+ 1
+ Metrics.VaultDetail.min
/// The native sidebar has an outer inset on Liquid Glass; older
/// systems separate it from the detail column with a one-point divider.
private static var sidebarSpacing: CGFloat {
if #available(macOS 26.0, *) { Metrics.Space.m } else { 1 }
}
/// Vault's complete working layout sets the application floor: the
/// navigation sidebar, main surface, and an Edit/New detail panel, plus
/// the two dividers between them. Reserving the third column even while
/// it is closed prevents opening an editor inside an already-too-narrow
/// window and keeps every host form usable from the moment it appears.
static let minWidth: CGFloat = Metrics.Sidebar.min + trailingContentMinWidth
/// Publish the full minimum to the window as well as the detail column.
/// A detail-only frame constraint can otherwise overflow a narrow window
/// when the native sidebar reopens.
static func minWidth(showsSidebar: Bool) -> CGFloat {
detailMin + (showsSidebar ? Metrics.Sidebar.min + sidebarSpacing : 0)
}
/// The sidebar may use only width left after the complete Vault work
/// area has been reserved. It grows with the window, but never outside
/// its own usability bounds.
/// Preserve a complete reading column beside the sidebar. If its
/// minimum width no longer fits, the native split view grows the window
/// when the sidebar opens instead of compressing the Assistant.
static func sidebarMaxWidth(for availableWidth: CGFloat) -> CGFloat {
min(
Metrics.Sidebar.max,
max(Metrics.Sidebar.min, availableWidth - trailingContentMinWidth)
max(Metrics.Sidebar.min, availableWidth - detailMin - sidebarSpacing)
)
}