From 3dcffe6f4ec89a7efd6312a729707fde101b5aaf Mon Sep 17 00:00:00 2001 From: l0ng-ai <24760907+l0ng-ai@users.noreply.github.com> Date: Sun, 9 Aug 2026 19:20:15 +0700 Subject: [PATCH] fix(windows): grow a remembered bound back up to the minimum size MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit window_min_size governs what a drag may do to a window, not the bounds it opens with, so a remembered bound walked straight under the declared 720pt minimum — the reported settings window measured 641. Clamp the restored size on the way in, keeping the origin. --- src/ui/windows.rs | 50 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/src/ui/windows.rs b/src/ui/windows.rs index 8603c795..9d7800e7 100644 --- a/src/ui/windows.rs +++ b/src/ui/windows.rs @@ -549,7 +549,7 @@ fn window_options(cx: &mut App, workspace: Option) -> WindowOptions let existing = WindowRegistry::count(cx); let bounds = match remembered { Some(state) => { - let bounds = state.bounds(); + let bounds = at_least_min_size(state.bounds()); if cx.displays().iter().any(|d| d.bounds().intersects(&bounds)) { bounds } else { @@ -582,6 +582,23 @@ fn window_options(cx: &mut App, workspace: Option) -> WindowOptions } } +/// Grow a remembered bound back up to `MIN_SIZE`. +/// +/// `window_min_size` only governs what a *drag* may do to a window; the bounds +/// we open with are taken as given. A window that got under the minimum — an +/// older build that had no minimum, a hand-edited `views.json`, a display that +/// went away — was reopened at whatever it had been saved at, and the settings +/// page it opened onto had never been laid out for that width. +fn at_least_min_size(bounds: Bounds) -> Bounds { + Bounds { + origin: bounds.origin, + size: size( + bounds.size.width.max(px(MIN_SIZE.0)), + bounds.size.height.max(px(MIN_SIZE.1)), + ), + } +} + fn cascade(bounds: Bounds, existing: usize) -> Bounds { if existing == 0 { return bounds; @@ -626,6 +643,37 @@ mod tests { assert_eq!(cascade(b, 3).size, b.size); } + #[test] + fn a_remembered_bound_under_the_minimum_is_grown_back_to_it() { + // The window in the report this was fixed for: 641x830, saved and + // reopened at a width no settings page is laid out for. + let undersized = Bounds { + origin: point(px(700.), px(60.)), + size: size(px(641.), px(830.)), + }; + let grown = at_least_min_size(undersized); + assert_eq!(grown.size.width, px(MIN_SIZE.0)); + assert_eq!(grown.size.height, px(830.), "a tall enough height is kept"); + assert_eq!(grown.origin, undersized.origin, "the corner does not move"); + + let short = at_least_min_size(Bounds { + origin: point(px(0.), px(0.)), + size: size(px(1200.), px(300.)), + }); + assert_eq!(short.size, size(px(1200.), px(MIN_SIZE.1))); + } + + #[test] + fn a_remembered_bound_at_or_over_the_minimum_is_left_alone() { + let b = bounds_at(100., 100.); + assert_eq!(at_least_min_size(b).size, b.size); + let exact = Bounds { + origin: point(px(0.), px(0.)), + size: size(px(MIN_SIZE.0), px(MIN_SIZE.1)), + }; + assert_eq!(at_least_min_size(exact).size, exact.size); + } + #[test] fn cascade_wraps_so_windows_never_march_off_screen() { let b = bounds_at(100., 100.);