Add limit to minimum window size (#13126)

Aaron Ruan created

Release Notes:

- Add a limit to the minimum window size on macOS.

Here's the minimum window before change:
<img width="121" alt="image"
src="https://github.com/zed-industries/zed/assets/38318044/9e907194-42e5-457e-91ea-96613426b479">

After change:
<img width="410" alt="image"
src="https://github.com/zed-industries/zed/assets/38318044/6e9c3057-9860-4f4b-9a73-c158ebac5ba9">

Change summary

crates/collab_ui/src/collab_ui.rs          | 1 +
crates/gpui/examples/window_positioning.rs | 1 +
crates/gpui/src/geometry.rs                | 9 +++++++++
crates/gpui/src/platform.rs                | 7 +++++++
crates/gpui/src/platform/mac/window.rs     | 6 ++++++
crates/gpui/src/window.rs                  | 2 ++
crates/zed/src/zed.rs                      | 4 ++++
7 files changed, 30 insertions(+)

Detailed changes

crates/collab_ui/src/collab_ui.rs 🔗

@@ -124,5 +124,6 @@ fn notification_window_options(
         display_id: Some(screen.id()),
         window_background: WindowBackgroundAppearance::default(),
         app_id: Some(app_id.to_owned()),
+        window_min_size: Size::default(),
     }
 }

crates/gpui/src/geometry.rs 🔗

@@ -2287,6 +2287,15 @@ impl Pixels {
     pub fn abs(&self) -> Self {
         Self(self.0.abs())
     }
+
+    /// Returns the f64 value of `Pixels`.
+    ///
+    /// # Returns
+    ///
+    /// A f64 value of the `Pixels`.
+    pub fn to_f64(self) -> f64 {
+        self.0 as f64
+    }
 }
 
 impl Mul<Pixels> for Pixels {

crates/gpui/src/platform.rs 🔗

@@ -567,6 +567,9 @@ pub struct WindowOptions {
 
     /// Application identifier of the window. Can by used by desktop environments to group applications together.
     pub app_id: Option<String>,
+
+    /// Window minimum size
+    pub window_min_size: Size<Pixels>,
 }
 
 /// The variables that can be configured when creating a new window
@@ -594,6 +597,9 @@ pub(crate) struct WindowParams {
     pub display_id: Option<DisplayId>,
 
     pub window_background: WindowBackgroundAppearance,
+
+    #[cfg_attr(target_os = "linux", allow(dead_code))]
+    pub window_min_size: Size<Pixels>,
 }
 
 /// Represents the status of how a window should be opened.
@@ -642,6 +648,7 @@ impl Default for WindowOptions {
             display_id: None,
             window_background: WindowBackgroundAppearance::default(),
             app_id: None,
+            window_min_size: Size::default(),
         }
     }
 }

crates/gpui/src/platform/mac/window.rs 🔗

@@ -505,6 +505,7 @@ impl MacWindow {
             focus,
             show,
             display_id,
+            window_min_size,
         }: WindowParams,
         executor: ForegroundExecutor,
         renderer_context: renderer::Context,
@@ -646,6 +647,11 @@ impl MacWindow {
 
             native_window.setMovable_(is_movable as BOOL);
 
+            native_window.setContentMinSize_(NSSize {
+                width: window_min_size.width.to_f64(),
+                height: window_min_size.height.to_f64(),
+            });
+
             if titlebar.map_or(true, |titlebar| titlebar.appears_transparent) {
                 native_window.setTitlebarAppearsTransparent_(YES);
                 native_window.setTitleVisibility_(NSWindowTitleVisibility::NSWindowTitleHidden);

crates/gpui/src/window.rs 🔗

@@ -631,6 +631,7 @@ impl Window {
             display_id,
             window_background,
             app_id,
+            window_min_size,
         } = options;
 
         let bounds = window_bounds
@@ -647,6 +648,7 @@ impl Window {
                 show,
                 display_id,
                 window_background,
+                window_min_size,
             },
         )?;
         let display_id = platform_window.display().map(|display| display.id());

crates/zed/src/zed.rs 🔗

@@ -105,6 +105,10 @@ pub fn build_window_options(display_uuid: Option<Uuid>, cx: &mut AppContext) ->
         display_id: display.map(|display| display.id()),
         window_background: cx.theme().window_background_appearance(),
         app_id: Some(app_id.to_owned()),
+        window_min_size: gpui::Size {
+            width: px(360.0),
+            height: px(240.0),
+        },
     }
 }