diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a94cf550d..4667cf4796 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ And please only add new entries to the top of this list, right below the `# Unre # Unreleased - Implement `HasRawDisplayHandle` for `EventLoop`. +- On macOS, set resize increments only for live resizes. # 0.28.1 diff --git a/src/platform_impl/macos/window.rs b/src/platform_impl/macos/window.rs index a5ff953296..3b411baca4 100644 --- a/src/platform_impl/macos/window.rs +++ b/src/platform_impl/macos/window.rs @@ -160,6 +160,9 @@ pub struct SharedState { save_presentation_opts: Option, pub current_theme: Option, + /// The current resize incerments for the window content. + pub(crate) resize_increments: NSSize, + /// The state of the `Option` as `Alt`. pub(crate) option_as_alt: OptionAsAlt, } @@ -301,6 +304,16 @@ impl WinitWindow { }; this.map(|mut this| { + let resize_increments = match attrs + .resize_increments + .map(|i| i.to_logical::(this.scale_factor())) + { + Some(LogicalSize { width, height }) if width >= 1. && height >= 1. => { + NSSize::new(width, height) + } + _ => NSSize::new(1., 1.), + }; + // Properly initialize the window's variables // // Ideally this should be done in an `init` method, @@ -308,6 +321,7 @@ impl WinitWindow { let state = SharedState { resizable: attrs.resizable, maximized: attrs.maximized, + resize_increments, ..Default::default() }; Ivar::write(&mut this.shared_state, Box::new(Mutex::new(state))); @@ -353,19 +367,6 @@ impl WinitWindow { } } - if let Some(increments) = attrs.resize_increments { - let increments = increments.to_logical(this.scale_factor()); - let (w, h) = (increments.width, increments.height); - if w >= 1.0 && h >= 1.0 { - let size = NSSize::new(w, h); - // It was concluded (#2411) that there is never a use-case for - // "outer" resize increments, hence we set "inner" ones here. - // ("outer" in macOS being just resizeIncrements, and "inner" - contentResizeIncrements) - // This is consistent with X11 size hints behavior - this.setContentResizeIncrements(size); - } - } - if !pl_attrs.has_shadow { this.setHasShadow(false); } @@ -648,7 +649,9 @@ impl WinitWindow { } pub fn resize_increments(&self) -> Option> { - let increments = self.contentResizeIncrements(); + let increments = self + .lock_shared_state("set_resize_increments") + .resize_increments; let (w, h) = (increments.width, increments.height); if w > 1.0 || h > 1.0 { Some(LogicalSize::new(w, h).to_physical(self.scale_factor())) @@ -658,12 +661,21 @@ impl WinitWindow { } pub fn set_resize_increments(&self, increments: Option) { - let size = increments + // XXX the resize increments are only used during live resizes. + let mut shared_state_lock = self.lock_shared_state("set_resize_increments"); + shared_state_lock.resize_increments = increments .map(|increments| { let logical = increments.to_logical::(self.scale_factor()); NSSize::new(logical.width.max(1.0), logical.height.max(1.0)) }) .unwrap_or_else(|| NSSize::new(1.0, 1.0)); + } + + pub(crate) fn set_resize_increments_inner(&self, size: NSSize) { + // It was concluded (#2411) that there is never a use-case for + // "outer" resize increments, hence we set "inner" ones here. + // ("outer" in macOS being just resizeIncrements, and "inner" - contentResizeIncrements) + // This is consistent with X11 size hints behavior self.setContentResizeIncrements(size); } diff --git a/src/platform_impl/macos/window_delegate.rs b/src/platform_impl/macos/window_delegate.rs index 6a8f2f1390..27f393cf6d 100644 --- a/src/platform_impl/macos/window_delegate.rs +++ b/src/platform_impl/macos/window_delegate.rs @@ -3,7 +3,7 @@ use std::ptr; use objc2::declare::{Ivar, IvarDrop}; -use objc2::foundation::{NSArray, NSObject, NSString}; +use objc2::foundation::{NSArray, NSObject, NSSize, NSString}; use objc2::rc::{autoreleasepool, Id, Shared}; use objc2::runtime::Object; use objc2::{class, declare_class, msg_send, msg_send_id, sel, ClassType}; @@ -117,6 +117,23 @@ declare_class!( self.emit_move_event(); } + #[sel(windowWillStartLiveResize:)] + fn window_will_start_live_resize(&mut self, _: Option<&Object>) { + trace_scope!("windowWillStartLiveResize:"); + + let increments = self + .window + .lock_shared_state("window_will_enter_fullscreen") + .resize_increments; + self.window.set_resize_increments_inner(increments); + } + + #[sel(windowDidEndLiveResize:)] + fn window_did_end_live_resize(&mut self, _: Option<&Object>) { + trace_scope!("windowDidEndLiveResize:"); + self.window.set_resize_increments_inner(NSSize::new(1., 1.)); + } + // This won't be triggered if the move was part of a resize. #[sel(windowDidMove:)] fn window_did_move(&mut self, _: Option<&Object>) {