From 289246162095cabc52ef6fdd620e8baa8c2e4e1f Mon Sep 17 00:00:00 2001 From: Adrien Prokopowicz <6529475+prokopyl@users.noreply.github.com> Date: Sun, 16 Aug 2026 08:29:22 +0200 Subject: [PATCH 1/5] X11 impl --- examples/render_wgpu/src/main.rs | 2 +- src/platform/x11/window_thread.rs | 6 +++- src/platform/x11/xcb_connection/size_hints.rs | 10 ++++++ src/settings.rs | 33 +++++++++++++++++++ src/utils.rs | 19 ++++++++--- src/window.rs | 8 +++++ 6 files changed, 72 insertions(+), 6 deletions(-) create mode 100644 src/platform/x11/xcb_connection/size_hints.rs diff --git a/examples/render_wgpu/src/main.rs b/examples/render_wgpu/src/main.rs index c423c3c1..e351a86d 100644 --- a/examples/render_wgpu/src/main.rs +++ b/examples/render_wgpu/src/main.rs @@ -217,7 +217,7 @@ fn main() -> Result<(), baseview::Error> { let window_open_options = WindowSettings::new() .with_title("WGPU on Baseview") .with_size(LogicalSize::new(512, 512)) - .with_max_size(LogicalSize::new(512, 512)); + .with_aspect_ratio(Some((1, 1))); Window::create(window_open_options, |c| pollster::block_on(WgpuExample::new(c)))? .run_until_closed()?; diff --git a/src/platform/x11/window_thread.rs b/src/platform/x11/window_thread.rs index a5e6e545..764122f7 100644 --- a/src/platform/x11/window_thread.rs +++ b/src/platform/x11/window_thread.rs @@ -7,8 +7,8 @@ use crate::platform::x11::present::PresentThreadShared; use crate::platform::x11::sizing::SizingThreadShared; use crate::platform::x11::window_shared::WindowShared; use crate::utils::SizingStrategy; -use crate::warn; use crate::window::WindowInitializer; +use crate::{warn, AspectRatio}; use crate::{WindowContext, WindowSettings, WindowSize}; use calloop::LoopSignal; use std::cell::{Cell, RefCell}; @@ -226,6 +226,10 @@ impl WindowThreadHandle { self.sizing_strategy().max_size() } + pub fn aspect_ratio(&self) -> Option { + self.shared.sizing_strategy().aspect_ratio() + } + pub fn handle_main_thread_callback(&self) { loop { let Some(receiver) = self.callback_receiver.as_ref() else { return }; diff --git a/src/platform/x11/xcb_connection/size_hints.rs b/src/platform/x11/xcb_connection/size_hints.rs new file mode 100644 index 00000000..43fc86bd --- /dev/null +++ b/src/platform/x11/xcb_connection/size_hints.rs @@ -0,0 +1,10 @@ + +fn to_x11_aspect_ratio(aspect_ratio: crate::AspectRatio) -> AspectRatio { + match (aspect_ratio.numerator.try_into(), aspect_ratio.denominator.try_into()) { + (Ok(numerator), Ok(denominator)) => AspectRatio { numerator, denominator }, + _ => AspectRatio { + numerator: (aspect_ratio.numerator / 2) as i32, + denominator: (aspect_ratio.denominator / 2) as i32, + }, + } +} diff --git a/src/settings.rs b/src/settings.rs index 491f5ae3..09adb230 100644 --- a/src/settings.rs +++ b/src/settings.rs @@ -33,6 +33,8 @@ pub struct WindowSettings { pub min_size: Option, pub max_size: Option, + pub aspect_ratio: Option, + /// A fallback scale factor, if Baseview couldn't get one from the platform. /// /// If the platform does already provide an accurate scaling factor, this doesn't do anything. @@ -126,6 +128,12 @@ impl WindowSettings { self } + #[inline] + pub fn with_aspect_ratio>(mut self, aspect_ratio: Option) -> Self { + self.aspect_ratio = aspect_ratio.map(A::into); + self + } + /// Sets [`gl_config`](Self::gl_config) to the given value. #[cfg(feature = "opengl")] #[inline] @@ -146,6 +154,7 @@ impl Default for WindowSettings { resizable: true, min_size: None, max_size: None, + aspect_ratio: None, #[cfg(feature = "opengl")] gl_config: None, } @@ -193,3 +202,27 @@ impl From for ParentWindowHandle { Self { inner } } } + +/// An aspect ratio `numerator` / `denominator`. +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub struct AspectRatio { + /// The numerator of the aspect ratio. + pub numerator: u32, + /// The denominator of the aspect ratio. + pub denominator: u32, +} + +impl AspectRatio { + /// Create a new aspect ratio with the given `numerator` and `denominator`. + #[inline] + pub fn new(numerator: u32, denominator: u32) -> Self { + Self { numerator, denominator } + } +} + +impl From<(u32, u32)> for AspectRatio { + #[inline] + fn from((numerator, denominator): (u32, u32)) -> Self { + Self::new(numerator, denominator) + } +} diff --git a/src/utils.rs b/src/utils.rs index 934ad460..ddf1da50 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,11 +1,11 @@ use crate::dpi::Size; -use crate::{WindowSettings, WindowSize}; +use crate::{AspectRatio, WindowSettings, WindowSize}; use dpi::{LogicalSize, PhysicalSize}; #[derive(Copy, Clone)] pub(crate) enum SizingStrategy { Fixed, - Resizable { min_size: Option, max_size: Option }, + Resizable { min_size: Option, max_size: Option, aspect_ratio: Option }, } impl SizingStrategy { @@ -20,7 +20,11 @@ impl SizingStrategy { } } - Self::Resizable { min_size: settings.min_size, max_size: settings.max_size } + Self::Resizable { + min_size: settings.min_size, + max_size: settings.max_size, + aspect_ratio: settings.aspect_ratio, + } } pub fn is_resizable(&self) -> bool { @@ -83,10 +87,17 @@ impl SizingStrategy { Size::Logical(size) => self.adjust_size_logical(size, window_size.scale_factor), } } + + pub fn aspect_ratio(&self) -> Option { + match self { + Self::Fixed => None, + Self::Resizable { aspect_ratio, .. } => *aspect_ratio, + } + } } impl Default for SizingStrategy { fn default() -> Self { - Self::Resizable { min_size: None, max_size: None } + Self::Resizable { min_size: None, max_size: None, aspect_ratio: None } } } diff --git a/src/window.rs b/src/window.rs index 2708e7c2..84105013 100644 --- a/src/window.rs +++ b/src/window.rs @@ -176,6 +176,14 @@ impl Window { self.inner.max_size() } + /// Returns the fixed aspect ratio of the window, if it has one. + /// + /// This is set by the [`WindowSettings::aspect_ratio`] field. + #[inline] + pub fn aspect_ratio(&self) -> Option { + self.inner.aspect_ratio() + } + /// Performs the work the window thread had scheduled for the main thread. /// /// This must be called back on the main thread, as a response to [`HostMainThreadCaller::call_main_thread`](host::HostMainThreadCaller::call_main_thread). From 2e0cfa71dacba343232a8d80a3dc9b60bbf8de75 Mon Sep 17 00:00:00 2001 From: Adrien Prokopowicz <6529475+prokopyl@users.noreply.github.com> Date: Sun, 16 Aug 2026 08:34:53 +0200 Subject: [PATCH 2/5] macOS impl --- src/platform/macos/view.rs | 7 +++++++ src/platform/macos/window.rs | 4 ++++ 2 files changed, 11 insertions(+) diff --git a/src/platform/macos/view.rs b/src/platform/macos/view.rs index 07cd39c6..d537719a 100644 --- a/src/platform/macos/view.rs +++ b/src/platform/macos/view.rs @@ -325,6 +325,13 @@ impl BaseviewView { let max_size = max_size.to_logical(scale_factor); window.setContentMaxSize(NSSize::new(max_size.width, max_size.height)); } + + if let Some(aspect_ratio) = this.state.sizing_strategy.aspect_ratio() { + window.setContentAspectRatio(NSSize::new( + aspect_ratio.numerator as _, + aspect_ratio.denominator as _, + )) + } } } diff --git a/src/platform/macos/window.rs b/src/platform/macos/window.rs index 4a82a6ca..dad2e03b 100644 --- a/src/platform/macos/window.rs +++ b/src/platform/macos/window.rs @@ -115,6 +115,10 @@ impl WindowHandle { self.state.sizing_strategy.max_size() } + pub fn aspect_ratio(&self) -> Option { + self.state.sizing_strategy.aspect_ratio() + } + #[inline] pub fn handle_main_thread_callback(&self) { // No-op From dd09546681d7aa04f572547c34bb6c8ce3b666a2 Mon Sep 17 00:00:00 2001 From: Adrien Prokopowicz <6529475+prokopyl@users.noreply.github.com> Date: Sun, 16 Aug 2026 16:30:48 +0200 Subject: [PATCH 3/5] min/max size now forced to respect apsect ratio --- src/settings.rs | 5 ++ src/utils.rs | 119 ++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 120 insertions(+), 4 deletions(-) diff --git a/src/settings.rs b/src/settings.rs index 09adb230..1bfc8d7e 100644 --- a/src/settings.rs +++ b/src/settings.rs @@ -218,6 +218,11 @@ impl AspectRatio { pub fn new(numerator: u32, denominator: u32) -> Self { Self { numerator, denominator } } + + #[inline] + pub fn ratio(&self) -> f64 { + (self.numerator as f64) / (self.denominator as f64) + } } impl From<(u32, u32)> for AspectRatio { diff --git a/src/utils.rs b/src/utils.rs index ddf1da50..03c5c155 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -20,11 +20,15 @@ impl SizingStrategy { } } - Self::Resizable { - min_size: settings.min_size, - max_size: settings.max_size, - aspect_ratio: settings.aspect_ratio, + let mut min_size = settings.min_size; + let mut max_size = settings.max_size; + + if let Some(ratio) = settings.aspect_ratio { + min_size = min_size.map(|s| adjust_min_size(s, ratio)); + max_size = max_size.map(|s| adjust_max_size(s, ratio)); } + + Self::Resizable { min_size, max_size, aspect_ratio: settings.aspect_ratio } } pub fn is_resizable(&self) -> bool { @@ -101,3 +105,110 @@ impl Default for SizingStrategy { Self::Resizable { min_size: None, max_size: None, aspect_ratio: None } } } + +fn adjust_min_size(size: Size, ratio: AspectRatio) -> Size { + fn inner(x: P, y: P, ratio: AspectRatio) -> (P, P) { + if ratio.numerator < ratio.denominator { + let raw_ratio = ratio.ratio(); + let y = y.into(); + let y = y.max(x.into() / raw_ratio); + (x, y.cast()) + } else if ratio.numerator == ratio.denominator { + if x.into() > y.into() { + (x, x) + } else { + (y, y) + } + } else { + let raw_ratio = ratio.ratio(); + let x = x.into(); + let x = x.max(y.into() * raw_ratio); + (x.cast(), y) + } + } + + match size { + Size::Physical(PhysicalSize { width, height }) => { + Size::Physical(PhysicalSize::from(inner(width, height, ratio))) + } + Size::Logical(LogicalSize { width, height }) => { + Size::Logical(LogicalSize::from(inner(width, height, ratio))) + } + } +} + +fn adjust_max_size(size: Size, ratio: AspectRatio) -> Size { + fn inner(x: P, y: P, ratio: AspectRatio) -> (P, P) { + if ratio.numerator < ratio.denominator { + let raw_ratio = ratio.ratio(); + let x = x.into(); + let x = x.min(y.into() * raw_ratio); + (x.cast(), y) + } else if ratio.numerator == ratio.denominator { + if x.into() > y.into() { + (x, x) + } else { + (y, y) + } + } else { + let raw_ratio = ratio.ratio(); + let y = y.into(); + let y = y.min(x.into() / raw_ratio); + (x, y.cast()) + } + } + + match size { + Size::Physical(PhysicalSize { width, height }) => { + Size::Physical(PhysicalSize::from(inner(width, height, ratio))) + } + Size::Logical(LogicalSize { width, height }) => { + Size::Logical(LogicalSize::from(inner(width, height, ratio))) + } + } +} + +#[cfg(test)] +mod tests { + use crate::utils::SizingStrategy; + use crate::{AspectRatio, WindowSettings}; + use dpi::LogicalSize; + + #[test] + fn aspect_ratio_set_to_min_size() { + let mut settings = WindowSettings::new() + .with_min_size(LogicalSize::new(200.0, 300.0)) + .with_aspect_ratio(Some((1, 2))); + + assert_eq!( + SizingStrategy::from_settings(&settings).min_size(), + Some(LogicalSize::new(200.0, 400.0).into()) + ); + + settings.aspect_ratio = Some(AspectRatio::from((2, 1))); + + assert_eq!( + SizingStrategy::from_settings(&settings).min_size(), + Some(LogicalSize::new(600.0, 300.0).into()) + ); + } + + #[test] + fn aspect_ratio_set_to_max_size() { + let mut settings = WindowSettings::new() + .with_max_size(LogicalSize::new(200.0, 300.0)) + .with_aspect_ratio(Some((1, 2))); + + assert_eq!( + SizingStrategy::from_settings(&settings).max_size(), + Some(LogicalSize::new(150.0, 300.0).into()) + ); + + settings.aspect_ratio = Some(AspectRatio::from((2, 1))); + + assert_eq!( + SizingStrategy::from_settings(&settings).max_size(), + Some(LogicalSize::new(200.0, 100.0).into()) + ); + } +} From e128ff98b82e2878f2cab035e285ee48aa58a0dc Mon Sep 17 00:00:00 2001 From: Adrien Prokopowicz <6529475+prokopyl@users.noreply.github.com> Date: Mon, 17 Aug 2026 05:26:02 +0200 Subject: [PATCH 4/5] wip --- src/utils.rs | 81 ++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 63 insertions(+), 18 deletions(-) diff --git a/src/utils.rs b/src/utils.rs index 03c5c155..5d728495 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -4,25 +4,25 @@ use dpi::{LogicalSize, PhysicalSize}; #[derive(Copy, Clone)] pub(crate) enum SizingStrategy { - Fixed, + Fixed { size: Size }, Resizable { min_size: Option, max_size: Option, aspect_ratio: Option }, } impl SizingStrategy { pub fn from_settings(settings: &WindowSettings) -> Self { if !settings.resizable { - return Self::Fixed; + return Self::Fixed { size: settings.size }; } - if let (Some(min_size), Some(max_size)) = (settings.min_size, settings.max_size) { + let mut min_size = settings.min_size; + let mut max_size = settings.max_size; + + if let (Some(min_size), Some(max_size)) = (min_size, max_size) { if min_size == max_size { - return Self::Fixed; + return Self::Fixed { size: min_size }; } } - let mut min_size = settings.min_size; - let mut max_size = settings.max_size; - if let Some(ratio) = settings.aspect_ratio { min_size = min_size.map(|s| adjust_min_size(s, ratio)); max_size = max_size.map(|s| adjust_max_size(s, ratio)); @@ -37,14 +37,14 @@ impl SizingStrategy { pub fn min_size(&self) -> Option { match self { - Self::Fixed => None, + Self::Fixed { .. } => None, Self::Resizable { min_size, .. } => *min_size, } } pub fn max_size(&self) -> Option { match self { - Self::Fixed => None, + Self::Fixed { .. } => None, Self::Resizable { max_size, .. } => *max_size, } } @@ -94,10 +94,49 @@ impl SizingStrategy { pub fn aspect_ratio(&self) -> Option { match self { - Self::Fixed => None, + Self::Fixed { .. } => None, Self::Resizable { aspect_ratio, .. } => *aspect_ratio, } } + + pub fn adjust_size(&self, size: Size, scale_factor: f64) -> Size { + let (min, max, ratio) = match *self { + SizingStrategy::Resizable { min_size, max_size, aspect_ratio } => { + (min_size, max_size, aspect_ratio) + } + SizingStrategy::Fixed { size: fixed_size } => { + return match size { + Size::Physical(_) => Size::Physical(fixed_size.to_physical(scale_factor)), + Size::Logical(_) => Size::Logical(fixed_size.to_logical(scale_factor)), + } + } + }; + + match size { + Size::Physical(mut size) => { + if let Some(max_size) = max { + let max_size = max_size.to_physical(scale_factor); + size.width = size.width.min(max_size.width); + size.height = size.height.min(max_size.height); + } + + if let Some(min_size) = min { + let min_size = min_size.to_physical(scale_factor); + size.width = size.width.max(min_size.width); + size.height = size.height.max(min_size.height); + } + + if let Some(ratio) = ratio { + todo!() + } + + size.into() + } + Size::Logical(size) => { + todo!() + } + } + } } impl Default for SizingStrategy { @@ -106,6 +145,19 @@ impl Default for SizingStrategy { } } +macro_rules! map_size { + ($size:expr, $ratio:expr, $inner:expr) => { + match $size { + Size::Physical(PhysicalSize { width, height }) => { + Size::Physical(PhysicalSize::from($inner(width, height, $ratio))) + } + Size::Logical(LogicalSize { width, height }) => { + Size::Logical(LogicalSize::from($inner(width, height, $ratio))) + } + } + }; +} + fn adjust_min_size(size: Size, ratio: AspectRatio) -> Size { fn inner(x: P, y: P, ratio: AspectRatio) -> (P, P) { if ratio.numerator < ratio.denominator { @@ -158,14 +210,7 @@ fn adjust_max_size(size: Size, ratio: AspectRatio) -> Size { } } - match size { - Size::Physical(PhysicalSize { width, height }) => { - Size::Physical(PhysicalSize::from(inner(width, height, ratio))) - } - Size::Logical(LogicalSize { width, height }) => { - Size::Logical(LogicalSize::from(inner(width, height, ratio))) - } - } + map_size!(size, ratio, inner) } #[cfg(test)] From 648dc3b7252811e2f5f7e9b682c0eb8936dae0f5 Mon Sep 17 00:00:00 2001 From: Adrien Prokopowicz <6529475+prokopyl@users.noreply.github.com> Date: Sun, 25 Oct 2026 04:07:51 +0100 Subject: [PATCH 5/5] fixes --- src/platform/x11/error.rs | 2 + src/platform/x11/sizing.rs | 50 ++++++++------- src/platform/x11/window_thread.rs | 2 +- src/platform/x11/xcb_connection/size_hints.rs | 10 --- src/utils.rs | 63 +++---------------- src/window.rs | 7 +++ 6 files changed, 48 insertions(+), 86 deletions(-) delete mode 100644 src/platform/x11/xcb_connection/size_hints.rs diff --git a/src/platform/x11/error.rs b/src/platform/x11/error.rs index 83bba98e..4fc341fe 100644 --- a/src/platform/x11/error.rs +++ b/src/platform/x11/error.rs @@ -65,6 +65,7 @@ pub enum PlatformError { RequestFromMainThreadFailed(RequestFailed), SendMainThread, Redraw(String), + ResizeAttemptedOnFixedWindow, #[cfg(feature = "opengl")] XLib(crate::wrappers::xlib::XLibError), #[cfg(feature = "opengl")] @@ -96,6 +97,7 @@ impl Display for PlatformError { PlatformError::Calloop(e) => e.fmt(f), PlatformError::RequestFromMainThreadFailed(e) => e.fmt(f), PlatformError::SendMainThread => FatalError::SendMainThread.fmt(f), + PlatformError::ResizeAttemptedOnFixedWindow => f.write_str("Attempted to resize a window which does not support resizing."), #[cfg(feature = "opengl")] PlatformError::XLib(e) => e.fmt(f), #[cfg(feature = "opengl")] diff --git a/src/platform/x11/sizing.rs b/src/platform/x11/sizing.rs index a5f78b49..8ca5f952 100644 --- a/src/platform/x11/sizing.rs +++ b/src/platform/x11/sizing.rs @@ -176,7 +176,7 @@ impl SizingStateShared { } pub fn make_size_hints(&self) -> WmSizeHints { - get_size_hints(&self.sizing_strategy, self.window_size.get(), self.scale_factor()) + get_size_hints(&self.sizing_strategy, self.scale_factor()) } pub fn store_size( @@ -198,13 +198,12 @@ impl SizingStateShared { return Ok(()); } - window.resize(new_size)?.check()?; - if !self.sizing_strategy.is_resizable() { - let size_hints = get_size_hints(&self.sizing_strategy, new_size, self.scale_factor()); - window.set_size_hints(size_hints)?.check()?; + return Err(PlatformError::ResizeAttemptedOnFixedWindow); } + window.resize(new_size)?.check()?; + // This will trigger a `ConfigureNotify` event which will in turn change `self.window_info` // and notify the window handler about it @@ -220,6 +219,10 @@ impl SizingStateShared { return Ok(()); }; + if !self.sizing_strategy.is_resizable() { + return Err(PlatformError::ResizeAttemptedOnFixedWindow); + } + if let Err(()) = handler.resize(WindowSize::from_physical(new_size.cast(), self.scale_factor())) { @@ -228,10 +231,6 @@ impl SizingStateShared { } shared.xcb_window.resize(new_size.cast())?.check()?; // Will not call handler, as size is the same as above. - if !self.sizing_strategy.is_resizable() { - let size_hints = get_size_hints(&self.sizing_strategy, new_size, self.scale_factor()); - shared.xcb_window.set_size_hints(size_hints)?.check()?; - } // These come from the Host, no need to notify it about the new size @@ -290,28 +289,37 @@ impl SizingThreadShared { } } -pub fn get_size_hints( - strategy: &SizingStrategy, current_size: PhysicalSize, scale_factor: f64, -) -> WmSizeHints { +pub fn get_size_hints(strategy: &SizingStrategy, scale_factor: f64) -> WmSizeHints { + fn to_x11_aspect_ratio(aspect_ratio: crate::AspectRatio) -> x11rb::properties::AspectRatio { + match (aspect_ratio.numerator.try_into(), aspect_ratio.denominator.try_into()) { + (Ok(numerator), Ok(denominator)) => { + x11rb::properties::AspectRatio { numerator, denominator } + } + _ => x11rb::properties::AspectRatio { + numerator: (aspect_ratio.numerator as f64 / 2.0) as i32, + denominator: (aspect_ratio.denominator as f64 / 2.0) as i32, + }, + } + } + let mut size_hints = WmSizeHints::default(); match strategy { - SizingStrategy::Fixed => { - size_hints.min_size = Some(to_size_hint(current_size)); + SizingStrategy::Fixed { size } => { + size_hints.min_size = Some(to_size_hint(size.to_physical(scale_factor))); size_hints.max_size = size_hints.min_size; + size_hints.aspect = None; } - SizingStrategy::Resizable { min_size, max_size } => { - size_hints.min_size = - min_size.map(|s| to_size_hint(s.to_physical::(scale_factor))); - size_hints.max_size = - max_size.map(|s| to_size_hint(s.to_physical::(scale_factor))); + SizingStrategy::Resizable { min_size, max_size, aspect_ratio } => { + size_hints.min_size = min_size.map(|s| to_size_hint(s.to_physical(scale_factor))); + size_hints.max_size = max_size.map(|s| to_size_hint(s.to_physical(scale_factor))); + size_hints.aspect = aspect_ratio.map(to_x11_aspect_ratio).map(|a| (a, a)) } } size_hints } -fn to_size_hint(size: PhysicalSize) -> (i32, i32) { - let size = size.cast(); +fn to_size_hint(size: PhysicalSize) -> (i32, i32) { (size.width, size.height) } diff --git a/src/platform/x11/window_thread.rs b/src/platform/x11/window_thread.rs index 764122f7..ac74fdb4 100644 --- a/src/platform/x11/window_thread.rs +++ b/src/platform/x11/window_thread.rs @@ -227,7 +227,7 @@ impl WindowThreadHandle { } pub fn aspect_ratio(&self) -> Option { - self.shared.sizing_strategy().aspect_ratio() + self.sizing_strategy().aspect_ratio() } pub fn handle_main_thread_callback(&self) { diff --git a/src/platform/x11/xcb_connection/size_hints.rs b/src/platform/x11/xcb_connection/size_hints.rs deleted file mode 100644 index 43fc86bd..00000000 --- a/src/platform/x11/xcb_connection/size_hints.rs +++ /dev/null @@ -1,10 +0,0 @@ - -fn to_x11_aspect_ratio(aspect_ratio: crate::AspectRatio) -> AspectRatio { - match (aspect_ratio.numerator.try_into(), aspect_ratio.denominator.try_into()) { - (Ok(numerator), Ok(denominator)) => AspectRatio { numerator, denominator }, - _ => AspectRatio { - numerator: (aspect_ratio.numerator / 2) as i32, - denominator: (aspect_ratio.denominator / 2) as i32, - }, - } -} diff --git a/src/utils.rs b/src/utils.rs index 5d728495..502e4610 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,6 +1,6 @@ use crate::dpi::Size; use crate::{AspectRatio, WindowSettings, WindowSize}; -use dpi::{LogicalSize, PhysicalSize}; +use dpi::{LogicalSize, PhysicalSize, Pixel}; #[derive(Copy, Clone)] pub(crate) enum SizingStrategy { @@ -98,45 +98,6 @@ impl SizingStrategy { Self::Resizable { aspect_ratio, .. } => *aspect_ratio, } } - - pub fn adjust_size(&self, size: Size, scale_factor: f64) -> Size { - let (min, max, ratio) = match *self { - SizingStrategy::Resizable { min_size, max_size, aspect_ratio } => { - (min_size, max_size, aspect_ratio) - } - SizingStrategy::Fixed { size: fixed_size } => { - return match size { - Size::Physical(_) => Size::Physical(fixed_size.to_physical(scale_factor)), - Size::Logical(_) => Size::Logical(fixed_size.to_logical(scale_factor)), - } - } - }; - - match size { - Size::Physical(mut size) => { - if let Some(max_size) = max { - let max_size = max_size.to_physical(scale_factor); - size.width = size.width.min(max_size.width); - size.height = size.height.min(max_size.height); - } - - if let Some(min_size) = min { - let min_size = min_size.to_physical(scale_factor); - size.width = size.width.max(min_size.width); - size.height = size.height.max(min_size.height); - } - - if let Some(ratio) = ratio { - todo!() - } - - size.into() - } - Size::Logical(size) => { - todo!() - } - } - } } impl Default for SizingStrategy { @@ -145,19 +106,6 @@ impl Default for SizingStrategy { } } -macro_rules! map_size { - ($size:expr, $ratio:expr, $inner:expr) => { - match $size { - Size::Physical(PhysicalSize { width, height }) => { - Size::Physical(PhysicalSize::from($inner(width, height, $ratio))) - } - Size::Logical(LogicalSize { width, height }) => { - Size::Logical(LogicalSize::from($inner(width, height, $ratio))) - } - } - }; -} - fn adjust_min_size(size: Size, ratio: AspectRatio) -> Size { fn inner(x: P, y: P, ratio: AspectRatio) -> (P, P) { if ratio.numerator < ratio.denominator { @@ -210,7 +158,14 @@ fn adjust_max_size(size: Size, ratio: AspectRatio) -> Size { } } - map_size!(size, ratio, inner) + match size { + Size::Physical(PhysicalSize { width, height }) => { + Size::Physical(PhysicalSize::from(inner(width, height, ratio))) + } + Size::Logical(LogicalSize { width, height }) => { + Size::Logical(LogicalSize::from(inner(width, height, ratio))) + } + } } #[cfg(test)] diff --git a/src/window.rs b/src/window.rs index 84105013..5fdd7ba9 100644 --- a/src/window.rs +++ b/src/window.rs @@ -106,6 +106,13 @@ impl Window { /// The `size` can be provided in either physical or logical pixels. /// /// Using this method does *not* trigger the [`HostCallbacks::request_resize`](host::HostCallbacks) callback. + /// + /// # Errors + /// + /// This function will fail if the window is not resizable. + /// + /// It can also fail if either the underlying window or the platform failed to resize the window + /// or its contents. #[inline] pub fn resize(&self, size: impl Into) -> Result<(), Error> { self.inner.resize(size.into())?;