From c1c6822e8bb4708857225491b939f076b120dec1 Mon Sep 17 00:00:00 2001
From: Amr Bashir <amr.bashir2015@gmail.com>
Date: Mon, 25 Jul 2022 16:37:01 +0200
Subject: [PATCH] fix(windows): respect min/max sizes when creating window,
 closes #498 (#499)

---
 .../windows-initial-window-min-max-size.md    |  5 +++
 src/dpi.rs                                    | 23 ++++++++++++++
 src/platform_impl/windows/window.rs           | 31 ++++++++++++-------
 3 files changed, 48 insertions(+), 11 deletions(-)
 create mode 100644 .changes/windows-initial-window-min-max-size.md

diff --git a/.changes/windows-initial-window-min-max-size.md b/.changes/windows-initial-window-min-max-size.md
new file mode 100644
index 000000000..d41ff2984
--- /dev/null
+++ b/.changes/windows-initial-window-min-max-size.md
@@ -0,0 +1,5 @@
+---
+"tao": "patch"
+---
+
+On Windows, respect min/max inner sizes when creating the window.
\ No newline at end of file
diff --git a/src/dpi.rs b/src/dpi.rs
index 7d3b6b255..28ebae9f6 100644
--- a/src/dpi.rs
+++ b/src/dpi.rs
@@ -433,6 +433,29 @@ impl Size {
       Size::Logical(size) => size.to_physical(scale_factor),
     }
   }
+
+  pub fn clamp<S: Into<Size>>(input: S, min: S, max: S, scale_factor: f64) -> Size {
+    let (input, min, max) = (
+      input.into().to_physical::<f64>(scale_factor),
+      min.into().to_physical::<f64>(scale_factor),
+      max.into().to_physical::<f64>(scale_factor),
+    );
+
+    let clamp = |input: f64, min: f64, max: f64| {
+      if input < min {
+        min
+      } else if input > max {
+        max
+      } else {
+        input
+      }
+    };
+
+    let width = clamp(input.width, min.width, max.width);
+    let height = clamp(input.height, min.height, max.height);
+
+    PhysicalSize::new(width, height).into()
+  }
 }
 
 impl<P: Pixel> From<PhysicalSize<P>> for Size {
diff --git a/src/platform_impl/windows/window.rs b/src/platform_impl/windows/window.rs
index ac72b7f30..857df4f57 100644
--- a/src/platform_impl/windows/window.rs
+++ b/src/platform_impl/windows/window.rs
@@ -941,22 +941,31 @@ unsafe fn init<T: 'static>(
 
   win.set_skip_taskbar(pl_attribs.skip_taskbar);
 
-  let dimensions = attributes
-    .inner_size
-    .unwrap_or_else(|| PhysicalSize::new(800, 600).into());
-  win.set_inner_size(dimensions);
-  if attributes.maximized {
-    // Need to set MAXIMIZED after setting `inner_size` as
-    // `Window::set_inner_size` changes MAXIMIZED to false.
-    win.set_maximized(true);
-  }
-  win.set_visible(attributes.visible);
-
   if attributes.fullscreen.is_some() {
     win.set_fullscreen(attributes.fullscreen);
     force_window_active(win.window.0);
+  } else {
+    let size = attributes
+      .inner_size
+      .unwrap_or_else(|| PhysicalSize::new(800, 600).into());
+    let max_size = attributes
+      .max_inner_size
+      .unwrap_or_else(|| PhysicalSize::new(f64::MAX, f64::MAX).into());
+    let min_size = attributes
+      .min_inner_size
+      .unwrap_or_else(|| PhysicalSize::new(0, 0).into());
+    let clamped_size = Size::clamp(size, min_size, max_size, win.scale_factor());
+    win.set_inner_size(clamped_size);
+
+    if attributes.maximized {
+      // Need to set MAXIMIZED after setting `inner_size` as
+      // `Window::set_inner_size` changes MAXIMIZED to false.
+      win.set_maximized(true);
+    }
   }
 
+  win.set_visible(attributes.visible);
+
   if let Some(position) = attributes.position {
     win.set_outer_position(position);
   }