Skip to content

Commit

Permalink
On macOS, set resize increments only for live resize
Browse files Browse the repository at this point in the history
Closes #2684 for macOS.
  • Loading branch information
kchibisov committed Mar 2, 2023
1 parent 230b37d commit 811cc5c
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 16 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
42 changes: 27 additions & 15 deletions src/platform_impl/macos/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,9 @@ pub struct SharedState {
save_presentation_opts: Option<NSApplicationPresentationOptions>,
pub current_theme: Option<Theme>,

/// 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,
}
Expand Down Expand Up @@ -301,13 +304,24 @@ impl WinitWindow {
};

this.map(|mut this| {
let resize_increments = match attrs
.resize_increments
.map(|i| i.to_logical::<f64>(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,
// but for convenience we do it here instead.
let state = SharedState {
resizable: attrs.resizable,
maximized: attrs.maximized,
resize_increments,
..Default::default()
};
Ivar::write(&mut this.shared_state, Box::new(Mutex::new(state)));
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -648,7 +649,9 @@ impl WinitWindow {
}

pub fn resize_increments(&self) -> Option<PhysicalSize<u32>> {
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()))
Expand All @@ -658,12 +661,21 @@ impl WinitWindow {
}

pub fn set_resize_increments(&self, increments: Option<Size>) {
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::<f64>(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);
}

Expand Down
19 changes: 18 additions & 1 deletion src/platform_impl/macos/window_delegate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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>) {
Expand Down

0 comments on commit 811cc5c

Please sign in to comment.