macOS: Clean up coordinate system calculations (#3302)
* Clean up macOS and iOS monitor code a bit * Clean up window size methods Use `setContentSize`, `setContentMinSize`, `setContentMaxSize` and `contentRectForFrameRect` to let the windowing system figure out the required scaling, instead of us doing it manually. * Use a flipped NSView coordinate system * Clean up window position methods
This commit is contained in:
parent
5a43ea8cd6
commit
4f6fd44c6c
9 changed files with 173 additions and 217 deletions
|
|
@ -7,16 +7,18 @@ use icrate::AppKit::{
|
|||
NSApplicationPresentationHideMenuBar, NSApplicationPresentationOptions, NSDraggingDestination,
|
||||
NSFilenamesPboardType, NSPasteboard, NSWindowDelegate, NSWindowOcclusionStateVisible,
|
||||
};
|
||||
use icrate::Foundation::{MainThreadMarker, NSArray, NSObject, NSObjectProtocol, NSSize, NSString};
|
||||
use icrate::Foundation::{
|
||||
MainThreadMarker, NSArray, NSObject, NSObjectProtocol, NSPoint, NSSize, NSString,
|
||||
};
|
||||
use objc2::rc::{autoreleasepool, Id};
|
||||
use objc2::runtime::{AnyObject, ProtocolObject};
|
||||
use objc2::{
|
||||
class, declare_class, msg_send, msg_send_id, mutability, sel, ClassType, DeclaredClass,
|
||||
};
|
||||
|
||||
use super::monitor::flip_window_screen_coordinates;
|
||||
use super::{
|
||||
app_state::AppState,
|
||||
util,
|
||||
window::{get_ns_theme, WinitWindow},
|
||||
Fullscreen,
|
||||
};
|
||||
|
|
@ -35,7 +37,9 @@ pub(crate) struct State {
|
|||
initial_fullscreen: Cell<bool>,
|
||||
|
||||
// During `windowDidResize`, we use this to only send Moved if the position changed.
|
||||
previous_position: Cell<Option<(f64, f64)>>,
|
||||
//
|
||||
// This is expressed in native screen coordinates.
|
||||
previous_position: Cell<Option<NSPoint>>,
|
||||
|
||||
// Used to prevent redundant events.
|
||||
previous_scale_factor: Cell<f64>,
|
||||
|
|
@ -450,34 +454,33 @@ impl WinitWindowDelegate {
|
|||
}
|
||||
|
||||
fn queue_static_scale_factor_changed_event(&self) {
|
||||
let scale_factor = self.ivars().window.scale_factor();
|
||||
let window = &self.ivars().window;
|
||||
let scale_factor = window.scale_factor();
|
||||
if scale_factor == self.ivars().previous_scale_factor.get() {
|
||||
return;
|
||||
};
|
||||
|
||||
self.ivars().previous_scale_factor.set(scale_factor);
|
||||
let suggested_size = self.view_size();
|
||||
let content_size = window.contentRectForFrameRect(window.frame()).size;
|
||||
let content_size = LogicalSize::new(content_size.width, content_size.height);
|
||||
AppState::queue_static_scale_factor_changed_event(
|
||||
self.ivars().window.clone(),
|
||||
suggested_size.to_physical(scale_factor),
|
||||
window.clone(),
|
||||
content_size.to_physical(scale_factor),
|
||||
scale_factor,
|
||||
);
|
||||
}
|
||||
|
||||
fn emit_move_event(&self) {
|
||||
let rect = self.ivars().window.frame();
|
||||
let x = rect.origin.x as f64;
|
||||
let y = util::bottom_left_to_top_left(rect);
|
||||
if self.ivars().previous_position.get() != Some((x, y)) {
|
||||
self.ivars().previous_position.set(Some((x, y)));
|
||||
let scale_factor = self.ivars().window.scale_factor();
|
||||
let physical_pos = LogicalPosition::<f64>::from((x, y)).to_physical(scale_factor);
|
||||
self.queue_event(WindowEvent::Moved(physical_pos));
|
||||
let window = &self.ivars().window;
|
||||
let frame = window.frame();
|
||||
if self.ivars().previous_position.get() == Some(frame.origin) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
self.ivars().previous_position.set(Some(frame.origin));
|
||||
|
||||
fn view_size(&self) -> LogicalSize<f64> {
|
||||
let size = self.ivars().window.contentView().unwrap().frame().size;
|
||||
LogicalSize::new(size.width as f64, size.height as f64)
|
||||
let position = flip_window_screen_coordinates(frame);
|
||||
let position =
|
||||
LogicalPosition::new(position.x, position.y).to_physical(window.scale_factor());
|
||||
self.queue_event(WindowEvent::Moved(position));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue