macOS: Dpi overhaul (#997) (and rebase changes)
* WIP - Make EL2 DPI changes and implement on Windows (#895) * Modify DPI API publicly and on Windows * Add generic Position and make dpi creation functions const * Make examples work * Fix fullscreen windows not appearing * Replace Logical coordinates in window events with Physical coordinates * Update HiDpiFactorChanged * Document to_static * fix app_state errors * fixes hidpi related errors in window_delegate * fix bad merge * dpi_factor edits in window_delegate * fixes type and lifetime errors in window and window_delegate * applies fmt * complies with @aleksijuvani requested changes * modifies Handler lifetimes * fixes lifetime isues, adds propper handling for HiDpiChanged * applies fmt * restore original lifetimes * solution is somewhere out there * applies fmt * pass as references * resolves issue with HANDLER * crate visible type error * fixes visibility issues * applies fmt * deals with warnings * simplifies new_inner_size setting algorthm * moves proxy instead of referencing it and removes double deref from proxy.ns_window * makes @Osspial tests (https://github.com/rust-windowing/winit/pull/997\#discussion_r301852354) pass * complies with @aleksijuvani suggested changes * makes max window size std::f32::MAX Changes from rebasing: * fixes compile errors * applies fmt * reimplements HiDpiFactorChanged after #1173 merge * uses EventWrappers
This commit is contained in:
parent
7b43b0bc94
commit
077ee4d851
10 changed files with 273 additions and 153 deletions
|
|
@ -10,7 +10,9 @@ use std::{
|
|||
};
|
||||
|
||||
use crate::{
|
||||
dpi::{LogicalPosition, LogicalSize},
|
||||
dpi::{
|
||||
LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize, Position, Size, Size::Logical,
|
||||
},
|
||||
error::{ExternalError, NotSupportedError, OsError as RootOsError},
|
||||
icon::Icon,
|
||||
monitor::{MonitorHandle as RootMonitorHandle, VideoMode as RootVideoMode},
|
||||
|
|
@ -130,12 +132,17 @@ fn create_window(
|
|||
None => None,
|
||||
};
|
||||
let frame = match screen {
|
||||
Some(screen) => appkit::NSScreen::frame(screen),
|
||||
Some(screen) => NSScreen::frame(screen),
|
||||
None => {
|
||||
let (width, height) = attrs
|
||||
.inner_size
|
||||
.map(|logical| (logical.width, logical.height))
|
||||
.unwrap_or_else(|| (800.0, 600.0));
|
||||
let screen = NSScreen::mainScreen(nil);
|
||||
let hidpi_factor = NSScreen::backingScaleFactor(screen) as f64;
|
||||
let (width, height) = match attrs.inner_size {
|
||||
Some(size) => {
|
||||
let logical = size.to_logical(hidpi_factor);
|
||||
(logical.width, logical.height)
|
||||
}
|
||||
None => (800.0, 600.0),
|
||||
};
|
||||
NSRect::new(NSPoint::new(0.0, 0.0), NSSize::new(width, height))
|
||||
}
|
||||
};
|
||||
|
|
@ -292,6 +299,7 @@ pub struct UnownedWindow {
|
|||
pub shared_state: Arc<Mutex<SharedState>>,
|
||||
decorations: AtomicBool,
|
||||
cursor_state: Weak<Mutex<CursorState>>,
|
||||
pub inner_rect: Option<PhysicalSize>,
|
||||
}
|
||||
|
||||
unsafe impl Send for UnownedWindow {}
|
||||
|
|
@ -328,6 +336,8 @@ impl UnownedWindow {
|
|||
|
||||
let input_context = unsafe { util::create_input_context(*ns_view) };
|
||||
|
||||
let dpi_factor = unsafe { NSWindow::backingScaleFactor(*ns_window) as f64 };
|
||||
|
||||
unsafe {
|
||||
if win_attribs.transparent {
|
||||
ns_window.setOpaque_(NO);
|
||||
|
|
@ -335,13 +345,14 @@ impl UnownedWindow {
|
|||
}
|
||||
|
||||
ns_app.activateIgnoringOtherApps_(YES);
|
||||
|
||||
win_attribs
|
||||
.min_inner_size
|
||||
.map(|dim| set_min_inner_size(*ns_window, dim));
|
||||
win_attribs
|
||||
.max_inner_size
|
||||
.map(|dim| set_max_inner_size(*ns_window, dim));
|
||||
win_attribs.min_inner_size.map(|dim| {
|
||||
let logical_dim = dim.to_logical(dpi_factor);
|
||||
set_min_inner_size(*ns_window, logical_dim)
|
||||
});
|
||||
win_attribs.max_inner_size.map(|dim| {
|
||||
let logical_dim = dim.to_logical(dpi_factor);
|
||||
set_max_inner_size(*ns_window, logical_dim)
|
||||
});
|
||||
|
||||
use cocoa::foundation::NSArray;
|
||||
// register for drag and drop operations.
|
||||
|
|
@ -361,6 +372,9 @@ impl UnownedWindow {
|
|||
let maximized = win_attribs.maximized;
|
||||
let visible = win_attribs.visible;
|
||||
let decorations = win_attribs.decorations;
|
||||
let inner_rect = win_attribs
|
||||
.inner_size
|
||||
.map(|size| size.to_physical(dpi_factor));
|
||||
|
||||
let window = Arc::new(UnownedWindow {
|
||||
ns_view,
|
||||
|
|
@ -369,6 +383,7 @@ impl UnownedWindow {
|
|||
shared_state: Arc::new(Mutex::new(win_attribs.into())),
|
||||
decorations: AtomicBool::new(decorations),
|
||||
cursor_state,
|
||||
inner_rect,
|
||||
});
|
||||
|
||||
let delegate = new_delegate(&window, fullscreen.is_some());
|
||||
|
|
@ -425,27 +440,31 @@ impl UnownedWindow {
|
|||
AppState::queue_redraw(RootWindowId(self.id()));
|
||||
}
|
||||
|
||||
pub fn outer_position(&self) -> Result<LogicalPosition, NotSupportedError> {
|
||||
pub fn outer_position(&self) -> Result<PhysicalPosition, NotSupportedError> {
|
||||
let frame_rect = unsafe { NSWindow::frame(*self.ns_window) };
|
||||
Ok((
|
||||
let position = LogicalPosition::new(
|
||||
frame_rect.origin.x as f64,
|
||||
util::bottom_left_to_top_left(frame_rect),
|
||||
)
|
||||
.into())
|
||||
);
|
||||
let dpi_factor = self.hidpi_factor();
|
||||
Ok(position.to_physical(dpi_factor))
|
||||
}
|
||||
|
||||
pub fn inner_position(&self) -> Result<LogicalPosition, NotSupportedError> {
|
||||
pub fn inner_position(&self) -> Result<PhysicalPosition, NotSupportedError> {
|
||||
let content_rect = unsafe {
|
||||
NSWindow::contentRectForFrameRect_(*self.ns_window, NSWindow::frame(*self.ns_window))
|
||||
};
|
||||
Ok((
|
||||
let position = LogicalPosition::new(
|
||||
content_rect.origin.x as f64,
|
||||
util::bottom_left_to_top_left(content_rect),
|
||||
)
|
||||
.into())
|
||||
);
|
||||
let dpi_factor = self.hidpi_factor();
|
||||
Ok(position.to_physical(dpi_factor))
|
||||
}
|
||||
|
||||
pub fn set_outer_position(&self, position: LogicalPosition) {
|
||||
pub fn set_outer_position(&self, position: Position) {
|
||||
let dpi_factor = self.hidpi_factor();
|
||||
let position = position.to_logical(dpi_factor);
|
||||
let dummy = NSRect::new(
|
||||
NSPoint::new(
|
||||
position.x,
|
||||
|
|
@ -461,35 +480,50 @@ impl UnownedWindow {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn inner_size(&self) -> LogicalSize {
|
||||
pub fn inner_size(&self) -> PhysicalSize {
|
||||
let view_frame = unsafe { NSView::frame(*self.ns_view) };
|
||||
(view_frame.size.width as f64, view_frame.size.height as f64).into()
|
||||
let logical: LogicalSize =
|
||||
(view_frame.size.width as f64, view_frame.size.height as f64).into();
|
||||
let dpi_factor = self.hidpi_factor();
|
||||
logical.to_physical(dpi_factor)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn outer_size(&self) -> LogicalSize {
|
||||
pub fn outer_size(&self) -> PhysicalSize {
|
||||
let view_frame = unsafe { NSWindow::frame(*self.ns_window) };
|
||||
(view_frame.size.width as f64, view_frame.size.height as f64).into()
|
||||
let logical: LogicalSize =
|
||||
(view_frame.size.width as f64, view_frame.size.height as f64).into();
|
||||
let dpi_factor = self.hidpi_factor();
|
||||
logical.to_physical(dpi_factor)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_inner_size(&self, size: LogicalSize) {
|
||||
pub fn set_inner_size(&self, size: Size) {
|
||||
unsafe {
|
||||
util::set_content_size_async(*self.ns_window, size);
|
||||
let dpi_factor = self.hidpi_factor();
|
||||
util::set_content_size_async(*self.ns_window, size.to_logical(dpi_factor));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_min_inner_size(&self, dimensions: Option<LogicalSize>) {
|
||||
pub fn set_min_inner_size(&self, dimensions: Option<Size>) {
|
||||
unsafe {
|
||||
let dimensions = dimensions.unwrap_or_else(|| (0, 0).into());
|
||||
set_min_inner_size(*self.ns_window, dimensions);
|
||||
let dimensions = dimensions.unwrap_or(Logical(LogicalSize {
|
||||
width: 0.0,
|
||||
height: 0.0,
|
||||
}));
|
||||
let dpi_factor = self.hidpi_factor();
|
||||
set_min_inner_size(*self.ns_window, dimensions.to_logical(dpi_factor));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_max_inner_size(&self, dimensions: Option<LogicalSize>) {
|
||||
pub fn set_max_inner_size(&self, dimensions: Option<Size>) {
|
||||
unsafe {
|
||||
let dimensions = dimensions.unwrap_or_else(|| (!0, !0).into());
|
||||
set_max_inner_size(*self.ns_window, dimensions);
|
||||
let dimensions = dimensions.unwrap_or(Logical(LogicalSize {
|
||||
width: std::f32::MAX as f64,
|
||||
height: std::f32::MAX as f64,
|
||||
}));
|
||||
let dpi_factor = self.hidpi_factor();
|
||||
set_max_inner_size(*self.ns_window, dimensions.to_logical(dpi_factor));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -554,14 +588,14 @@ impl UnownedWindow {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_cursor_position(
|
||||
&self,
|
||||
cursor_position: LogicalPosition,
|
||||
) -> Result<(), ExternalError> {
|
||||
let window_position = self.inner_position().unwrap();
|
||||
pub fn set_cursor_position(&self, cursor_position: Position) -> Result<(), ExternalError> {
|
||||
let physical_window_position = self.inner_position().unwrap();
|
||||
let dpi_factor = self.hidpi_factor();
|
||||
let window_position = physical_window_position.to_logical(dpi_factor);
|
||||
let logical_cursor_position = cursor_position.to_logical(dpi_factor);
|
||||
let point = appkit::CGPoint {
|
||||
x: (cursor_position.x + window_position.x) as CGFloat,
|
||||
y: (cursor_position.y + window_position.y) as CGFloat,
|
||||
x: (logical_cursor_position.x + window_position.x) as CGFloat,
|
||||
y: (logical_cursor_position.y + window_position.y) as CGFloat,
|
||||
};
|
||||
CGDisplay::warp_mouse_cursor_position(point)
|
||||
.map_err(|e| ExternalError::Os(os_error!(OsError::CGError(e))))?;
|
||||
|
|
@ -894,7 +928,9 @@ impl UnownedWindow {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_ime_position(&self, logical_spot: LogicalPosition) {
|
||||
pub fn set_ime_position(&self, spot: Position) {
|
||||
let dpi_factor = self.hidpi_factor();
|
||||
let logical_spot = spot.to_logical(dpi_factor);
|
||||
unsafe {
|
||||
view::set_ime_position(
|
||||
*self.ns_view,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue