From da2611e7c3714f49013ac2fcd2d5a0dcac92ba34 Mon Sep 17 00:00:00 2001 From: Osspial Date: Wed, 19 Jun 2019 16:49:43 -0400 Subject: [PATCH 01/25] 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 --- examples/multithreaded.rs | 34 ++-- examples/resizable.rs | 3 +- examples/window.rs | 1 + src/dpi.rs | 116 ++++++++++--- src/event.rs | 135 +++++++++++++-- src/event_loop.rs | 2 +- src/platform/desktop.rs | 12 +- src/platform_impl/windows/dpi.rs | 4 - src/platform_impl/windows/drop_handler.rs | 6 +- src/platform_impl/windows/event_loop.rs | 194 ++++++++++----------- src/platform_impl/windows/monitor.rs | 10 +- src/platform_impl/windows/util.rs | 6 +- src/platform_impl/windows/window.rs | 198 +++++----------------- src/platform_impl/windows/window_state.rs | 6 +- src/window.rs | 63 ++++--- 15 files changed, 427 insertions(+), 363 deletions(-) diff --git a/examples/multithreaded.rs b/examples/multithreaded.rs index 59cac69b8d..69754cac38 100644 --- a/examples/multithreaded.rs +++ b/examples/multithreaded.rs @@ -2,13 +2,14 @@ extern crate env_logger; use std::{collections::HashMap, sync::mpsc, thread, time::Duration}; use winit::{ + dpi::{PhysicalPosition, PhysicalSize}, event::{ElementState, Event, KeyboardInput, VirtualKeyCode, WindowEvent}, event_loop::{ControlFlow, EventLoop}, window::{CursorIcon, WindowBuilder}, }; const WINDOW_COUNT: usize = 3; -const WINDOW_SIZE: (u32, u32) = (600, 400); +const WINDOW_SIZE: PhysicalSize = PhysicalSize::new(600, 400); fn main() { env_logger::init(); @@ -16,7 +17,7 @@ fn main() { let mut window_senders = HashMap::with_capacity(WINDOW_COUNT); for _ in 0..WINDOW_COUNT { let window = WindowBuilder::new() - .with_inner_size(WINDOW_SIZE.into()) + .with_inner_size(WINDOW_SIZE) .build(&event_loop) .unwrap(); let (tx, rx) = mpsc::channel(); @@ -63,7 +64,7 @@ fn main() { }, L => { window.set_min_inner_size(match state { - true => Some(WINDOW_SIZE.into()), + true => Some(WINDOW_SIZE), false => None, }) }, @@ -80,19 +81,22 @@ fn main() { Q => window.request_redraw(), R => window.set_resizable(state), S => { - window.set_inner_size( - match state { - true => (WINDOW_SIZE.0 + 100, WINDOW_SIZE.1 + 100), - false => WINDOW_SIZE, - } - .into(), - ) + window.set_inner_size(match state { + true => { + PhysicalSize::new( + WINDOW_SIZE.width + 100, + WINDOW_SIZE.height + 100, + ) + }, + false => WINDOW_SIZE, + }) }, W => { window - .set_cursor_position( - (WINDOW_SIZE.0 as i32 / 2, WINDOW_SIZE.1 as i32 / 2).into(), - ) + .set_cursor_position(PhysicalPosition::new( + WINDOW_SIZE.width as f64 / 2.0, + WINDOW_SIZE.height as f64 / 2.0, + )) .unwrap() }, Z => { @@ -130,7 +134,9 @@ fn main() { }, _ => { if let Some(tx) = window_senders.get(&window_id) { - tx.send(event).unwrap(); + if let Some(event) = event.to_static() { + tx.send(event).unwrap(); + } } }, } diff --git a/examples/resizable.rs b/examples/resizable.rs index ae30585f15..44aa31656a 100644 --- a/examples/resizable.rs +++ b/examples/resizable.rs @@ -1,4 +1,5 @@ use winit::{ + dpi::LogicalSize, event::{ElementState, Event, KeyboardInput, VirtualKeyCode, WindowEvent}, event_loop::{ControlFlow, EventLoop}, window::WindowBuilder, @@ -11,7 +12,7 @@ fn main() { let window = WindowBuilder::new() .with_title("Hit space to toggle resizability.") - .with_inner_size((400, 200).into()) + .with_inner_size(LogicalSize::new(400.0, 200.0)) .with_resizable(resizable) .build(&event_loop) .unwrap(); diff --git a/examples/window.rs b/examples/window.rs index 12e0593e93..92f70c983f 100644 --- a/examples/window.rs +++ b/examples/window.rs @@ -9,6 +9,7 @@ fn main() { let window = WindowBuilder::new() .with_title("A fantastic window!") + .with_inner_size(winit::dpi::LogicalSize::new(128.0, 128.0)) .build(&event_loop) .unwrap(); diff --git a/src/dpi.rs b/src/dpi.rs index 9c89c12c3a..5b0b6a5b94 100644 --- a/src/dpi.rs +++ b/src/dpi.rs @@ -99,7 +99,7 @@ pub struct LogicalPosition { impl LogicalPosition { #[inline] - pub fn new(x: f64, y: f64) -> Self { + pub const fn new(x: f64, y: f64) -> Self { LogicalPosition { x, y } } @@ -160,7 +160,7 @@ pub struct PhysicalPosition { impl PhysicalPosition { #[inline] - pub fn new(x: f64, y: f64) -> Self { + pub const fn new(x: f64, y: f64) -> Self { PhysicalPosition { x, y } } @@ -221,7 +221,7 @@ pub struct LogicalSize { impl LogicalSize { #[inline] - pub fn new(width: f64, height: f64) -> Self { + pub const fn new(width: f64, height: f64) -> Self { LogicalSize { width, height } } @@ -235,7 +235,7 @@ impl LogicalSize { assert!(validate_hidpi_factor(dpi_factor)); let width = self.width * dpi_factor; let height = self.height * dpi_factor; - PhysicalSize::new(width, height) + PhysicalSize::new(width.round() as _, height.round() as _) } } @@ -269,20 +269,16 @@ impl Into<(u32, u32)> for LogicalSize { } /// A size represented in physical pixels. -/// -/// The size is stored as floats, so please be careful. Casting floats to integers truncates the fractional part, -/// which can cause noticable issues. To help with that, an `Into<(u32, u32)>` implementation is provided which -/// does the rounding for you. -#[derive(Debug, Copy, Clone, PartialEq)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct PhysicalSize { - pub width: f64, - pub height: f64, + pub width: u32, + pub height: u32, } impl PhysicalSize { #[inline] - pub fn new(width: f64, height: f64) -> Self { + pub const fn new(width: u32, height: u32) -> Self { PhysicalSize { width, height } } @@ -294,37 +290,105 @@ impl PhysicalSize { #[inline] pub fn to_logical(&self, dpi_factor: f64) -> LogicalSize { assert!(validate_hidpi_factor(dpi_factor)); - let width = self.width / dpi_factor; - let height = self.height / dpi_factor; + let width = self.width as f64 / dpi_factor; + let height = self.height as f64 / dpi_factor; LogicalSize::new(width, height) } } -impl From<(f64, f64)> for PhysicalSize { +impl From<(u32, u32)> for PhysicalSize { #[inline] - fn from((width, height): (f64, f64)) -> Self { + fn from((width, height): (u32, u32)) -> Self { Self::new(width, height) } } -impl From<(u32, u32)> for PhysicalSize { +impl Into<(u32, u32)> for PhysicalSize { + /// Note that this rounds instead of truncating. #[inline] - fn from((width, height): (u32, u32)) -> Self { - Self::new(width as f64, height as f64) + fn into(self) -> (u32, u32) { + (self.width, self.height) } } -impl Into<(f64, f64)> for PhysicalSize { +#[derive(Debug, Copy, Clone, PartialEq)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +pub enum Size { + Physical(PhysicalSize), + Logical(LogicalSize), +} + +impl Size { + pub fn new>(size: S) -> Size { + size.into() + } + + pub fn to_logical(&self, dpi_factor: f64) -> LogicalSize { + match *self { + Size::Physical(size) => size.to_logical(dpi_factor), + Size::Logical(size) => size, + } + } + + pub fn to_physical(&self, dpi_factor: f64) -> PhysicalSize { + match *self { + Size::Physical(size) => size, + Size::Logical(size) => size.to_physical(dpi_factor), + } + } +} + +impl From for Size { #[inline] - fn into(self) -> (f64, f64) { - (self.width, self.height) + fn from(size: PhysicalSize) -> Size { + Size::Physical(size) } } -impl Into<(u32, u32)> for PhysicalSize { - /// Note that this rounds instead of truncating. +impl From for Size { #[inline] - fn into(self) -> (u32, u32) { - (self.width.round() as _, self.height.round() as _) + fn from(size: LogicalSize) -> Size { + Size::Logical(size) + } +} + +#[derive(Debug, Copy, Clone, PartialEq)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +pub enum Position { + Physical(PhysicalPosition), + Logical(LogicalPosition), +} + +impl Position { + pub fn new>(position: S) -> Position { + position.into() + } + + pub fn to_logical(&self, dpi_factor: f64) -> LogicalPosition { + match *self { + Position::Physical(position) => position.to_logical(dpi_factor), + Position::Logical(position) => position, + } + } + + pub fn to_physical(&self, dpi_factor: f64) -> PhysicalPosition { + match *self { + Position::Physical(position) => position, + Position::Logical(position) => position.to_physical(dpi_factor), + } + } +} + +impl From for Position { + #[inline] + fn from(position: PhysicalPosition) -> Position { + Position::Physical(position) + } +} + +impl From for Position { + #[inline] + fn from(position: LogicalPosition) -> Position { + Position::Logical(position) } } diff --git a/src/event.rs b/src/event.rs index 3a6aeccb7b..b332a41668 100644 --- a/src/event.rs +++ b/src/event.rs @@ -7,18 +7,18 @@ use std::{path::PathBuf, time::Instant}; use crate::{ - dpi::{LogicalPosition, LogicalSize}, + dpi::{LogicalPosition, PhysicalPosition, PhysicalSize}, platform_impl, window::WindowId, }; /// Describes a generic event. -#[derive(Clone, Debug, PartialEq)] -pub enum Event { +#[derive(Debug, PartialEq)] +pub enum Event<'a, T: 'static> { /// Emitted when the OS sends an event to a winit window. WindowEvent { window_id: WindowId, - event: WindowEvent, + event: WindowEvent<'a>, }, /// Emitted when the OS sends an event to a device. DeviceEvent { @@ -43,8 +43,8 @@ pub enum Event { Suspended(bool), } -impl Event { - pub fn map_nonuser_event(self) -> Result, Event> { +impl<'a, T> Event<'a, T> { + pub fn map_nonuser_event(self) -> Result, Event<'a, T>> { use self::Event::*; match self { UserEvent(_) => Err(self), @@ -56,6 +56,25 @@ impl Event { Suspended(suspended) => Ok(Suspended(suspended)), } } + + /// If the event doesn't contain a reference, turn it into an event with a `'static` lifetime. + /// Otherwise, return `None`. + pub fn to_static(self) -> Option> { + use self::Event::*; + match self { + WindowEvent { window_id, event } => { + event + .to_static() + .map(|event| WindowEvent { window_id, event }) + }, + UserEvent(e) => Some(UserEvent(e)), + DeviceEvent { device_id, event } => Some(DeviceEvent { device_id, event }), + NewEvents(cause) => Some(NewEvents(cause)), + EventsCleared => Some(EventsCleared), + LoopDestroyed => Some(LoopDestroyed), + Suspended(suspended) => Some(Suspended(suspended)), + } + } } /// Describes the reason the event loop is resuming. @@ -85,13 +104,13 @@ pub enum StartCause { } /// Describes an event from a `Window`. -#[derive(Clone, Debug, PartialEq)] -pub enum WindowEvent { +#[derive(Debug, PartialEq)] +pub enum WindowEvent<'a> { /// The size of the window has changed. Contains the client area's new dimensions. - Resized(LogicalSize), + Resized(PhysicalSize), /// The position of the window has changed. Contains the window's new position. - Moved(LogicalPosition), + Moved(PhysicalPosition), /// The window has been requested to close. CloseRequested, @@ -138,7 +157,7 @@ pub enum WindowEvent { /// (x,y) coords in pixels relative to the top-left corner of the window. Because the range of this data is /// limited by the display area and it may have been transformed by the OS to implement effects such as cursor /// acceleration, it should not be used to implement non-cursor-like interactions such as 3D camera control. - position: LogicalPosition, + position: PhysicalPosition, modifiers: ModifiersState, }, @@ -196,8 +215,98 @@ pub enum WindowEvent { /// * Changing the display's DPI factor (e.g. in Control Panel on Windows). /// * Moving the window to a display with a different DPI factor. /// + /// After this event callback has been processed, the window will be resized to whatever value + /// is pointed to by the `new_inner_size` reference. By default, this will contain the size suggested + /// by the OS, but it can be changed to any value. If `new_inner_size` is set to `None`, no resizing + /// will occur. + /// /// For more information about DPI in general, see the [`dpi`](dpi/index.html) module. - HiDpiFactorChanged(f64), + HiDpiFactorChanged { + hidpi_factor: f64, + new_inner_size: &'a mut Option, + }, +} + +impl<'a> WindowEvent<'a> { + pub fn to_static(self) -> Option> { + use self::WindowEvent::*; + match self { + Resized(size) => Some(Resized(size)), + Moved(position) => Some(Moved(position)), + CloseRequested => Some(CloseRequested), + Destroyed => Some(Destroyed), + DroppedFile(file) => Some(DroppedFile(file)), + HoveredFile(file) => Some(HoveredFile(file)), + HoveredFileCancelled => Some(HoveredFileCancelled), + ReceivedCharacter(c) => Some(ReceivedCharacter(c)), + Focused(focused) => Some(Focused(focused)), + KeyboardInput { device_id, input } => Some(KeyboardInput { device_id, input }), + CursorMoved { + device_id, + position, + modifiers, + } => { + Some(CursorMoved { + device_id, + position, + modifiers, + }) + }, + CursorEntered { device_id } => Some(CursorEntered { device_id }), + CursorLeft { device_id } => Some(CursorLeft { device_id }), + MouseWheel { + device_id, + delta, + phase, + modifiers, + } => { + Some(MouseWheel { + device_id, + delta, + phase, + modifiers, + }) + }, + MouseInput { + device_id, + state, + button, + modifiers, + } => { + Some(MouseInput { + device_id, + state, + button, + modifiers, + }) + }, + TouchpadPressure { + device_id, + pressure, + stage, + } => { + Some(TouchpadPressure { + device_id, + pressure, + stage, + }) + }, + AxisMotion { + device_id, + axis, + value, + } => { + Some(AxisMotion { + device_id, + axis, + value, + }) + }, + RedrawRequested => Some(RedrawRequested), + Touch(touch) => Some(Touch(touch)), + HiDpiFactorChanged { .. } => None, + } + } } /// Identifier of an input device. @@ -320,7 +429,7 @@ pub enum TouchPhase { pub struct Touch { pub device_id: DeviceId, pub phase: TouchPhase, - pub location: LogicalPosition, + pub location: PhysicalPosition, /// unique identifier of a finger. pub id: u64, } diff --git a/src/event_loop.rs b/src/event_loop.rs index bbd3aea722..4ec814f24b 100644 --- a/src/event_loop.rs +++ b/src/event_loop.rs @@ -134,7 +134,7 @@ impl EventLoop { #[inline] pub fn run(self, event_handler: F) -> ! where - F: 'static + FnMut(Event, &EventLoopWindowTarget, &mut ControlFlow), + F: 'static + FnMut(Event<'_, T>, &EventLoopWindowTarget, &mut ControlFlow), { self.event_loop.run(event_handler) } diff --git a/src/platform/desktop.rs b/src/platform/desktop.rs index 1ec2056230..df80143162 100644 --- a/src/platform/desktop.rs +++ b/src/platform/desktop.rs @@ -30,7 +30,11 @@ pub trait EventLoopExtDesktop { /// You are strongly encouraged to use `run`, unless the use of this is absolutely necessary. fn run_return(&mut self, event_handler: F) where - F: FnMut(Event, &EventLoopWindowTarget, &mut ControlFlow); + F: FnMut( + Event<'_, Self::UserEvent>, + &EventLoopWindowTarget, + &mut ControlFlow, + ); } impl EventLoopExtDesktop for EventLoop { @@ -38,7 +42,11 @@ impl EventLoopExtDesktop for EventLoop { fn run_return(&mut self, event_handler: F) where - F: FnMut(Event, &EventLoopWindowTarget, &mut ControlFlow), + F: FnMut( + Event<'_, Self::UserEvent>, + &EventLoopWindowTarget, + &mut ControlFlow, + ), { self.event_loop.run_return(event_handler) } diff --git a/src/platform_impl/windows/dpi.rs b/src/platform_impl/windows/dpi.rs index afdae28741..7f9162cb25 100644 --- a/src/platform_impl/windows/dpi.rs +++ b/src/platform_impl/windows/dpi.rs @@ -176,7 +176,3 @@ pub unsafe fn hwnd_dpi(hwnd: HWND) -> u32 { } } } - -pub fn hwnd_scale_factor(hwnd: HWND) -> f64 { - dpi_to_scale_factor(unsafe { hwnd_dpi(hwnd) }) -} diff --git a/src/platform_impl/windows/drop_handler.rs b/src/platform_impl/windows/drop_handler.rs index 2ad5a97ad4..511902328d 100644 --- a/src/platform_impl/windows/drop_handler.rs +++ b/src/platform_impl/windows/drop_handler.rs @@ -32,7 +32,7 @@ pub struct FileDropHandlerData { pub interface: IDropTarget, refcount: AtomicUsize, window: HWND, - send_event: Box)>, + send_event: Box)>, cursor_effect: DWORD, hovered_is_valid: bool, /* If the currently hovered item is not valid there must not be any `HoveredFileCancelled` emitted */ } @@ -43,7 +43,7 @@ pub struct FileDropHandler { #[allow(non_snake_case)] impl FileDropHandler { - pub fn new(window: HWND, send_event: Box)>) -> FileDropHandler { + pub fn new(window: HWND, send_event: Box)>) -> FileDropHandler { let data = Box::new(FileDropHandlerData { interface: IDropTarget { lpVtbl: &DROP_TARGET_VTBL as *const IDropTargetVtbl, @@ -225,7 +225,7 @@ impl FileDropHandler { } impl FileDropHandlerData { - fn send_event(&self, event: Event<()>) { + fn send_event(&self, event: Event<'static, ()>) { (self.send_event)(event); } } diff --git a/src/platform_impl/windows/event_loop.rs b/src/platform_impl/windows/event_loop.rs index 929a0e0ff8..272fb8c5e2 100644 --- a/src/platform_impl/windows/event_loop.rs +++ b/src/platform_impl/windows/event_loop.rs @@ -30,7 +30,6 @@ use std::{ use winapi::shared::basetsd::{DWORD_PTR, UINT_PTR}; use winapi::{ - ctypes::c_int, shared::{ minwindef::{BOOL, DWORD, HIWORD, INT, LOWORD, LPARAM, LRESULT, UINT, WPARAM}, windef::{HWND, POINT, RECT}, @@ -38,19 +37,17 @@ use winapi::{ }, um::{ commctrl, libloaderapi, ole2, processthreadsapi, winbase, - winnt::{LONG, LPCSTR, SHORT}, + winnt::{LPCSTR, SHORT}, winuser, }, }; use crate::{ - dpi::{LogicalPosition, LogicalSize, PhysicalSize}, + dpi::{PhysicalPosition, PhysicalSize}, event::{DeviceEvent, Event, KeyboardInput, StartCause, Touch, TouchPhase, WindowEvent}, event_loop::{ControlFlow, EventLoopClosed, EventLoopWindowTarget as RootELW}, platform_impl::platform::{ - dpi::{ - become_dpi_aware, dpi_to_scale_factor, enable_non_client_dpi_scaling, hwnd_scale_factor, - }, + dpi::{become_dpi_aware, dpi_to_scale_factor, enable_non_client_dpi_scaling}, drop_handler::FileDropHandler, event::{self, handle_extended_keys, process_key_params, vkey_to_winit_vkey}, raw_input::{get_raw_input_data, get_raw_mouse_button_state}, @@ -62,25 +59,29 @@ use crate::{ window::WindowId as RootWindowId, }; -pub(crate) struct SubclassInput { +pub(crate) struct SubclassInput { pub window_state: Arc>, pub event_loop_runner: EventLoopRunnerShared, pub file_drop_handler: FileDropHandler, } impl SubclassInput { - unsafe fn send_event(&self, event: Event) { + unsafe fn send_event(&self, event: Event<'static, T>) { self.event_loop_runner.send_event(event); } + + unsafe fn send_event_unbuffered<'e>(&self, event: Event<'e, T>) -> Result<(), Event<'e, T>> { + self.event_loop_runner.send_event_unbuffered(event) + } } -struct ThreadMsgTargetSubclassInput { +struct ThreadMsgTargetSubclassInput { event_loop_runner: EventLoopRunnerShared, user_event_receiver: Receiver, } impl ThreadMsgTargetSubclassInput { - unsafe fn send_event(&self, event: Event) { + unsafe fn send_event(&self, event: Event<'static, T>) { self.event_loop_runner.send_event(event); } } @@ -90,7 +91,7 @@ pub struct EventLoop { window_target: RootELW, } -pub struct EventLoopWindowTarget { +pub struct EventLoopWindowTarget { thread_id: DWORD, trigger_newevents_on_redraw: Arc, thread_msg_target: HWND, @@ -133,7 +134,7 @@ impl EventLoop { pub fn run(mut self, event_handler: F) -> ! where - F: 'static + FnMut(Event, &RootELW, &mut ControlFlow), + F: 'static + FnMut(Event<'_, T>, &RootELW, &mut ControlFlow), { self.run_return(event_handler); ::std::process::exit(0); @@ -141,7 +142,7 @@ impl EventLoop { pub fn run_return(&mut self, mut event_handler: F) where - F: FnMut(Event, &RootELW, &mut ControlFlow), + F: FnMut(Event<'_, T>, &RootELW, &mut ControlFlow), { unsafe { winuser::IsGUIThread(1); @@ -243,23 +244,34 @@ impl EventLoopWindowTarget { } pub(crate) type EventLoopRunnerShared = Rc>; -pub(crate) struct ELRShared { +pub(crate) struct ELRShared { runner: RefCell>>, - buffer: RefCell>>, + buffer: RefCell>>, } -pub(crate) struct EventLoopRunner { +pub(crate) struct EventLoopRunner { trigger_newevents_on_redraw: Arc, control_flow: ControlFlow, runner_state: RunnerState, modal_redraw_window: HWND, in_modal_loop: bool, - event_handler: Box, &mut ControlFlow)>, + event_handler: Box, &mut ControlFlow)>, panic_error: Option, } type PanicError = Box; impl ELRShared { - pub(crate) unsafe fn send_event(&self, event: Event) { + pub(crate) unsafe fn send_event(&self, event: Event<'static, T>) { + if let Err(event) = self.send_event_unbuffered(event) { + // If the runner is already borrowed, we're in the middle of an event loop invocation. Add + // the event to a buffer to be processed later. + self.buffer.borrow_mut().push_back(event) + } + } + + pub(crate) unsafe fn send_event_unbuffered<'e>( + &self, + event: Event<'e, T>, + ) -> Result<(), Event<'e, T>> { if let Ok(mut runner_ref) = self.runner.try_borrow_mut() { if let Some(ref mut runner) = *runner_ref { runner.process_event(event); @@ -277,13 +289,11 @@ impl ELRShared { } } - return; + return Ok(()); } } - // If the runner is already borrowed, we're in the middle of an event loop invocation. Add - // the event to a buffer to be processed later. - self.buffer.borrow_mut().push_back(event) + Err(event) } } @@ -305,7 +315,7 @@ enum RunnerState { impl EventLoopRunner { unsafe fn new(event_loop: &EventLoop, f: F) -> EventLoopRunner where - F: FnMut(Event, &mut ControlFlow), + F: FnMut(Event<'_, T>, &mut ControlFlow), { EventLoopRunner { trigger_newevents_on_redraw: event_loop @@ -318,8 +328,8 @@ impl EventLoopRunner { in_modal_loop: false, modal_redraw_window: event_loop.window_target.p.thread_msg_target, event_handler: mem::transmute::< - Box, &mut ControlFlow)>, - Box, &mut ControlFlow)>, + Box, &mut ControlFlow)>, + Box, &mut ControlFlow)>, >(Box::new(f)), panic_error: None, } @@ -375,7 +385,7 @@ impl EventLoopRunner { }; } - fn process_event(&mut self, event: Event) { + fn process_event(&mut self, event: Event<'_, T>) { // If we're in the modal loop, we need to have some mechanism for finding when the event // queue has been cleared so we can call `events_cleared`. Windows doesn't give any utilities // for doing this, but it DOES guarantee that WM_PAINT will only occur after input events have @@ -479,7 +489,7 @@ impl EventLoopRunner { } } - fn call_event_handler(&mut self, event: Event) { + fn call_event_handler(&mut self, event: Event<'_, T>) { match event { Event::NewEvents(_) => { self.trigger_newevents_on_redraw @@ -678,13 +688,6 @@ lazy_static! { winuser::RegisterWindowMessageA("Winit::DestroyMsg\0".as_ptr() as LPCSTR) } }; - // Message sent by a `Window` after creation if it has a DPI != 96. - // WPARAM is the the DPI (u32). LOWORD of LPARAM is width, and HIWORD is height. - pub static ref INITIAL_DPI_MSG_ID: u32 = { - unsafe { - winuser::RegisterWindowMessageA("Winit::InitialDpiMsg\0".as_ptr() as LPCSTR) - } - }; // Message sent by a `Window` if it's requesting a redraw without sending a NewEvents. pub static ref REQUEST_REDRAW_NO_NEWEVENTS_MSG_ID: u32 = { unsafe { @@ -808,7 +811,7 @@ pub(crate) fn subclass_window(window: HWND, subclass_input: SubclassInput) // // Returning 0 tells the Win32 API that the message has been processed. // FIXME: detect WM_DWMCOMPOSITIONCHANGED and call DwmEnableBlurBehindWindow if necessary -unsafe extern "system" fn public_window_callback( +unsafe extern "system" fn public_window_callback( window: HWND, msg: UINT, wparam: WPARAM, @@ -923,12 +926,11 @@ unsafe extern "system" fn public_window_callback( let windowpos = lparam as *const winuser::WINDOWPOS; if (*windowpos).flags & winuser::SWP_NOMOVE != winuser::SWP_NOMOVE { - let dpi_factor = hwnd_scale_factor(window); - let logical_position = - LogicalPosition::from_physical(((*windowpos).x, (*windowpos).y), dpi_factor); + let physical_position = + PhysicalPosition::new((*windowpos).x as f64, (*windowpos).y as f64); subclass_input.send_event(Event::WindowEvent { window_id: RootWindowId(WindowId(window)), - event: Moved(logical_position), + event: Moved(physical_position), }); } @@ -941,11 +943,10 @@ unsafe extern "system" fn public_window_callback( let w = LOWORD(lparam as DWORD) as u32; let h = HIWORD(lparam as DWORD) as u32; - let dpi_factor = hwnd_scale_factor(window); - let logical_size = LogicalSize::from_physical((w, h), dpi_factor); + let physical_size = PhysicalSize::new(w, h); let event = Event::WindowEvent { window_id: RootWindowId(WindowId(window)), - event: Resized(logical_size), + event: Resized(physical_size), }; { @@ -1011,8 +1012,7 @@ unsafe extern "system" fn public_window_callback( let x = windowsx::GET_X_LPARAM(lparam) as f64; let y = windowsx::GET_Y_LPARAM(lparam) as f64; - let dpi_factor = hwnd_scale_factor(window); - let position = LogicalPosition::from_physical((x, y), dpi_factor); + let position = PhysicalPosition::new(x, y); subclass_input.send_event(Event::WindowEvent { window_id: RootWindowId(WindowId(window)), @@ -1413,11 +1413,10 @@ unsafe extern "system" fn public_window_callback( mem::size_of::() as INT, ) > 0 { - let dpi_factor = hwnd_scale_factor(window); for input in &inputs { let x = (input.x as f64) / 100f64; let y = (input.y as f64) / 100f64; - let location = LogicalPosition::from_physical((x, y), dpi_factor); + let location = PhysicalPosition::new(x, y); subclass_input.send_event(Event::WindowEvent { window_id: RootWindowId(WindowId(window)), event: WindowEvent::Touch(Touch { @@ -1538,27 +1537,66 @@ unsafe extern "system" fn public_window_callback( new_dpi_factor != old_dpi_factor && window_state.fullscreen.is_none() }; - // This prevents us from re-applying DPI adjustment to the restored size after exiting - // fullscreen (the restored size is already DPI adjusted). - if allow_resize { - // Resize window to the size suggested by Windows. - let rect = &*(lparam as *const RECT); + let style = winuser::GetWindowLongW(window, winuser::GWL_STYLE) as _; + let style_ex = winuser::GetWindowLongW(window, winuser::GWL_EXSTYLE) as _; + let b_menu = !winuser::GetMenu(window).is_null() as BOOL; + + // New size as suggested by Windows. + let rect = *(lparam as *const RECT); + + // The window rect provided is the window's outer size, not it's inner size. However, + // win32 doesn't provide an `UnadjustWindowRectEx` function to get the client rect from + // the outer rect, so we instead adjust the window rect to get the decoration margins + // and remove them from the outer size. + let margins_horizontal: u32; + let margins_vertical: u32; + { + let mut adjusted_rect = rect; + winuser::AdjustWindowRectExForDpi( + &mut adjusted_rect, + style, + b_menu, + style_ex, + new_dpi_x, + ); + let margin_left = rect.left - adjusted_rect.left; + let margin_right = adjusted_rect.right - rect.right; + let margin_top = rect.top - adjusted_rect.top; + let margin_bottom = adjusted_rect.bottom - rect.bottom; + + margins_horizontal = (margin_left + margin_right) as u32; + margins_vertical = (margin_bottom + margin_top) as u32; + } + + let physical_inner_rect = PhysicalSize::new( + (rect.right - rect.left) as u32 - margins_horizontal, + (rect.bottom - rect.top) as u32 - margins_vertical, + ); + + // `allow_resize` prevents us from re-applying DPI adjustment to the restored size after + // exiting fullscreen (the restored size is already DPI adjusted). + let mut new_inner_rect_opt = Some(physical_inner_rect).filter(|_| allow_resize); + + let _ = subclass_input.send_event_unbuffered(Event::WindowEvent { + window_id: RootWindowId(WindowId(window)), + event: HiDpiFactorChanged { + hidpi_factor: new_dpi_factor, + new_inner_size: &mut new_inner_rect_opt, + }, + }); + + if let Some(new_inner_rect) = new_inner_rect_opt { winuser::SetWindowPos( window, ptr::null_mut(), rect.left, rect.top, - rect.right - rect.left, - rect.bottom - rect.top, + (new_inner_rect.width + margins_horizontal) as _, + (new_inner_rect.height + margins_vertical) as _, winuser::SWP_NOZORDER | winuser::SWP_NOACTIVATE, ); } - subclass_input.send_event(Event::WindowEvent { - window_id: RootWindowId(WindowId(window)), - event: HiDpiFactorChanged(new_dpi_factor), - }); - 0 }, @@ -1572,44 +1610,6 @@ unsafe extern "system" fn public_window_callback( f.set(WindowFlags::MARKER_RETAIN_STATE_ON_SIZE, wparam != 0) }); 0 - } else if msg == *INITIAL_DPI_MSG_ID { - use crate::event::WindowEvent::HiDpiFactorChanged; - let scale_factor = dpi_to_scale_factor(wparam as u32); - subclass_input.send_event(Event::WindowEvent { - window_id: RootWindowId(WindowId(window)), - event: HiDpiFactorChanged(scale_factor), - }); - // Automatically resize for actual DPI - let width = LOWORD(lparam as DWORD) as u32; - let height = HIWORD(lparam as DWORD) as u32; - let (adjusted_width, adjusted_height): (u32, u32) = - PhysicalSize::from_logical((width, height), scale_factor).into(); - // We're not done yet! `SetWindowPos` needs the window size, not the client area size. - let mut rect = RECT { - top: 0, - left: 0, - bottom: adjusted_height as LONG, - right: adjusted_width as LONG, - }; - let dw_style = winuser::GetWindowLongA(window, winuser::GWL_STYLE) as DWORD; - let b_menu = !winuser::GetMenu(window).is_null() as BOOL; - let dw_style_ex = winuser::GetWindowLongA(window, winuser::GWL_EXSTYLE) as DWORD; - winuser::AdjustWindowRectEx(&mut rect, dw_style, b_menu, dw_style_ex); - let outer_x = (rect.right - rect.left).abs() as c_int; - let outer_y = (rect.top - rect.bottom).abs() as c_int; - winuser::SetWindowPos( - window, - ptr::null_mut(), - 0, - 0, - outer_x, - outer_y, - winuser::SWP_NOMOVE - | winuser::SWP_NOREPOSITION - | winuser::SWP_NOZORDER - | winuser::SWP_NOACTIVATE, - ); - 0 } else { commctrl::DefSubclassProc(window, msg, wparam, lparam) } @@ -1617,7 +1617,7 @@ unsafe extern "system" fn public_window_callback( } } -unsafe extern "system" fn thread_event_target_callback( +unsafe extern "system" fn thread_event_target_callback( window: HWND, msg: UINT, wparam: WPARAM, diff --git a/src/platform_impl/windows/monitor.rs b/src/platform_impl/windows/monitor.rs index e4ee3f92f3..046e3e5f76 100644 --- a/src/platform_impl/windows/monitor.rs +++ b/src/platform_impl/windows/monitor.rs @@ -3,7 +3,7 @@ use winapi::{ minwindef::{BOOL, DWORD, LPARAM, TRUE, WORD}, windef::{HDC, HMONITOR, HWND, LPRECT, POINT}, }, - um::{wingdi, winnt::LONG, winuser}, + um::{wingdi, winuser}, }; use std::{ @@ -143,14 +143,6 @@ impl MonitorHandle { } } - pub(crate) fn contains_point(&self, point: &POINT) -> bool { - let left = self.position.0 as LONG; - let right = left + self.dimensions.0 as LONG; - let top = self.position.1 as LONG; - let bottom = top + self.dimensions.1 as LONG; - point.x >= left && point.x <= right && point.y >= top && point.y <= bottom - } - #[inline] pub fn name(&self) -> Option { Some(self.monitor_name.clone()) diff --git a/src/platform_impl/windows/util.rs b/src/platform_impl/windows/util.rs index a02964b396..cb1c377140 100644 --- a/src/platform_impl/windows/util.rs +++ b/src/platform_impl/windows/util.rs @@ -10,7 +10,7 @@ use winapi::{ ctypes::wchar_t, shared::{ minwindef::{BOOL, DWORD}, - windef::{HWND, POINT, RECT}, + windef::{HWND, RECT}, }, um::{winbase::lstrlenW, winuser}, }; @@ -49,10 +49,6 @@ fn win_to_err BOOL>(f: F) -> Result<(), io::Error> { } } -pub fn get_cursor_pos() -> Option { - unsafe { status_map(|cursor_pos| winuser::GetCursorPos(cursor_pos)) } -} - pub fn get_window_rect(hwnd: HWND) -> Option { unsafe { status_map(|rect| winuser::GetWindowRect(hwnd, rect)) } } diff --git a/src/platform_impl/windows/window.rs b/src/platform_impl/windows/window.rs index 01a559b5d6..1007179f80 100644 --- a/src/platform_impl/windows/window.rs +++ b/src/platform_impl/windows/window.rs @@ -13,7 +13,7 @@ use std::{ use winapi::{ ctypes::c_int, shared::{ - minwindef::{DWORD, LPARAM, UINT, WORD, WPARAM}, + minwindef::{DWORD, UINT}, windef::{HWND, POINT, RECT}, }, um::{ @@ -29,15 +29,14 @@ use winapi::{ }; use crate::{ - dpi::{LogicalPosition, LogicalSize, PhysicalSize}, + dpi::{PhysicalPosition, PhysicalSize, Position, Size}, error::{ExternalError, NotSupportedError, OsError as RootOsError}, monitor::MonitorHandle as RootMonitorHandle, platform_impl::platform::{ dpi::{dpi_to_scale_factor, hwnd_dpi}, drop_handler::FileDropHandler, event_loop::{ - self, EventLoopWindowTarget, DESTROY_MSG_ID, INITIAL_DPI_MSG_ID, - REQUEST_REDRAW_NO_NEWEVENTS_MSG_ID, + self, EventLoopWindowTarget, DESTROY_MSG_ID, REQUEST_REDRAW_NO_NEWEVENTS_MSG_ID, }, icon::{self, IconType, WinIcon}, monitor, @@ -128,14 +127,14 @@ impl Window { #[inline] pub fn set_visible(&self, visible: bool) { - match visible { - true => unsafe { - winuser::ShowWindow(self.window.0, winuser::SW_SHOW); - }, - false => unsafe { - winuser::ShowWindow(self.window.0, winuser::SW_HIDE); - }, - } + let window = self.window.clone(); + let window_state = Arc::clone(&self.window_state); + + self.thread_executor.execute_in_thread(move || { + WindowState::set_window_flags(window_state.lock(), window.0, None, |f| { + f.set(WindowFlags::VISIBLE, visible) + }); + }); } #[inline] @@ -154,41 +153,25 @@ impl Window { } } - pub(crate) fn outer_position_physical(&self) -> (i32, i32) { + #[inline] + pub fn outer_position(&self) -> Result { util::get_window_rect(self.window.0) - .map(|rect| (rect.left as i32, rect.top as i32)) - .unwrap() + .map(|rect| Ok(PhysicalPosition::new(rect.left as f64, rect.top as f64))) + .expect("Unexpected GetWindowRect failure; please report this error to https://github.com/rust-windowing/winit") } #[inline] - pub fn outer_position(&self) -> Result { - let physical_position = self.outer_position_physical(); - let dpi_factor = self.hidpi_factor(); - Ok(LogicalPosition::from_physical( - physical_position, - dpi_factor, - )) - } - - pub(crate) fn inner_position_physical(&self) -> (i32, i32) { + pub fn inner_position(&self) -> Result { let mut position: POINT = unsafe { mem::zeroed() }; if unsafe { winuser::ClientToScreen(self.window.0, &mut position) } == 0 { panic!("Unexpected ClientToScreen failure: please report this error to https://github.com/rust-windowing/winit") } - (position.x, position.y) + Ok(PhysicalPosition::new(position.x as f64, position.y as f64)) } #[inline] - pub fn inner_position(&self) -> Result { - let physical_position = self.inner_position_physical(); - let dpi_factor = self.hidpi_factor(); - Ok(LogicalPosition::from_physical( - physical_position, - dpi_factor, - )) - } - - pub(crate) fn set_position_physical(&self, x: i32, y: i32) { + pub fn set_outer_position(&self, position: Position) { + let (x, y): (i32, i32) = position.to_physical(self.hidpi_factor()).into(); unsafe { winuser::SetWindowPos( self.window.0, @@ -204,34 +187,22 @@ impl Window { } #[inline] - pub fn set_outer_position(&self, logical_position: LogicalPosition) { - let dpi_factor = self.hidpi_factor(); - let (x, y) = logical_position.to_physical(dpi_factor).into(); - self.set_position_physical(x, y); - } - - pub(crate) fn inner_size_physical(&self) -> (u32, u32) { + pub fn inner_size(&self) -> PhysicalSize { let mut rect: RECT = unsafe { mem::uninitialized() }; if unsafe { winuser::GetClientRect(self.window.0, &mut rect) } == 0 { panic!("Unexpected GetClientRect failure: please report this error to https://github.com/rust-windowing/winit") } - ( + PhysicalSize::new( (rect.right - rect.left) as u32, (rect.bottom - rect.top) as u32, ) } #[inline] - pub fn inner_size(&self) -> LogicalSize { - let physical_size = self.inner_size_physical(); - let dpi_factor = self.hidpi_factor(); - LogicalSize::from_physical(physical_size, dpi_factor) - } - - pub(crate) fn outer_size_physical(&self) -> (u32, u32) { + pub fn outer_size(&self) -> PhysicalSize { util::get_window_rect(self.window.0) .map(|rect| { - ( + PhysicalSize::new( (rect.right - rect.left) as u32, (rect.bottom - rect.top) as u32, ) @@ -239,13 +210,6 @@ impl Window { .unwrap() } - #[inline] - pub fn outer_size(&self) -> LogicalSize { - let physical_size = self.outer_size_physical(); - let dpi_factor = self.hidpi_factor(); - LogicalSize::from_physical(physical_size, dpi_factor) - } - pub(crate) fn set_inner_size_physical(&self, x: u32, y: u32) { unsafe { let rect = util::adjust_window_rect( @@ -278,42 +242,26 @@ impl Window { } #[inline] - pub fn set_inner_size(&self, logical_size: LogicalSize) { + pub fn set_inner_size(&self, size: Size) { let dpi_factor = self.hidpi_factor(); - let (width, height) = logical_size.to_physical(dpi_factor).into(); - self.set_inner_size_physical(width, height); - } - - pub(crate) fn set_min_inner_size_physical(&self, dimensions: Option<(u32, u32)>) { - self.window_state.lock().min_size = dimensions.map(Into::into); - // Make windows re-check the window size bounds. - let (width, height) = self.inner_size_physical(); + let (width, height) = size.to_physical(dpi_factor).into(); self.set_inner_size_physical(width, height); } #[inline] - pub fn set_min_inner_size(&self, logical_size: Option) { - let physical_size = logical_size.map(|logical_size| { - let dpi_factor = self.hidpi_factor(); - logical_size.to_physical(dpi_factor).into() - }); - self.set_min_inner_size_physical(physical_size); - } - - pub fn set_max_inner_size_physical(&self, dimensions: Option<(u32, u32)>) { - self.window_state.lock().max_size = dimensions.map(Into::into); + pub fn set_min_inner_size(&self, size: Option) { + self.window_state.lock().min_size = size; // Make windows re-check the window size bounds. - let (width, height) = self.inner_size_physical(); - self.set_inner_size_physical(width, height); + let size = self.inner_size(); + self.set_inner_size(size.into()); } #[inline] - pub fn set_max_inner_size(&self, logical_size: Option) { - let physical_size = logical_size.map(|logical_size| { - let dpi_factor = self.hidpi_factor(); - logical_size.to_physical(dpi_factor).into() - }); - self.set_max_inner_size_physical(physical_size); + pub fn set_max_inner_size(&self, size: Option) { + self.window_state.lock().max_size = size; + // Make windows re-check the window size bounds. + let size = self.inner_size(); + self.set_inner_size(size.into()); } #[inline] @@ -382,7 +330,11 @@ impl Window { self.window_state.lock().dpi_factor } - fn set_cursor_position_physical(&self, x: i32, y: i32) -> Result<(), ExternalError> { + #[inline] + pub fn set_cursor_position(&self, position: Position) -> Result<(), ExternalError> { + let dpi_factor = self.hidpi_factor(); + let (x, y) = position.to_physical(dpi_factor).into(); + let mut point = POINT { x, y }; unsafe { if winuser::ClientToScreen(self.window.0, &mut point) == 0 { @@ -395,16 +347,6 @@ impl Window { Ok(()) } - #[inline] - pub fn set_cursor_position( - &self, - logical_position: LogicalPosition, - ) -> Result<(), ExternalError> { - let dpi_factor = self.hidpi_factor(); - let (x, y) = logical_position.to_physical(dpi_factor).into(); - self.set_cursor_position_physical(x, y) - } - #[inline] pub fn id(&self) -> WindowId { WindowId(self.window.0) @@ -551,7 +493,7 @@ impl Window { } #[inline] - pub fn set_ime_position(&self, _logical_spot: LogicalPosition) { + pub fn set_ime_position(&self, _position: Position) { unimplemented!(); } } @@ -625,41 +567,6 @@ unsafe fn init( // registering the window class let class_name = register_window_class(&window_icon, &taskbar_icon); - let guessed_dpi_factor = { - let monitors = monitor::available_monitors(); - let dpi_factor = if !monitors.is_empty() { - let mut dpi_factor = Some(monitors[0].hidpi_factor()); - for monitor in &monitors { - if Some(monitor.hidpi_factor()) != dpi_factor { - dpi_factor = None; - } - } - dpi_factor - } else { - return Err(os_error!(io::Error::new( - io::ErrorKind::NotFound, - "No monitors were detected." - ))); - }; - dpi_factor.unwrap_or_else(|| { - util::get_cursor_pos() - .and_then(|cursor_pos| { - let mut dpi_factor = None; - for monitor in &monitors { - if monitor.contains_point(&cursor_pos) { - dpi_factor = Some(monitor.hidpi_factor()); - break; - } - } - dpi_factor - }) - .unwrap_or(1.0) - }) - }; - info!("Guessed window DPI factor: {}", guessed_dpi_factor); - - let dimensions = attributes.inner_size.unwrap_or_else(|| (1024, 768).into()); - let mut window_flags = WindowFlags::empty(); window_flags.set(WindowFlags::DECORATIONS, attributes.decorations); window_flags.set(WindowFlags::ALWAYS_ON_TOP, attributes.always_on_top); @@ -711,20 +618,6 @@ unsafe fn init( let dpi = hwnd_dpi(real_window.0); let dpi_factor = dpi_to_scale_factor(dpi); - if dpi_factor != guessed_dpi_factor { - let (width, height): (u32, u32) = dimensions.into(); - let mut packed_dimensions = 0; - // MAKELPARAM isn't provided by winapi yet. - let ptr = &mut packed_dimensions as *mut LPARAM as *mut WORD; - *ptr.offset(0) = width as WORD; - *ptr.offset(1) = height as WORD; - winuser::PostMessageW( - real_window.0, - *INITIAL_DPI_MSG_ID, - dpi as WPARAM, - packed_dimensions, - ); - } // making the window transparent if attributes.transparent && !pl_attribs.no_redirection_bitmap { @@ -758,7 +651,6 @@ unsafe fn init( } } - window_flags.set(WindowFlags::VISIBLE, attributes.visible); window_flags.set(WindowFlags::MAXIMIZED, attributes.maximized); let window_state = { @@ -776,15 +668,17 @@ unsafe fn init( thread_executor: event_loop.create_thread_executor(), }; + let dimensions = attributes + .inner_size + .unwrap_or_else(|| PhysicalSize::new(1024, 768).into()); + win.set_inner_size(dimensions); + win.set_visible(attributes.visible); + if let Some(_) = attributes.fullscreen { win.set_fullscreen(attributes.fullscreen); force_window_active(win.window.0); } - if let Some(dimensions) = attributes.inner_size { - win.set_inner_size(dimensions); - } - Ok(win) } diff --git a/src/platform_impl/windows/window_state.rs b/src/platform_impl/windows/window_state.rs index 22d5ae0675..a76dfb2b34 100644 --- a/src/platform_impl/windows/window_state.rs +++ b/src/platform_impl/windows/window_state.rs @@ -1,5 +1,5 @@ use crate::{ - dpi::LogicalSize, + dpi::Size, monitor::MonitorHandle, platform_impl::platform::{event_loop, icon::WinIcon, util}, window::{CursorIcon, WindowAttributes}, @@ -20,8 +20,8 @@ pub struct WindowState { pub mouse: MouseProperties, /// Used by `WM_GETMINMAXINFO`. - pub min_size: Option, - pub max_size: Option, + pub min_size: Option, + pub max_size: Option, pub window_icon: Option, pub taskbar_icon: Option, diff --git a/src/window.rs b/src/window.rs index 19ef78a546..23a52f4aad 100644 --- a/src/window.rs +++ b/src/window.rs @@ -2,7 +2,7 @@ use std::fmt; use crate::{ - dpi::{LogicalPosition, LogicalSize}, + dpi::{LogicalSize, PhysicalPosition, PhysicalSize, Position, Size}, error::{ExternalError, NotSupportedError, OsError}, event_loop::EventLoopWindowTarget, monitor::{AvailableMonitorsIter, MonitorHandle}, @@ -90,17 +90,17 @@ pub struct WindowAttributes { /// used. /// /// The default is `None`. - pub inner_size: Option, + pub inner_size: Option, /// The minimum dimensions a window can be, If this is `None`, the window will have no minimum dimensions (aside from reserved). /// /// The default is `None`. - pub min_inner_size: Option, + pub min_inner_size: Option, /// The maximum dimensions a window can be, If this is `None`, the maximum will have no maximum or will be set to the primary monitor's dimensions by the platform. /// /// The default is `None`. - pub max_inner_size: Option, + pub max_inner_size: Option, /// Whether the window is resizable or not. /// @@ -180,22 +180,22 @@ impl WindowBuilder { /// Requests the window to be of specific dimensions. #[inline] - pub fn with_inner_size(mut self, size: LogicalSize) -> WindowBuilder { - self.window.inner_size = Some(size); + pub fn with_inner_size>(mut self, size: S) -> WindowBuilder { + self.window.inner_size = Some(size.into()); self } /// Sets a minimum dimension size for the window #[inline] - pub fn with_min_inner_size(mut self, min_size: LogicalSize) -> WindowBuilder { - self.window.min_inner_size = Some(min_size); + pub fn with_min_inner_size>(mut self, min_size: S) -> WindowBuilder { + self.window.min_inner_size = Some(min_size.into()); self } /// Sets a maximum dimension size for the window #[inline] - pub fn with_max_inner_size(mut self, max_size: LogicalSize) -> WindowBuilder { - self.window.max_inner_size = Some(max_size); + pub fn with_max_inner_size>(mut self, max_size: S) -> WindowBuilder { + self.window.max_inner_size = Some(max_size.into()); self } @@ -294,11 +294,10 @@ impl WindowBuilder { ) -> Result { self.window.inner_size = Some(self.window.inner_size.unwrap_or_else(|| { if let Some(ref monitor) = self.window.fullscreen { - // resizing the window to the dimensions of the monitor when fullscreen - LogicalSize::from_physical(monitor.size(), monitor.hidpi_factor()) // DPI factor applies here since this is a borderless window and not real fullscreen + Size::new(monitor.size()) } else { // default dimensions - (1024, 768).into() + Size::new(LogicalSize::new(1024.0, 768.0)) } })); @@ -384,7 +383,7 @@ impl Window { /// /// [safe area]: https://developer.apple.com/documentation/uikit/uiview/2891103-safeareainsets?language=objc #[inline] - pub fn inner_position(&self) -> Result { + pub fn inner_position(&self) -> Result { self.window.inner_position() } @@ -403,7 +402,7 @@ impl Window { /// - **iOS:** Can only be called on the main thread. Returns the top left coordinates of the /// window in the screen space coordinate system. #[inline] - pub fn outer_position(&self) -> Result { + pub fn outer_position(&self) -> Result { self.window.outer_position() } @@ -418,24 +417,22 @@ impl Window { /// - **iOS:** Can only be called on the main thread. Sets the top left coordinates of the /// window in the screen space coordinate system. #[inline] - pub fn set_outer_position(&self, position: LogicalPosition) { - self.window.set_outer_position(position) + pub fn set_outer_position>(&self, position: P) { + self.window.set_outer_position(position.into()) } /// Returns the logical size of the window's client area. /// /// The client area is the content of the window, excluding the title bar and borders. /// - /// Converting the returned `LogicalSize` to `PhysicalSize` produces the size your framebuffer should be. - /// /// ## Platform-specific /// - /// - **iOS:** Can only be called on the main thread. Returns the `LogicalSize` of the window's + /// - **iOS:** Can only be called on the main thread. Returns the `PhysicalSize` of the window's /// [safe area] in screen space coordinates. /// /// [safe area]: https://developer.apple.com/documentation/uikit/uiview/2891103-safeareainsets?language=objc #[inline] - pub fn inner_size(&self) -> LogicalSize { + pub fn inner_size(&self) -> PhysicalSize { self.window.inner_size() } @@ -448,8 +445,8 @@ impl Window { /// - **iOS:** Unimplemented. Currently this panics, as it's not clear what `set_inner_size` /// would mean for iOS. #[inline] - pub fn set_inner_size(&self, size: LogicalSize) { - self.window.set_inner_size(size) + pub fn set_inner_size>(&self, size: S) { + self.window.set_inner_size(size.into()) } /// Returns the logical size of the entire window. @@ -459,10 +456,10 @@ impl Window { /// /// ## Platform-specific /// - /// - **iOS:** Can only be called on the main thread. Returns the `LogicalSize` of the window in + /// - **iOS:** Can only be called on the main thread. Returns the `PhysicalSize` of the window in /// screen space coordinates. #[inline] - pub fn outer_size(&self) -> LogicalSize { + pub fn outer_size(&self) -> PhysicalSize { self.window.outer_size() } @@ -472,8 +469,8 @@ impl Window { /// /// - **iOS:** Has no effect. #[inline] - pub fn set_min_inner_size(&self, dimensions: Option) { - self.window.set_min_inner_size(dimensions) + pub fn set_min_inner_size>(&self, min_size: Option) { + self.window.set_min_inner_size(min_size.map(|s| s.into())) } /// Sets a maximum dimension size for the window. @@ -482,8 +479,8 @@ impl Window { /// /// - **iOS:** Has no effect. #[inline] - pub fn set_max_inner_size(&self, dimensions: Option) { - self.window.set_max_inner_size(dimensions) + pub fn set_max_inner_size>(&self, max_size: Option) { + self.window.set_max_inner_size(max_size.map(|s| s.into())) } } @@ -602,8 +599,8 @@ impl Window { /// /// **iOS:** Has no effect. #[inline] - pub fn set_ime_position(&self, position: LogicalPosition) { - self.window.set_ime_position(position) + pub fn set_ime_position>(&self, position: P) { + self.window.set_ime_position(position.into()) } } @@ -626,8 +623,8 @@ impl Window { /// /// - **iOS:** Always returns an `Err`. #[inline] - pub fn set_cursor_position(&self, position: LogicalPosition) -> Result<(), ExternalError> { - self.window.set_cursor_position(position) + pub fn set_cursor_position>(&self, position: P) -> Result<(), ExternalError> { + self.window.set_cursor_position(position.into()) } /// Grabs the cursor, preventing it from leaving the window. From c3c12f43206befe965adf20244b804f2dfb48d0b Mon Sep 17 00:00:00 2001 From: Vladimir Bogaevsky Date: Tue, 25 Jun 2019 00:18:22 +0300 Subject: [PATCH 02/25] fix app_state errors --- src/platform_impl/macos/app_state.rs | 33 ++++++++++++++-------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/src/platform_impl/macos/app_state.rs b/src/platform_impl/macos/app_state.rs index 470cf9964b..f3f9f504a2 100644 --- a/src/platform_impl/macos/app_state.rs +++ b/src/platform_impl/macos/app_state.rs @@ -23,8 +23,8 @@ lazy_static! { static ref HANDLER: Handler = Default::default(); } -impl Event { - fn userify(self) -> Event { +impl<'a, Never> Event<'a, Never> { + fn userify(self) -> Event<'a, T> { self.map_nonuser_event() // `Never` can't be constructed, so the `UserEvent` variant can't // be present here. @@ -33,7 +33,8 @@ impl Event { } pub trait EventHandler: Debug { - fn handle_nonuser_event(&mut self, event: Event, control_flow: &mut ControlFlow); + // Not sure probably it should accept Event<'static, Never> + fn handle_nonuser_event(&mut self, event: Event<'_, Never>, control_flow: &mut ControlFlow); fn handle_user_events(&mut self, control_flow: &mut ControlFlow); } @@ -54,10 +55,10 @@ impl Debug for EventLoopHandler { impl EventHandler for EventLoopHandler where - F: 'static + FnMut(Event, &RootWindowTarget, &mut ControlFlow), + F: 'static + FnMut(Event<'_, T>, &RootWindowTarget, &mut ControlFlow), T: 'static, { - fn handle_nonuser_event(&mut self, event: Event, control_flow: &mut ControlFlow) { + fn handle_nonuser_event(&mut self, event: Event<'_, Never>, control_flow: &mut ControlFlow) { (self.callback)(event.userify(), &self.window_target, control_flow); self.will_exit |= *control_flow == ControlFlow::Exit; if self.will_exit { @@ -86,8 +87,8 @@ struct Handler { control_flow_prev: Mutex, start_time: Mutex>, callback: Mutex>>, - pending_events: Mutex>>, - deferred_events: Mutex>>, + pending_events: Mutex>>, + deferred_events: Mutex>>, pending_redraw: Mutex>, waker: Mutex, } @@ -96,11 +97,11 @@ unsafe impl Send for Handler {} unsafe impl Sync for Handler {} impl Handler { - fn events<'a>(&'a self) -> MutexGuard<'a, VecDeque>> { + fn events<'a>(&'a self) -> MutexGuard<'a, VecDeque>> { self.pending_events.lock().unwrap() } - fn deferred<'a>(&'a self) -> MutexGuard<'a, VecDeque>> { + fn deferred<'a>(&'a self) -> MutexGuard<'a, VecDeque>> { self.deferred_events.lock().unwrap() } @@ -144,11 +145,11 @@ impl Handler { *self.start_time.lock().unwrap() = Some(Instant::now()); } - fn take_events(&self) -> VecDeque> { + fn take_events(&self) -> VecDeque> { mem::replace(&mut *self.events(), Default::default()) } - fn take_deferred(&self) -> VecDeque> { + fn take_deferred(&self) -> VecDeque> { mem::replace(&mut *self.deferred(), Default::default()) } @@ -164,7 +165,7 @@ impl Handler { self.in_callback.store(in_callback, Ordering::Release); } - fn handle_nonuser_event(&self, event: Event) { + fn handle_nonuser_event(&self, event: Event<'_, Never>) { if let Some(ref mut callback) = *self.callback.lock().unwrap() { callback.handle_nonuser_event(event, &mut *self.control_flow.lock().unwrap()); } @@ -182,7 +183,7 @@ pub enum AppState {} impl AppState { pub fn set_callback(callback: F, window_target: RootWindowTarget) where - F: 'static + FnMut(Event, &RootWindowTarget, &mut ControlFlow), + F: 'static + FnMut(Event<'_, T>, &RootWindowTarget, &mut ControlFlow), T: 'static, { *HANDLER.callback.lock().unwrap() = Some(Box::new(EventLoopHandler { @@ -247,21 +248,21 @@ impl AppState { } } - pub fn queue_event(event: Event) { + pub fn queue_event(event: Event<'static, Never>) { if !unsafe { msg_send![class!(NSThread), isMainThread] } { panic!("Event queued from different thread: {:#?}", event); } HANDLER.events().push_back(event); } - pub fn queue_events(mut events: VecDeque>) { + pub fn queue_events(mut events: VecDeque>) { if !unsafe { msg_send![class!(NSThread), isMainThread] } { panic!("Events queued from different thread: {:#?}", events); } HANDLER.events().append(&mut events); } - pub fn send_event_immediately(event: Event) { + pub fn send_event_immediately(event: Event<'static, Never>) { if !unsafe { msg_send![class!(NSThread), isMainThread] } { panic!("Event sent from different thread: {:#?}", event); } From fec2f805015dfaf5cb90259a9971e09e4aac1bc3 Mon Sep 17 00:00:00 2001 From: Vladimir Bogaevsky Date: Tue, 25 Jun 2019 23:17:38 +0300 Subject: [PATCH 03/25] fixes hidpi related errors in window_delegate --- Cargo.toml | 2 +- src/platform_impl/macos/event.rs | 2 +- src/platform_impl/macos/event_loop.rs | 4 +-- src/platform_impl/macos/window_delegate.rs | 41 ++++++++++++++-------- 4 files changed, 30 insertions(+), 19 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 19a5e01f02..62ced1ee01 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,7 +37,7 @@ core-foundation = "0.6" core-graphics = "0.17.3" core-video-sys = "0.1.2" dispatch = "0.1.4" -objc = "0.2.3" +objc = "0.2.6" [target.'cfg(target_os = "windows")'.dependencies] bitflags = "1" diff --git a/src/platform_impl/macos/event.rs b/src/platform_impl/macos/event.rs index 02d6b9c266..41787bb4e9 100644 --- a/src/platform_impl/macos/event.rs +++ b/src/platform_impl/macos/event.rs @@ -244,7 +244,7 @@ pub unsafe fn modifier_event( ns_event: id, keymask: NSEventModifierFlags, was_key_pressed: bool, -) -> Option { +) -> Option> { if !was_key_pressed && NSEvent::modifierFlags(ns_event).contains(keymask) || was_key_pressed && !NSEvent::modifierFlags(ns_event).contains(keymask) { diff --git a/src/platform_impl/macos/event_loop.rs b/src/platform_impl/macos/event_loop.rs index 2ad17e1d1d..e904b9bdb9 100644 --- a/src/platform_impl/macos/event_loop.rs +++ b/src/platform_impl/macos/event_loop.rs @@ -83,7 +83,7 @@ impl EventLoop { pub fn run(self, callback: F) -> ! where - F: 'static + FnMut(Event, &RootWindowTarget, &mut ControlFlow), + F: 'static + FnMut(Event<'_, T>, &RootWindowTarget, &mut ControlFlow), { unsafe { let _pool = NSAutoreleasePool::new(nil); @@ -98,7 +98,7 @@ impl EventLoop { pub fn run_return(&mut self, _callback: F) where - F: FnMut(Event, &RootWindowTarget, &mut ControlFlow), + F: FnMut(Event<'_, T>, &RootWindowTarget, &mut ControlFlow), { unimplemented!(); } diff --git a/src/platform_impl/macos/window_delegate.rs b/src/platform_impl/macos/window_delegate.rs index c9680d892a..d894d04a97 100644 --- a/src/platform_impl/macos/window_delegate.rs +++ b/src/platform_impl/macos/window_delegate.rs @@ -15,7 +15,7 @@ use objc::{ }; use crate::{ - dpi::LogicalSize, + dpi::{ LogicalSize, PhysicalSize }, event::{Event, WindowEvent}, platform_impl::platform::{ app_state::AppState, @@ -47,7 +47,7 @@ pub struct WindowDelegateState { impl WindowDelegateState { pub fn new(window: &Arc, initial_fullscreen: bool) -> Self { - let dpi_factor = window.hidpi_factor(); + let hidpi_factor = window.hidpi_factor(); let mut delegate_state = WindowDelegateState { ns_window: window.ns_window.clone(), @@ -55,11 +55,14 @@ impl WindowDelegateState { window: Arc::downgrade(&window), initial_fullscreen, previous_position: None, - previous_dpi_factor: dpi_factor, + previous_dpi_factor: hidpi_factor, }; - if dpi_factor != 1.0 { - delegate_state.emit_event(WindowEvent::HiDpiFactorChanged(dpi_factor)); + if hidpi_factor != 1.0 { + let new_inner_size = &mut Some(window.inner_size().to_physical(hidpi_factor)); + delegate_state.emit_event( + WindowEvent::HiDpiFactorChanged { hidpi_factor, new_inner_size } + ); delegate_state.emit_resize_event(); } @@ -73,7 +76,7 @@ impl WindowDelegateState { self.window.upgrade().map(|ref window| callback(window)) } - pub fn emit_event(&mut self, event: WindowEvent) { + pub fn emit_event(&mut self, event: WindowEvent<'static>) { let event = Event::WindowEvent { window_id: WindowId(get_window_id(*self.ns_window)), event, @@ -84,9 +87,11 @@ impl WindowDelegateState { pub fn emit_resize_event(&mut self) { let rect = unsafe { NSView::frame(*self.ns_view) }; let size = LogicalSize::new(rect.size.width as f64, rect.size.height as f64); + let hidpi_factor = self.previous_dpi_factor; + let physical_size = size.to_physical(hidpi_factor); let event = Event::WindowEvent { window_id: WindowId(get_window_id(*self.ns_window)), - event: WindowEvent::Resized(size), + event: WindowEvent::Resized(physical_size), }; AppState::send_event_immediately(event); } @@ -275,10 +280,13 @@ extern "C" fn window_did_move(this: &Object, _: Sel, _: id) { extern "C" fn window_did_change_screen(this: &Object, _: Sel, _: id) { trace!("Triggered `windowDidChangeScreen:`"); with_state(this, |state| { - let dpi_factor = unsafe { NSWindow::backingScaleFactor(*state.ns_window) } as f64; - if state.previous_dpi_factor != dpi_factor { - state.previous_dpi_factor = dpi_factor; - state.emit_event(WindowEvent::HiDpiFactorChanged(dpi_factor)); + let hidpi_factor = unsafe { NSWindow::backingScaleFactor(*state.ns_window) } as f64; + let ns_size = unsafe { NSWindow::contentSize(*state.ns_window) }; + let new_inner_size = + &mut Some(PhysicalSize::new(ns_size.width as u32, ns_size.height as u32)); + if state.previous_dpi_factor != hidpi_factor { + state.previous_dpi_factor = hidpi_factor; + state.emit_event(WindowEvent::HiDpiFactorChanged { hidpi_factor, new_inner_size }); state.emit_resize_event(); } }); @@ -289,10 +297,13 @@ extern "C" fn window_did_change_screen(this: &Object, _: Sel, _: id) { extern "C" fn window_did_change_backing_properties(this: &Object, _: Sel, _: id) { trace!("Triggered `windowDidChangeBackingProperties:`"); with_state(this, |state| { - let dpi_factor = unsafe { NSWindow::backingScaleFactor(*state.ns_window) } as f64; - if state.previous_dpi_factor != dpi_factor { - state.previous_dpi_factor = dpi_factor; - state.emit_event(WindowEvent::HiDpiFactorChanged(dpi_factor)); + let hidpi_factor = unsafe { NSWindow::backingScaleFactor(*state.ns_window) } as f64; + let ns_size = unsafe { NSWindow::contentSize(*state.ns_window) }; + let new_inner_size = + &mut Some(PhysicalSize::new(ns_size.width as u32, ns_size.height as u32)); + if state.previous_dpi_factor != hidpi_factor { + state.previous_dpi_factor = hidpi_factor; + state.emit_event(WindowEvent::HiDpiFactorChanged { hidpi_factor, new_inner_size }); state.emit_resize_event(); } }); From 4213c7a1d25d220aecc434547be78389de708780 Mon Sep 17 00:00:00 2001 From: Vladimir Bogaevsky Date: Tue, 25 Jun 2019 23:43:28 +0300 Subject: [PATCH 04/25] fix bad merge --- src/event.rs | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/src/event.rs b/src/event.rs index 6e46709a26..65a38cccdb 100644 --- a/src/event.rs +++ b/src/event.rs @@ -76,25 +76,6 @@ impl<'a, T> Event<'a, T> { Resumed => Some(Resumed), } } - - /// If the event doesn't contain a reference, turn it into an event with a `'static` lifetime. - /// Otherwise, return `None`. - pub fn to_static(self) -> Option> { - use self::Event::*; - match self { - WindowEvent { window_id, event } => { - event - .to_static() - .map(|event| WindowEvent { window_id, event }) - }, - UserEvent(e) => Some(UserEvent(e)), - DeviceEvent { device_id, event } => Some(DeviceEvent { device_id, event }), - NewEvents(cause) => Some(NewEvents(cause)), - EventsCleared => Some(EventsCleared), - LoopDestroyed => Some(LoopDestroyed), - Suspended(suspended) => Some(Suspended(suspended)), - } - } } /// Describes the reason the event loop is resuming. From 90ed1e40fdfb2025baddb020b8f576ecd964a40c Mon Sep 17 00:00:00 2001 From: Vladimir Bogaevsky Date: Thu, 27 Jun 2019 00:58:00 +0300 Subject: [PATCH 05/25] dpi_factor edits in window_delegate --- src/platform_impl/macos/window.rs | 27 ++++++++++++++++------ src/platform_impl/macos/window_delegate.rs | 12 ++++++---- 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/src/platform_impl/macos/window.rs b/src/platform_impl/macos/window.rs index 67469b126e..8436790ef5 100644 --- a/src/platform_impl/macos/window.rs +++ b/src/platform_impl/macos/window.rs @@ -122,10 +122,17 @@ fn create_window( let frame = match screen { Some(screen) => appkit::NSScreen::frame(screen), None => { - let (width, height) = attrs - .inner_size - .map(|logical| (logical.width, logical.height)) - .unwrap_or_else(|| (800.0, 600.0)); + // Not sure what dpi_factor we need here. + // If i understand correctly, here we fail to create NSScreen frame, so we've got + // no dpi_factor + let hidpi_factor = 1.0; + 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)) } }; @@ -315,13 +322,19 @@ impl UnownedWindow { } ns_app.activateIgnoringOtherApps_(YES); - + let dpi_factor = NSWindow::backingScaleFactor(*ns_window) as f64; win_attribs .min_inner_size - .map(|dim| set_min_inner_size(*ns_window, dim)); + .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| set_max_inner_size(*ns_window, dim)); + .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. diff --git a/src/platform_impl/macos/window_delegate.rs b/src/platform_impl/macos/window_delegate.rs index d894d04a97..2616165abd 100644 --- a/src/platform_impl/macos/window_delegate.rs +++ b/src/platform_impl/macos/window_delegate.rs @@ -7,7 +7,7 @@ use std::{ use cocoa::{ appkit::{self, NSView, NSWindow}, base::{id, nil}, - foundation::NSAutoreleasePool, + foundation::{NSAutoreleasePool, NSSize}, }; use objc::{ declare::ClassDecl, @@ -225,6 +225,10 @@ extern "C" fn dealloc(this: &Object, _sel: Sel) { }); } +fn inner_size(size: NSSize, dpi_factor: f64) -> PhysicalSize { + LogicalSize::new(size.width, size.height).to_physical(dpi_factor) +} + extern "C" fn init_with_winit(this: &Object, _sel: Sel, state: *mut c_void) -> id { unsafe { let this: id = msg_send![this, init]; @@ -282,8 +286,7 @@ extern "C" fn window_did_change_screen(this: &Object, _: Sel, _: id) { with_state(this, |state| { let hidpi_factor = unsafe { NSWindow::backingScaleFactor(*state.ns_window) } as f64; let ns_size = unsafe { NSWindow::contentSize(*state.ns_window) }; - let new_inner_size = - &mut Some(PhysicalSize::new(ns_size.width as u32, ns_size.height as u32)); + let new_inner_size = &mut Some(inner_size(ns_size, hidpi_factor)); if state.previous_dpi_factor != hidpi_factor { state.previous_dpi_factor = hidpi_factor; state.emit_event(WindowEvent::HiDpiFactorChanged { hidpi_factor, new_inner_size }); @@ -299,8 +302,7 @@ extern "C" fn window_did_change_backing_properties(this: &Object, _: Sel, _: id) with_state(this, |state| { let hidpi_factor = unsafe { NSWindow::backingScaleFactor(*state.ns_window) } as f64; let ns_size = unsafe { NSWindow::contentSize(*state.ns_window) }; - let new_inner_size = - &mut Some(PhysicalSize::new(ns_size.width as u32, ns_size.height as u32)); + let new_inner_size = &mut Some(inner_size(ns_size, hidpi_factor)); if state.previous_dpi_factor != hidpi_factor { state.previous_dpi_factor = hidpi_factor; state.emit_event(WindowEvent::HiDpiFactorChanged { hidpi_factor, new_inner_size }); From 607e6c3aee63236b8f66bcf4f83bbb23f1bbd4c3 Mon Sep 17 00:00:00 2001 From: Vladimir Bogaevsky Date: Sat, 29 Jun 2019 02:29:32 +0300 Subject: [PATCH 06/25] fixes type and lifetime errors in window and window_delegate --- src/platform_impl/macos/window.rs | 69 ++++++++++++---------- src/platform_impl/macos/window_delegate.rs | 19 +++--- 2 files changed, 49 insertions(+), 39 deletions(-) diff --git a/src/platform_impl/macos/window.rs b/src/platform_impl/macos/window.rs index 8436790ef5..0527e568df 100644 --- a/src/platform_impl/macos/window.rs +++ b/src/platform_impl/macos/window.rs @@ -24,7 +24,7 @@ use objc::{ }; use crate::{ - dpi::{LogicalPosition, LogicalSize}, + dpi::{Position, PhysicalPosition, LogicalSize, PhysicalSize, Size, Size::Logical}, error::{ExternalError, NotSupportedError, OsError as RootOsError}, icon::Icon, monitor::MonitorHandle as RootMonitorHandle, @@ -428,27 +428,21 @@ impl UnownedWindow { AppState::queue_redraw(RootWindowId(self.id())); } - pub fn outer_position(&self) -> Result { + pub fn outer_position(&self) -> Result { let frame_rect = unsafe { NSWindow::frame(*self.ns_window) }; - Ok(( - frame_rect.origin.x as f64, - util::bottom_left_to_top_left(frame_rect), - ) - .into()) + Ok((frame_rect.origin.x as f64, util::bottom_left_to_top_left(frame_rect), ).into()) } - pub fn inner_position(&self) -> Result { + pub fn inner_position(&self) -> Result { let content_rect = unsafe { NSWindow::contentRectForFrameRect_(*self.ns_window, NSWindow::frame(*self.ns_window)) }; - Ok(( - content_rect.origin.x as f64, - util::bottom_left_to_top_left(content_rect), - ) - .into()) + Ok((content_rect.origin.x as f64, util::bottom_left_to_top_left(content_rect), ).into()) } - 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, @@ -464,35 +458,46 @@ 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) { + pub fn set_min_inner_size(&self, dimensions: Option) { 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) { + pub fn set_max_inner_size(&self, dimensions: Option) { 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: 0.0, height: 0.0 })); + let dpi_factor = self.hidpi_factor(); + set_max_inner_size(*self.ns_window, dimensions.to_logical(dpi_factor)); } } @@ -558,12 +563,14 @@ impl UnownedWindow { #[inline] pub fn set_cursor_position( &self, - cursor_position: LogicalPosition, + cursor_position: Position, ) -> Result<(), ExternalError> { let window_position = self.inner_position().unwrap(); + let dpi_factor = self.hidpi_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))))?; @@ -743,7 +750,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, diff --git a/src/platform_impl/macos/window_delegate.rs b/src/platform_impl/macos/window_delegate.rs index 2616165abd..d46ce4857c 100644 --- a/src/platform_impl/macos/window_delegate.rs +++ b/src/platform_impl/macos/window_delegate.rs @@ -45,7 +45,7 @@ pub struct WindowDelegateState { previous_dpi_factor: f64, } -impl WindowDelegateState { +impl<'a> WindowDelegateState { pub fn new(window: &Arc, initial_fullscreen: bool) -> Self { let hidpi_factor = window.hidpi_factor(); @@ -59,10 +59,9 @@ impl WindowDelegateState { }; if hidpi_factor != 1.0 { - let new_inner_size = &mut Some(window.inner_size().to_physical(hidpi_factor)); - delegate_state.emit_event( - WindowEvent::HiDpiFactorChanged { hidpi_factor, new_inner_size } - ); + delegate_state.emit_event(WindowEvent::HiDpiFactorChanged { + hidpi_factor, new_inner_size: &mut Some(window.inner_size()) + }.to_static().unwrap()); delegate_state.emit_resize_event(); } @@ -286,10 +285,11 @@ extern "C" fn window_did_change_screen(this: &Object, _: Sel, _: id) { with_state(this, |state| { let hidpi_factor = unsafe { NSWindow::backingScaleFactor(*state.ns_window) } as f64; let ns_size = unsafe { NSWindow::contentSize(*state.ns_window) }; - let new_inner_size = &mut Some(inner_size(ns_size, hidpi_factor)); if state.previous_dpi_factor != hidpi_factor { state.previous_dpi_factor = hidpi_factor; - state.emit_event(WindowEvent::HiDpiFactorChanged { hidpi_factor, new_inner_size }); + state.emit_event(WindowEvent::HiDpiFactorChanged { + hidpi_factor, new_inner_size: &mut Some(inner_size(ns_size, hidpi_factor)) + }.to_static().unwrap()); state.emit_resize_event(); } }); @@ -302,10 +302,11 @@ extern "C" fn window_did_change_backing_properties(this: &Object, _: Sel, _: id) with_state(this, |state| { let hidpi_factor = unsafe { NSWindow::backingScaleFactor(*state.ns_window) } as f64; let ns_size = unsafe { NSWindow::contentSize(*state.ns_window) }; - let new_inner_size = &mut Some(inner_size(ns_size, hidpi_factor)); if state.previous_dpi_factor != hidpi_factor { state.previous_dpi_factor = hidpi_factor; - state.emit_event(WindowEvent::HiDpiFactorChanged { hidpi_factor, new_inner_size }); + state.emit_event(WindowEvent::HiDpiFactorChanged { + hidpi_factor, new_inner_size: &mut Some(inner_size(ns_size, hidpi_factor)) + }.to_static().unwrap()); state.emit_resize_event(); } }); From 97ebda66860018e209b3c92655e3ff1c518dd43f Mon Sep 17 00:00:00 2001 From: Vladimir Bogaevsky Date: Sat, 29 Jun 2019 02:56:19 +0300 Subject: [PATCH 07/25] applies fmt --- src/platform_impl/macos/window.rs | 55 ++++++++++++---------- src/platform_impl/macos/window_delegate.rs | 35 ++++++++++---- 2 files changed, 55 insertions(+), 35 deletions(-) diff --git a/src/platform_impl/macos/window.rs b/src/platform_impl/macos/window.rs index 0527e568df..5c729ebb60 100644 --- a/src/platform_impl/macos/window.rs +++ b/src/platform_impl/macos/window.rs @@ -24,7 +24,7 @@ use objc::{ }; use crate::{ - dpi::{Position, PhysicalPosition, LogicalSize, PhysicalSize, Size, Size::Logical}, + dpi::{LogicalSize, PhysicalPosition, PhysicalSize, Position, Size, Size::Logical}, error::{ExternalError, NotSupportedError, OsError as RootOsError}, icon::Icon, monitor::MonitorHandle as RootMonitorHandle, @@ -125,12 +125,12 @@ fn create_window( // Not sure what dpi_factor we need here. // If i understand correctly, here we fail to create NSScreen frame, so we've got // no dpi_factor - let hidpi_factor = 1.0; + let hidpi_factor = 1.0; 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)) @@ -323,18 +323,14 @@ impl UnownedWindow { ns_app.activateIgnoringOtherApps_(YES); let dpi_factor = NSWindow::backingScaleFactor(*ns_window) as f64; - 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) - }); + 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. @@ -430,14 +426,22 @@ impl UnownedWindow { pub fn outer_position(&self) -> Result { let frame_rect = unsafe { NSWindow::frame(*self.ns_window) }; - Ok((frame_rect.origin.x as f64, util::bottom_left_to_top_left(frame_rect), ).into()) + Ok(( + frame_rect.origin.x as f64, + util::bottom_left_to_top_left(frame_rect), + ) + .into()) } pub fn inner_position(&self) -> Result { let content_rect = unsafe { NSWindow::contentRectForFrameRect_(*self.ns_window, NSWindow::frame(*self.ns_window)) }; - Ok((content_rect.origin.x as f64, util::bottom_left_to_top_left(content_rect), ).into()) + Ok(( + content_rect.origin.x as f64, + util::bottom_left_to_top_left(content_rect), + ) + .into()) } pub fn set_outer_position(&self, position: Position) { @@ -485,8 +489,10 @@ impl UnownedWindow { pub fn set_min_inner_size(&self, dimensions: Option) { unsafe { - let dimensions = - dimensions.unwrap_or(Logical(LogicalSize { width: 0.0, height: 0.0 })); + 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)); } @@ -494,8 +500,10 @@ impl UnownedWindow { pub fn set_max_inner_size(&self, dimensions: Option) { unsafe { - let dimensions = - dimensions.unwrap_or(Logical(LogicalSize { width: 0.0, height: 0.0 })); + let dimensions = dimensions.unwrap_or(Logical(LogicalSize { + width: 0.0, + height: 0.0, + })); let dpi_factor = self.hidpi_factor(); set_max_inner_size(*self.ns_window, dimensions.to_logical(dpi_factor)); } @@ -561,10 +569,7 @@ impl UnownedWindow { } #[inline] - pub fn set_cursor_position( - &self, - cursor_position: Position, - ) -> Result<(), ExternalError> { + pub fn set_cursor_position(&self, cursor_position: Position) -> Result<(), ExternalError> { let window_position = self.inner_position().unwrap(); let dpi_factor = self.hidpi_factor(); let logical_cursor_position = cursor_position.to_logical(dpi_factor); diff --git a/src/platform_impl/macos/window_delegate.rs b/src/platform_impl/macos/window_delegate.rs index d46ce4857c..491d751a93 100644 --- a/src/platform_impl/macos/window_delegate.rs +++ b/src/platform_impl/macos/window_delegate.rs @@ -15,7 +15,7 @@ use objc::{ }; use crate::{ - dpi::{ LogicalSize, PhysicalSize }, + dpi::{LogicalSize, PhysicalSize}, event::{Event, WindowEvent}, platform_impl::platform::{ app_state::AppState, @@ -59,9 +59,14 @@ impl<'a> WindowDelegateState { }; if hidpi_factor != 1.0 { - delegate_state.emit_event(WindowEvent::HiDpiFactorChanged { - hidpi_factor, new_inner_size: &mut Some(window.inner_size()) - }.to_static().unwrap()); + delegate_state.emit_event( + WindowEvent::HiDpiFactorChanged { + hidpi_factor, + new_inner_size: &mut Some(window.inner_size()), + } + .to_static() + .unwrap(), + ); delegate_state.emit_resize_event(); } @@ -287,9 +292,14 @@ extern "C" fn window_did_change_screen(this: &Object, _: Sel, _: id) { let ns_size = unsafe { NSWindow::contentSize(*state.ns_window) }; if state.previous_dpi_factor != hidpi_factor { state.previous_dpi_factor = hidpi_factor; - state.emit_event(WindowEvent::HiDpiFactorChanged { - hidpi_factor, new_inner_size: &mut Some(inner_size(ns_size, hidpi_factor)) - }.to_static().unwrap()); + state.emit_event( + WindowEvent::HiDpiFactorChanged { + hidpi_factor, + new_inner_size: &mut Some(inner_size(ns_size, hidpi_factor)), + } + .to_static() + .unwrap(), + ); state.emit_resize_event(); } }); @@ -304,9 +314,14 @@ extern "C" fn window_did_change_backing_properties(this: &Object, _: Sel, _: id) let ns_size = unsafe { NSWindow::contentSize(*state.ns_window) }; if state.previous_dpi_factor != hidpi_factor { state.previous_dpi_factor = hidpi_factor; - state.emit_event(WindowEvent::HiDpiFactorChanged { - hidpi_factor, new_inner_size: &mut Some(inner_size(ns_size, hidpi_factor)) - }.to_static().unwrap()); + state.emit_event( + WindowEvent::HiDpiFactorChanged { + hidpi_factor, + new_inner_size: &mut Some(inner_size(ns_size, hidpi_factor)), + } + .to_static() + .unwrap(), + ); state.emit_resize_event(); } }); From 7ac43a4e131f1600cf8cd61a141210c3996bd635 Mon Sep 17 00:00:00 2001 From: Vladimir Bogaevsky Date: Mon, 1 Jul 2019 01:57:42 +0300 Subject: [PATCH 08/25] complies with @aleksijuvani requested changes --- src/platform_impl/macos/window.rs | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/platform_impl/macos/window.rs b/src/platform_impl/macos/window.rs index 5c729ebb60..ac3d8ee725 100644 --- a/src/platform_impl/macos/window.rs +++ b/src/platform_impl/macos/window.rs @@ -24,7 +24,9 @@ use objc::{ }; use crate::{ - dpi::{LogicalSize, PhysicalPosition, PhysicalSize, Position, Size, Size::Logical}, + dpi::{ + LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize, Position, Size, Size::Logical, + }, error::{ExternalError, NotSupportedError, OsError as RootOsError}, icon::Icon, monitor::MonitorHandle as RootMonitorHandle, @@ -426,22 +428,24 @@ impl UnownedWindow { pub fn outer_position(&self) -> Result { 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 { 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: Position) { @@ -570,8 +574,9 @@ impl UnownedWindow { #[inline] pub fn set_cursor_position(&self, cursor_position: Position) -> Result<(), ExternalError> { - let window_position = self.inner_position().unwrap(); + 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: (logical_cursor_position.x + window_position.x) as CGFloat, From a3ecb4befe681677ecdc67a5519a405c23271d50 Mon Sep 17 00:00:00 2001 From: Vladimir Bogaevsky Date: Wed, 3 Jul 2019 02:07:11 +0300 Subject: [PATCH 09/25] modifies Handler lifetimes --- src/platform_impl/macos/app_state.rs | 24 +++++++-------- src/platform_impl/macos/window_delegate.rs | 34 +++++++++++++--------- 2 files changed, 33 insertions(+), 25 deletions(-) diff --git a/src/platform_impl/macos/app_state.rs b/src/platform_impl/macos/app_state.rs index 23637bd008..1c71e4e869 100644 --- a/src/platform_impl/macos/app_state.rs +++ b/src/platform_impl/macos/app_state.rs @@ -20,7 +20,7 @@ use crate::{ }; lazy_static! { - static ref HANDLER: Handler = Default::default(); + static ref HANDLER: Handler<'static> = Default::default(); } impl<'a, Never> Event<'a, Never> { @@ -80,36 +80,36 @@ where } #[derive(Default)] -struct Handler { +struct Handler<'a> { ready: AtomicBool, in_callback: AtomicBool, control_flow: Mutex, control_flow_prev: Mutex, start_time: Mutex>, callback: Mutex>>, - pending_events: Mutex>>, - deferred_events: Mutex>>, + pending_events: Mutex>>, + deferred_events: Mutex>>, pending_redraw: Mutex>, waker: Mutex, } -unsafe impl Send for Handler {} -unsafe impl Sync for Handler {} +unsafe impl<'a> Send for Handler<'a> {} +unsafe impl<'a> Sync for Handler<'a> {} -impl Handler { - fn events<'a>(&'a self) -> MutexGuard<'a, VecDeque>> { +impl<'a> Handler<'a> { + fn events(&self) -> MutexGuard<'_, VecDeque>> { self.pending_events.lock().unwrap() } - fn deferred<'a>(&'a self) -> MutexGuard<'a, VecDeque>> { + fn deferred(&self) -> MutexGuard<'_, VecDeque>> { self.deferred_events.lock().unwrap() } - fn redraw<'a>(&'a self) -> MutexGuard<'a, Vec> { + fn redraw(&self) -> MutexGuard<'_, Vec> { self.pending_redraw.lock().unwrap() } - fn waker<'a>(&'a self) -> MutexGuard<'a, EventLoopWaker> { + fn waker(&self) -> MutexGuard<'_, EventLoopWaker> { self.waker.lock().unwrap() } @@ -260,7 +260,7 @@ impl AppState { HANDLER.events().append(&mut events); } - pub fn send_event_immediately(event: Event<'static, Never>) { + pub fn send_event_immediately(event: Event<'_, Never>) { if !unsafe { msg_send![class!(NSThread), isMainThread] } { panic!("Event sent from different thread: {:#?}", event); } diff --git a/src/platform_impl/macos/window_delegate.rs b/src/platform_impl/macos/window_delegate.rs index 491d751a93..18254deb9f 100644 --- a/src/platform_impl/macos/window_delegate.rs +++ b/src/platform_impl/macos/window_delegate.rs @@ -25,7 +25,7 @@ use crate::{ window::WindowId, }; -pub struct WindowDelegateState { +pub struct WindowDelegateState<'a> { ns_window: IdRef, // never changes ns_view: IdRef, // never changes @@ -43,11 +43,14 @@ pub struct WindowDelegateState { // Used to prevent redundant events. previous_dpi_factor: f64, + + new_inner_rect_opt: &'a mut Option, } -impl<'a> WindowDelegateState { +impl<'a> WindowDelegateState<'a> { pub fn new(window: &Arc, initial_fullscreen: bool) -> Self { let hidpi_factor = window.hidpi_factor(); + let new_inner_rect_opt = window.inner_size(); let mut delegate_state = WindowDelegateState { ns_window: window.ns_window.clone(), @@ -56,17 +59,11 @@ impl<'a> WindowDelegateState { initial_fullscreen, previous_position: None, previous_dpi_factor: hidpi_factor, + new_inner_rect_opt: &mut Some(new_inner_rect_opt), }; if hidpi_factor != 1.0 { - delegate_state.emit_event( - WindowEvent::HiDpiFactorChanged { - hidpi_factor, - new_inner_size: &mut Some(window.inner_size()), - } - .to_static() - .unwrap(), - ); + delegate_state.emit_hidpi_factor_changed_event(); delegate_state.emit_resize_event(); } @@ -88,6 +85,17 @@ impl<'a> WindowDelegateState { AppState::queue_event(event); } + pub fn emit_hidpi_factor_changed_event(&mut self) { + let event = Event::WindowEvent { + window_id: WindowId(get_window_id(*self.ns_window)), + event: WindowEvent::HiDpiFactorChanged { + hidpi_factor: self.previous_dpi_factor, + new_inner_size: &mut self.new_inner_rect_opt, + }, + }; + AppState::send_event_immediately(event); + } + pub fn emit_resize_event(&mut self) { let rect = unsafe { NSView::frame(*self.ns_view) }; let size = LogicalSize::new(rect.size.width as f64, rect.size.height as f64); @@ -215,17 +223,17 @@ lazy_static! { // This function is definitely unsafe, but labeling that would increase // boilerplate and wouldn't really clarify anything... -fn with_state T, T>(this: &Object, callback: F) { +fn with_state) -> T, T>(this: &Object, callback: F) { let state_ptr = unsafe { let state_ptr: *mut c_void = *this.get_ivar("winitState"); - &mut *(state_ptr as *mut WindowDelegateState) + &mut *(state_ptr as *mut WindowDelegateState<'_>) }; callback(state_ptr); } extern "C" fn dealloc(this: &Object, _sel: Sel) { with_state(this, |state| unsafe { - Box::from_raw(state as *mut WindowDelegateState); + Box::from_raw(state as *mut WindowDelegateState<'_>); }); } From 5d029ab68fa030636840cbcc08595231694cc089 Mon Sep 17 00:00:00 2001 From: Vladimir Bogaevsky Date: Tue, 9 Jul 2019 21:18:00 +0300 Subject: [PATCH 10/25] fixes lifetime isues, adds propper handling for HiDpiChanged --- src/platform_impl/macos/app_state.rs | 26 ++++++++----- src/platform_impl/macos/window.rs | 10 ++--- src/platform_impl/macos/window_delegate.rs | 45 ++++++++-------------- 3 files changed, 35 insertions(+), 46 deletions(-) diff --git a/src/platform_impl/macos/app_state.rs b/src/platform_impl/macos/app_state.rs index 1c71e4e869..ff8f26d5ea 100644 --- a/src/platform_impl/macos/app_state.rs +++ b/src/platform_impl/macos/app_state.rs @@ -88,7 +88,8 @@ struct Handler<'a> { start_time: Mutex>, callback: Mutex>>, pending_events: Mutex>>, - deferred_events: Mutex>>, + // We don't need it any more. See line 270 + // deferred_events: Mutex>>, pending_redraw: Mutex>, waker: Mutex, } @@ -101,9 +102,10 @@ impl<'a> Handler<'a> { self.pending_events.lock().unwrap() } - fn deferred(&self) -> MutexGuard<'_, VecDeque>> { - self.deferred_events.lock().unwrap() - } + // We don't need it any more. + // fn deferred(&self) -> MutexGuard<'_, VecDeque>> { + // self.deferred_events.lock().unwrap() + // } fn redraw(&self) -> MutexGuard<'_, Vec> { self.pending_redraw.lock().unwrap() @@ -149,9 +151,10 @@ impl<'a> Handler<'a> { mem::replace(&mut *self.events(), Default::default()) } - fn take_deferred(&self) -> VecDeque> { - mem::replace(&mut *self.deferred(), Default::default()) - } + // We don't need it any more. + // fn take_deferred(&self) -> VecDeque> { + // mem::replace(&mut *self.deferred(), Default::default()) + // } fn should_redraw(&self) -> Vec { mem::replace(&mut *self.redraw(), Default::default()) @@ -264,12 +267,15 @@ impl AppState { if !unsafe { msg_send![class!(NSThread), isMainThread] } { panic!("Event sent from different thread: {:#?}", event); } - HANDLER.deferred().push_back(event); + // HANDLER.deferred().push_back(event); // Commenting this out due to unnecessity + // We check that events are sent here from the same thread so we do not need to process + // asynchronously, thus we do not need a VecDeque here if !HANDLER.get_in_callback() { HANDLER.set_in_callback(true); - for event in HANDLER.take_deferred() { + // Since we do not push_back, we don't need to take_deferred + // for event in HANDLER.take_deferred() { HANDLER.handle_nonuser_event(event); - } + // } HANDLER.set_in_callback(false); } } diff --git a/src/platform_impl/macos/window.rs b/src/platform_impl/macos/window.rs index ac3d8ee725..4203c2b665 100644 --- a/src/platform_impl/macos/window.rs +++ b/src/platform_impl/macos/window.rs @@ -117,17 +117,15 @@ fn create_window( let screen = match attrs.fullscreen { Some(ref monitor_id) => { let monitor_screen = monitor_id.inner.ns_screen(); - Some(monitor_screen.unwrap_or(appkit::NSScreen::mainScreen(nil))) + Some(monitor_screen.unwrap_or(NSScreen::mainScreen(nil))) } _ => None, }; let frame = match screen { - Some(screen) => appkit::NSScreen::frame(screen), + Some(screen) => NSScreen::frame(screen), None => { - // Not sure what dpi_factor we need here. - // If i understand correctly, here we fail to create NSScreen frame, so we've got - // no dpi_factor - let hidpi_factor = 1.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); diff --git a/src/platform_impl/macos/window_delegate.rs b/src/platform_impl/macos/window_delegate.rs index 18254deb9f..e7358ae30e 100644 --- a/src/platform_impl/macos/window_delegate.rs +++ b/src/platform_impl/macos/window_delegate.rs @@ -25,7 +25,7 @@ use crate::{ window::WindowId, }; -pub struct WindowDelegateState<'a> { +pub struct WindowDelegateState { ns_window: IdRef, // never changes ns_view: IdRef, // never changes @@ -43,14 +43,12 @@ pub struct WindowDelegateState<'a> { // Used to prevent redundant events. previous_dpi_factor: f64, - - new_inner_rect_opt: &'a mut Option, } -impl<'a> WindowDelegateState<'a> { +impl WindowDelegateState { pub fn new(window: &Arc, initial_fullscreen: bool) -> Self { let hidpi_factor = window.hidpi_factor(); - let new_inner_rect_opt = window.inner_size(); + let mut new_inner_rect_opt = Some(window.inner_size()); let mut delegate_state = WindowDelegateState { ns_window: window.ns_window.clone(), @@ -59,11 +57,10 @@ impl<'a> WindowDelegateState<'a> { initial_fullscreen, previous_position: None, previous_dpi_factor: hidpi_factor, - new_inner_rect_opt: &mut Some(new_inner_rect_opt), }; if hidpi_factor != 1.0 { - delegate_state.emit_hidpi_factor_changed_event(); + delegate_state.emit_hidpi_factor_changed_event(&mut new_inner_rect_opt); delegate_state.emit_resize_event(); } @@ -85,12 +82,12 @@ impl<'a> WindowDelegateState<'a> { AppState::queue_event(event); } - pub fn emit_hidpi_factor_changed_event(&mut self) { + pub fn emit_hidpi_factor_changed_event(&mut self, new_inner_rect_opt: &mut Option) { let event = Event::WindowEvent { window_id: WindowId(get_window_id(*self.ns_window)), event: WindowEvent::HiDpiFactorChanged { hidpi_factor: self.previous_dpi_factor, - new_inner_size: &mut self.new_inner_rect_opt, + new_inner_size: new_inner_rect_opt, }, }; AppState::send_event_immediately(event); @@ -223,17 +220,17 @@ lazy_static! { // This function is definitely unsafe, but labeling that would increase // boilerplate and wouldn't really clarify anything... -fn with_state) -> T, T>(this: &Object, callback: F) { +fn with_state T, T>(this: &Object, callback: F) { let state_ptr = unsafe { let state_ptr: *mut c_void = *this.get_ivar("winitState"); - &mut *(state_ptr as *mut WindowDelegateState<'_>) + &mut *(state_ptr as *mut WindowDelegateState) }; callback(state_ptr); } extern "C" fn dealloc(this: &Object, _sel: Sel) { with_state(this, |state| unsafe { - Box::from_raw(state as *mut WindowDelegateState<'_>); + Box::from_raw(state as *mut WindowDelegateState); }); } @@ -297,17 +294,11 @@ extern "C" fn window_did_change_screen(this: &Object, _: Sel, _: id) { trace!("Triggered `windowDidChangeScreen:`"); with_state(this, |state| { let hidpi_factor = unsafe { NSWindow::backingScaleFactor(*state.ns_window) } as f64; - let ns_size = unsafe { NSWindow::contentSize(*state.ns_window) }; + let ns_size = unsafe { NSWindow::frame(*state.ns_window).size }; + let new_size = inner_size(ns_size, hidpi_factor); if state.previous_dpi_factor != hidpi_factor { state.previous_dpi_factor = hidpi_factor; - state.emit_event( - WindowEvent::HiDpiFactorChanged { - hidpi_factor, - new_inner_size: &mut Some(inner_size(ns_size, hidpi_factor)), - } - .to_static() - .unwrap(), - ); + state.emit_hidpi_factor_changed_event(&mut Some(new_size)); state.emit_resize_event(); } }); @@ -319,17 +310,11 @@ extern "C" fn window_did_change_backing_properties(this: &Object, _: Sel, _: id) trace!("Triggered `windowDidChangeBackingProperties:`"); with_state(this, |state| { let hidpi_factor = unsafe { NSWindow::backingScaleFactor(*state.ns_window) } as f64; - let ns_size = unsafe { NSWindow::contentSize(*state.ns_window) }; + let ns_size = unsafe { NSWindow::frame(*state.ns_window).size }; + let new_size = inner_size(ns_size, hidpi_factor); if state.previous_dpi_factor != hidpi_factor { state.previous_dpi_factor = hidpi_factor; - state.emit_event( - WindowEvent::HiDpiFactorChanged { - hidpi_factor, - new_inner_size: &mut Some(inner_size(ns_size, hidpi_factor)), - } - .to_static() - .unwrap(), - ); + state.emit_hidpi_factor_changed_event(&mut Some(new_size)); state.emit_resize_event(); } }); From cad8ae3a544d51c86cad5838b4bad02a28f3ed32 Mon Sep 17 00:00:00 2001 From: Vladimir Bogaevsky Date: Tue, 9 Jul 2019 22:55:47 +0300 Subject: [PATCH 11/25] applies fmt --- src/platform_impl/macos/app_state.rs | 2 +- src/platform_impl/macos/window_delegate.rs | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/platform_impl/macos/app_state.rs b/src/platform_impl/macos/app_state.rs index ff8f26d5ea..5e9a76fbc6 100644 --- a/src/platform_impl/macos/app_state.rs +++ b/src/platform_impl/macos/app_state.rs @@ -274,7 +274,7 @@ impl AppState { HANDLER.set_in_callback(true); // Since we do not push_back, we don't need to take_deferred // for event in HANDLER.take_deferred() { - HANDLER.handle_nonuser_event(event); + HANDLER.handle_nonuser_event(event); // } HANDLER.set_in_callback(false); } diff --git a/src/platform_impl/macos/window_delegate.rs b/src/platform_impl/macos/window_delegate.rs index e7358ae30e..0e749fb773 100644 --- a/src/platform_impl/macos/window_delegate.rs +++ b/src/platform_impl/macos/window_delegate.rs @@ -82,7 +82,10 @@ impl WindowDelegateState { AppState::queue_event(event); } - pub fn emit_hidpi_factor_changed_event(&mut self, new_inner_rect_opt: &mut Option) { + pub fn emit_hidpi_factor_changed_event( + &mut self, + new_inner_rect_opt: &mut Option, + ) { let event = Event::WindowEvent { window_id: WindowId(get_window_id(*self.ns_window)), event: WindowEvent::HiDpiFactorChanged { From f5a7f402973d0c352e8eed60230bd783cb3211f2 Mon Sep 17 00:00:00 2001 From: Vladimir Bogaevsky Date: Sat, 13 Jul 2019 14:37:20 +0300 Subject: [PATCH 12/25] restore original lifetimes --- src/platform_impl/macos/app_state.rs | 44 ++++++++++------------ src/platform_impl/macos/window.rs | 6 ++- src/platform_impl/macos/window_delegate.rs | 8 +++- 3 files changed, 30 insertions(+), 28 deletions(-) diff --git a/src/platform_impl/macos/app_state.rs b/src/platform_impl/macos/app_state.rs index 5e9a76fbc6..ffc1ddf62c 100644 --- a/src/platform_impl/macos/app_state.rs +++ b/src/platform_impl/macos/app_state.rs @@ -20,7 +20,7 @@ use crate::{ }; lazy_static! { - static ref HANDLER: Handler<'static> = Default::default(); + static ref HANDLER: Handler = Default::default(); } impl<'a, Never> Event<'a, Never> { @@ -80,32 +80,30 @@ where } #[derive(Default)] -struct Handler<'a> { +struct Handler { ready: AtomicBool, in_callback: AtomicBool, control_flow: Mutex, control_flow_prev: Mutex, start_time: Mutex>, callback: Mutex>>, - pending_events: Mutex>>, - // We don't need it any more. See line 270 - // deferred_events: Mutex>>, + pending_events: Mutex>>, + deferred_events: Mutex>>, pending_redraw: Mutex>, waker: Mutex, } -unsafe impl<'a> Send for Handler<'a> {} -unsafe impl<'a> Sync for Handler<'a> {} +unsafe impl Send for Handler {} +unsafe impl Sync for Handler {} -impl<'a> Handler<'a> { - fn events(&self) -> MutexGuard<'_, VecDeque>> { +impl Handler { + fn events(&self) -> MutexGuard<'_, VecDeque>> { self.pending_events.lock().unwrap() } - // We don't need it any more. - // fn deferred(&self) -> MutexGuard<'_, VecDeque>> { - // self.deferred_events.lock().unwrap() - // } + fn deferred(&self) -> MutexGuard<'_, VecDeque>> { + self.deferred_events.lock().unwrap() + } fn redraw(&self) -> MutexGuard<'_, Vec> { self.pending_redraw.lock().unwrap() @@ -151,10 +149,9 @@ impl<'a> Handler<'a> { mem::replace(&mut *self.events(), Default::default()) } - // We don't need it any more. - // fn take_deferred(&self) -> VecDeque> { - // mem::replace(&mut *self.deferred(), Default::default()) - // } + fn take_deferred(&self) -> VecDeque> { + mem::replace(&mut *self.deferred(), Default::default()) + } fn should_redraw(&self) -> Vec { mem::replace(&mut *self.redraw(), Default::default()) @@ -263,19 +260,16 @@ impl AppState { HANDLER.events().append(&mut events); } - pub fn send_event_immediately(event: Event<'_, Never>) { + pub fn send_event_immediately(event: Event<'static, Never>) { if !unsafe { msg_send![class!(NSThread), isMainThread] } { panic!("Event sent from different thread: {:#?}", event); } - // HANDLER.deferred().push_back(event); // Commenting this out due to unnecessity - // We check that events are sent here from the same thread so we do not need to process - // asynchronously, thus we do not need a VecDeque here + HANDLER.deferred().push_back(event); if !HANDLER.get_in_callback() { HANDLER.set_in_callback(true); - // Since we do not push_back, we don't need to take_deferred - // for event in HANDLER.take_deferred() { - HANDLER.handle_nonuser_event(event); - // } + for event in HANDLER.take_deferred() { + HANDLER.handle_nonuser_event(event); + } HANDLER.set_in_callback(false); } } diff --git a/src/platform_impl/macos/window.rs b/src/platform_impl/macos/window.rs index 4203c2b665..2c58ee7983 100644 --- a/src/platform_impl/macos/window.rs +++ b/src/platform_impl/macos/window.rs @@ -280,6 +280,7 @@ pub struct UnownedWindow { decorations: AtomicBool, cursor: Weak>, cursor_visible: AtomicBool, + pub inner_rect: Option, } unsafe impl Send for UnownedWindow {} @@ -315,6 +316,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); @@ -322,7 +325,6 @@ impl UnownedWindow { } ns_app.activateIgnoringOtherApps_(YES); - let dpi_factor = NSWindow::backingScaleFactor(*ns_window) as f64; win_attribs.min_inner_size.map(|dim| { let logical_dim = dim.to_logical(dpi_factor); set_min_inner_size(*ns_window, logical_dim) @@ -350,6 +352,7 @@ 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, @@ -359,6 +362,7 @@ impl UnownedWindow { decorations: AtomicBool::new(decorations), cursor, cursor_visible: AtomicBool::new(true), + inner_rect, }); let delegate = new_delegate(&window, fullscreen.is_some()); diff --git a/src/platform_impl/macos/window_delegate.rs b/src/platform_impl/macos/window_delegate.rs index 0e749fb773..14cf3f13ab 100644 --- a/src/platform_impl/macos/window_delegate.rs +++ b/src/platform_impl/macos/window_delegate.rs @@ -84,7 +84,7 @@ impl WindowDelegateState { pub fn emit_hidpi_factor_changed_event( &mut self, - new_inner_rect_opt: &mut Option, + new_inner_rect_opt: &'static mut std::option::Option, ) { let event = Event::WindowEvent { window_id: WindowId(get_window_id(*self.ns_window)), @@ -301,8 +301,12 @@ extern "C" fn window_did_change_screen(this: &Object, _: Sel, _: id) { let new_size = inner_size(ns_size, hidpi_factor); if state.previous_dpi_factor != hidpi_factor { state.previous_dpi_factor = hidpi_factor; - state.emit_hidpi_factor_changed_event(&mut Some(new_size)); + let mut new_inner_rect = Some(new_size); + state.emit_hidpi_factor_changed_event(&mut new_inner_rect); state.emit_resize_event(); + if let Some(window) = state.window.upgrade() { + window.inner_rect = new_inner_rect; + }; } }); trace!("Completed `windowDidChangeScreen:`"); From 00da630cfa44a49939fd1501ff97499bb653a743 Mon Sep 17 00:00:00 2001 From: Vladimir Bogaevsky Date: Thu, 22 Aug 2019 01:15:48 +0200 Subject: [PATCH 13/25] solution is somewhere out there --- src/platform_impl/macos/app_state.rs | 61 ++++++++++++++++++---- src/platform_impl/macos/event.rs | 52 ++++++++++++++++-- src/platform_impl/macos/util/mod.rs | 1 + src/platform_impl/macos/window_delegate.rs | 59 ++++++--------------- 4 files changed, 117 insertions(+), 56 deletions(-) diff --git a/src/platform_impl/macos/app_state.rs b/src/platform_impl/macos/app_state.rs index ffc1ddf62c..8933adafec 100644 --- a/src/platform_impl/macos/app_state.rs +++ b/src/platform_impl/macos/app_state.rs @@ -10,12 +10,18 @@ use std::{ time::Instant, }; -use cocoa::{appkit::NSApp, base::nil}; +use cocoa::{appkit::{NSApp, NSWindow}, base::nil}; use crate::{ - event::{Event, StartCause, WindowEvent}, + dpi::{LogicalSize, PhysicalSize}, + event::{Event, StartCause, WindowEvent} , event_loop::{ControlFlow, EventLoopWindowTarget as RootWindowTarget}, - platform_impl::platform::{observer::EventLoopWaker, util::Never}, + platform_impl::platform::{ + event::{EventProxy, WindowEventProxy, EventWrapper}, + observer::EventLoopWaker, + util::{IdRef, Never}, + window::get_window_id + }, window::WindowId, }; @@ -88,9 +94,10 @@ struct Handler { start_time: Mutex>, callback: Mutex>>, pending_events: Mutex>>, - deferred_events: Mutex>>, + deferred_events: Mutex>, pending_redraw: Mutex>, waker: Mutex, + window_size: Box>, } unsafe impl Send for Handler {} @@ -101,7 +108,7 @@ impl Handler { self.pending_events.lock().unwrap() } - fn deferred(&self) -> MutexGuard<'_, VecDeque>> { + fn deferred(&self) -> MutexGuard<'_, VecDeque> { self.deferred_events.lock().unwrap() } @@ -149,7 +156,7 @@ impl Handler { mem::replace(&mut *self.events(), Default::default()) } - fn take_deferred(&self) -> VecDeque> { + fn take_deferred(&self) -> VecDeque { mem::replace(&mut *self.deferred(), Default::default()) } @@ -176,6 +183,29 @@ impl Handler { callback.handle_user_events(&mut *self.control_flow.lock().unwrap()); } } + + fn create_hidpi_factor_changed_event(&mut self, ns_window: IdRef) -> Event<'_, Never> { + let hidpi_factor = unsafe { NSWindow::backingScaleFactor(*ns_window) } as f64; + let ns_size = unsafe { NSWindow::frame(*ns_window).size }; + let new_size = LogicalSize::new(ns_size.width, ns_size.height).to_physical(hidpi_factor); + self.window_size = Box::new(Some(new_size)); + // let new_inner_size: &'static mut Option = + Event::WindowEvent { + window_id: WindowId(get_window_id(*ns_window)), + event: WindowEvent::HiDpiFactorChanged { + hidpi_factor: hidpi_factor, + new_inner_size: &mut *self.window_size, + }, + } + } + + fn make_event(&mut self, proxy: EventProxy) -> Event<'_, Never> { + match proxy { + EventProxy::WindowEvent { + ns_window, proxy: WindowEventProxy::HiDpiFactorChangedProxy, + } => self.create_hidpi_factor_changed_event(ns_window), + } + } } pub enum AppState {} @@ -260,15 +290,24 @@ impl AppState { HANDLER.events().append(&mut events); } - pub fn send_event_immediately(event: Event<'static, Never>) { + pub fn send_event_immediately(wrapper: EventWrapper) { if !unsafe { msg_send![class!(NSThread), isMainThread] } { - panic!("Event sent from different thread: {:#?}", event); + panic!("Event sent from different thread: {:#?}", wrapper); } - HANDLER.deferred().push_back(event); + HANDLER.deferred().push_back(wrapper); if !HANDLER.get_in_callback() { HANDLER.set_in_callback(true); - for event in HANDLER.take_deferred() { - HANDLER.handle_nonuser_event(event); + for wrapper in HANDLER.take_deferred() { + match wrapper { + EventWrapper::StaticEvent(event) => HANDLER.handle_nonuser_event(event), + EventWrapper::EventProxy(proxy) => { + let event = HANDLER.make_event(proxy); + HANDLER.handle_nonuser_event(event); + if let Event::WindowEvent { event: window_event, .. } = event { + proxy.callback(window_event); + }; + }, + }; } HANDLER.set_in_callback(false); } diff --git a/src/platform_impl/macos/event.rs b/src/platform_impl/macos/event.rs index 41787bb4e9..daa39dede4 100644 --- a/src/platform_impl/macos/event.rs +++ b/src/platform_impl/macos/event.rs @@ -1,15 +1,61 @@ use std::os::raw::c_ushort; use cocoa::{ - appkit::{NSEvent, NSEventModifierFlags}, + appkit::{NSEvent, NSEventModifierFlags, NSWindow}, + foundation::{NSRect, NSSize}, base::id, }; use crate::{ - event::{ElementState, KeyboardInput, ModifiersState, VirtualKeyCode, WindowEvent}, - platform_impl::platform::DEVICE_ID, + event::{Event, ElementState, KeyboardInput, ModifiersState, VirtualKeyCode, WindowEvent}, + platform_impl::platform::{DEVICE_ID, util::{IdRef, Never}}, }; +#[derive(Debug)] +pub(crate) enum EventWrapper { + StaticEvent(Event<'static, Never>), + EventProxy(EventProxy), +} + +#[derive(Debug, PartialEq)] +pub(crate) enum EventProxy { + WindowEvent { + ns_window: IdRef, + proxy: WindowEventProxy, + }, +} + +impl EventProxy { + pub fn callback(self, event: WindowEvent<'_>) { + match self { + EventProxy::WindowEvent { ns_window, proxy } => proxy.callback(ns_window, event), + }; + } +} + +#[derive(Debug, PartialEq)] +pub(crate) enum WindowEventProxy { + HiDpiFactorChangedProxy, +} + +impl WindowEventProxy { + fn callback(self, ns_window: IdRef, event: WindowEvent<'_>) { + match self { + WindowEventProxy::HiDpiFactorChangedProxy => { + if let WindowEvent::HiDpiFactorChanged { hidpi_factor, new_inner_size } = event { + let origin = unsafe { NSWindow::frame(*ns_window).origin }; + if let Some(physical_size) = new_inner_size { + let logical_size = physical_size.to_logical(hidpi_factor); + let size = NSSize::new(logical_size.width, logical_size.height); + let rect = NSRect::new(origin, size); + unsafe { ns_window.setFrame_display_(rect, cocoa::base::YES) }; + }; + }; + }, + } + } +} + pub fn char_to_keycode(c: char) -> Option { // We only translate keys that are affected by keyboard layout. // diff --git a/src/platform_impl/macos/util/mod.rs b/src/platform_impl/macos/util/mod.rs index 238c9e5ddc..3a454cbba4 100644 --- a/src/platform_impl/macos/util/mod.rs +++ b/src/platform_impl/macos/util/mod.rs @@ -31,6 +31,7 @@ pub const EMPTY_RANGE: ffi::NSRange = ffi::NSRange { length: 0, }; +#[derive(Debug, PartialEq)] pub struct IdRef(id); impl IdRef { diff --git a/src/platform_impl/macos/window_delegate.rs b/src/platform_impl/macos/window_delegate.rs index 14cf3f13ab..bc57ed8c7a 100644 --- a/src/platform_impl/macos/window_delegate.rs +++ b/src/platform_impl/macos/window_delegate.rs @@ -7,7 +7,7 @@ use std::{ use cocoa::{ appkit::{self, NSView, NSWindow}, base::{id, nil}, - foundation::{NSAutoreleasePool, NSSize}, + foundation::{NSAutoreleasePool}, }; use objc::{ declare::ClassDecl, @@ -15,10 +15,11 @@ use objc::{ }; use crate::{ - dpi::{LogicalSize, PhysicalSize}, + dpi::{LogicalSize}, event::{Event, WindowEvent}, platform_impl::platform::{ app_state::AppState, + event::{EventWrapper, EventProxy, WindowEventProxy}, util::{self, IdRef}, window::{get_window_id, UnownedWindow}, }, @@ -48,8 +49,6 @@ pub struct WindowDelegateState { impl WindowDelegateState { pub fn new(window: &Arc, initial_fullscreen: bool) -> Self { let hidpi_factor = window.hidpi_factor(); - let mut new_inner_rect_opt = Some(window.inner_size()); - let mut delegate_state = WindowDelegateState { ns_window: window.ns_window.clone(), ns_view: window.ns_view.clone(), @@ -60,7 +59,7 @@ impl WindowDelegateState { }; if hidpi_factor != 1.0 { - delegate_state.emit_hidpi_factor_changed_event(&mut new_inner_rect_opt); + delegate_state.emit_static_hidpi_factor_changed_event(); delegate_state.emit_resize_event(); } @@ -82,18 +81,13 @@ impl WindowDelegateState { AppState::queue_event(event); } - pub fn emit_hidpi_factor_changed_event( - &mut self, - new_inner_rect_opt: &'static mut std::option::Option, - ) { - let event = Event::WindowEvent { - window_id: WindowId(get_window_id(*self.ns_window)), - event: WindowEvent::HiDpiFactorChanged { - hidpi_factor: self.previous_dpi_factor, - new_inner_size: new_inner_rect_opt, - }, - }; - AppState::send_event_immediately(event); + pub fn emit_static_hidpi_factor_changed_event(&self) { + let wrapper = EventWrapper::EventProxy( + EventProxy::WindowEvent { + ns_window: IdRef::retain(*self.ns_window), + proxy: WindowEventProxy::HiDpiFactorChangedProxy, + }); + AppState::send_event_immediately(wrapper); } pub fn emit_resize_event(&mut self) { @@ -105,7 +99,8 @@ impl WindowDelegateState { window_id: WindowId(get_window_id(*self.ns_window)), event: WindowEvent::Resized(physical_size), }; - AppState::send_event_immediately(event); + let wrapper = EventWrapper::StaticEvent(event); + AppState::send_event_immediately(wrapper); } fn emit_move_event(&mut self) { @@ -237,10 +232,6 @@ extern "C" fn dealloc(this: &Object, _sel: Sel) { }); } -fn inner_size(size: NSSize, dpi_factor: f64) -> PhysicalSize { - LogicalSize::new(size.width, size.height).to_physical(dpi_factor) -} - extern "C" fn init_with_winit(this: &Object, _sel: Sel, state: *mut c_void) -> id { unsafe { let this: id = msg_send![this, init]; @@ -296,18 +287,8 @@ extern "C" fn window_did_move(this: &Object, _: Sel, _: id) { extern "C" fn window_did_change_screen(this: &Object, _: Sel, _: id) { trace!("Triggered `windowDidChangeScreen:`"); with_state(this, |state| { - let hidpi_factor = unsafe { NSWindow::backingScaleFactor(*state.ns_window) } as f64; - let ns_size = unsafe { NSWindow::frame(*state.ns_window).size }; - let new_size = inner_size(ns_size, hidpi_factor); - if state.previous_dpi_factor != hidpi_factor { - state.previous_dpi_factor = hidpi_factor; - let mut new_inner_rect = Some(new_size); - state.emit_hidpi_factor_changed_event(&mut new_inner_rect); - state.emit_resize_event(); - if let Some(window) = state.window.upgrade() { - window.inner_rect = new_inner_rect; - }; - } + state.emit_static_hidpi_factor_changed_event(); + state.emit_resize_event(); }); trace!("Completed `windowDidChangeScreen:`"); } @@ -316,14 +297,8 @@ extern "C" fn window_did_change_screen(this: &Object, _: Sel, _: id) { extern "C" fn window_did_change_backing_properties(this: &Object, _: Sel, _: id) { trace!("Triggered `windowDidChangeBackingProperties:`"); with_state(this, |state| { - let hidpi_factor = unsafe { NSWindow::backingScaleFactor(*state.ns_window) } as f64; - let ns_size = unsafe { NSWindow::frame(*state.ns_window).size }; - let new_size = inner_size(ns_size, hidpi_factor); - if state.previous_dpi_factor != hidpi_factor { - state.previous_dpi_factor = hidpi_factor; - state.emit_hidpi_factor_changed_event(&mut Some(new_size)); - state.emit_resize_event(); - } + state.emit_static_hidpi_factor_changed_event(); + state.emit_resize_event(); }); trace!("Completed `windowDidChangeBackingProperties:`"); } From c7becf9e7b115b1e120caa3f2648de0d5509e115 Mon Sep 17 00:00:00 2001 From: Vladimir Bogaevsky Date: Thu, 22 Aug 2019 01:30:14 +0200 Subject: [PATCH 14/25] applies fmt --- src/platform_impl/macos/app_state.rs | 24 ++++++++++++++-------- src/platform_impl/macos/event.rs | 17 ++++++++++----- src/platform_impl/macos/window.rs | 4 +++- src/platform_impl/macos/window_delegate.rs | 13 ++++++------ 4 files changed, 37 insertions(+), 21 deletions(-) diff --git a/src/platform_impl/macos/app_state.rs b/src/platform_impl/macos/app_state.rs index 8933adafec..d373f595a3 100644 --- a/src/platform_impl/macos/app_state.rs +++ b/src/platform_impl/macos/app_state.rs @@ -10,17 +10,20 @@ use std::{ time::Instant, }; -use cocoa::{appkit::{NSApp, NSWindow}, base::nil}; +use cocoa::{ + appkit::{NSApp, NSWindow}, + base::nil, +}; use crate::{ dpi::{LogicalSize, PhysicalSize}, - event::{Event, StartCause, WindowEvent} , + event::{Event, StartCause, WindowEvent}, event_loop::{ControlFlow, EventLoopWindowTarget as RootWindowTarget}, platform_impl::platform::{ - event::{EventProxy, WindowEventProxy, EventWrapper}, + event::{EventProxy, EventWrapper, WindowEventProxy}, observer::EventLoopWaker, util::{IdRef, Never}, - window::get_window_id + window::get_window_id, }, window::WindowId, }; @@ -193,7 +196,7 @@ impl Handler { Event::WindowEvent { window_id: WindowId(get_window_id(*ns_window)), event: WindowEvent::HiDpiFactorChanged { - hidpi_factor: hidpi_factor, + hidpi_factor, new_inner_size: &mut *self.window_size, }, } @@ -202,7 +205,8 @@ impl Handler { fn make_event(&mut self, proxy: EventProxy) -> Event<'_, Never> { match proxy { EventProxy::WindowEvent { - ns_window, proxy: WindowEventProxy::HiDpiFactorChangedProxy, + ns_window, + proxy: WindowEventProxy::HiDpiFactorChangedProxy, } => self.create_hidpi_factor_changed_event(ns_window), } } @@ -303,10 +307,14 @@ impl AppState { EventWrapper::EventProxy(proxy) => { let event = HANDLER.make_event(proxy); HANDLER.handle_nonuser_event(event); - if let Event::WindowEvent { event: window_event, .. } = event { + if let Event::WindowEvent { + event: window_event, + .. + } = event + { proxy.callback(window_event); }; - }, + } }; } HANDLER.set_in_callback(false); diff --git a/src/platform_impl/macos/event.rs b/src/platform_impl/macos/event.rs index daa39dede4..431a7f5dc5 100644 --- a/src/platform_impl/macos/event.rs +++ b/src/platform_impl/macos/event.rs @@ -2,13 +2,16 @@ use std::os::raw::c_ushort; use cocoa::{ appkit::{NSEvent, NSEventModifierFlags, NSWindow}, - foundation::{NSRect, NSSize}, base::id, + foundation::{NSRect, NSSize}, }; use crate::{ - event::{Event, ElementState, KeyboardInput, ModifiersState, VirtualKeyCode, WindowEvent}, - platform_impl::platform::{DEVICE_ID, util::{IdRef, Never}}, + event::{ElementState, Event, KeyboardInput, ModifiersState, VirtualKeyCode, WindowEvent}, + platform_impl::platform::{ + util::{IdRef, Never}, + DEVICE_ID, + }, }; #[derive(Debug)] @@ -42,7 +45,11 @@ impl WindowEventProxy { fn callback(self, ns_window: IdRef, event: WindowEvent<'_>) { match self { WindowEventProxy::HiDpiFactorChangedProxy => { - if let WindowEvent::HiDpiFactorChanged { hidpi_factor, new_inner_size } = event { + if let WindowEvent::HiDpiFactorChanged { + hidpi_factor, + new_inner_size, + } = event + { let origin = unsafe { NSWindow::frame(*ns_window).origin }; if let Some(physical_size) = new_inner_size { let logical_size = physical_size.to_logical(hidpi_factor); @@ -51,7 +58,7 @@ impl WindowEventProxy { unsafe { ns_window.setFrame_display_(rect, cocoa::base::YES) }; }; }; - }, + } } } } diff --git a/src/platform_impl/macos/window.rs b/src/platform_impl/macos/window.rs index 2c58ee7983..bccf68cc55 100644 --- a/src/platform_impl/macos/window.rs +++ b/src/platform_impl/macos/window.rs @@ -352,7 +352,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 inner_rect = win_attribs + .inner_size + .map(|size| size.to_physical(dpi_factor)); let window = Arc::new(UnownedWindow { ns_view, diff --git a/src/platform_impl/macos/window_delegate.rs b/src/platform_impl/macos/window_delegate.rs index bc57ed8c7a..c52c0c3d27 100644 --- a/src/platform_impl/macos/window_delegate.rs +++ b/src/platform_impl/macos/window_delegate.rs @@ -7,7 +7,7 @@ use std::{ use cocoa::{ appkit::{self, NSView, NSWindow}, base::{id, nil}, - foundation::{NSAutoreleasePool}, + foundation::NSAutoreleasePool, }; use objc::{ declare::ClassDecl, @@ -15,11 +15,11 @@ use objc::{ }; use crate::{ - dpi::{LogicalSize}, + dpi::LogicalSize, event::{Event, WindowEvent}, platform_impl::platform::{ app_state::AppState, - event::{EventWrapper, EventProxy, WindowEventProxy}, + event::{EventProxy, EventWrapper, WindowEventProxy}, util::{self, IdRef}, window::{get_window_id, UnownedWindow}, }, @@ -82,10 +82,9 @@ impl WindowDelegateState { } pub fn emit_static_hidpi_factor_changed_event(&self) { - let wrapper = EventWrapper::EventProxy( - EventProxy::WindowEvent { - ns_window: IdRef::retain(*self.ns_window), - proxy: WindowEventProxy::HiDpiFactorChangedProxy, + let wrapper = EventWrapper::EventProxy(EventProxy::WindowEvent { + ns_window: IdRef::retain(*self.ns_window), + proxy: WindowEventProxy::HiDpiFactorChangedProxy, }); AppState::send_event_immediately(wrapper); } From 8305206b0b002fc7a0aa3cb75ec98583f4f1ce90 Mon Sep 17 00:00:00 2001 From: Vladimir Bogaevsky Date: Thu, 22 Aug 2019 01:45:48 +0200 Subject: [PATCH 15/25] pass as references --- src/platform_impl/macos/app_state.rs | 14 +++++++------- src/platform_impl/macos/event.rs | 6 +++--- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/platform_impl/macos/app_state.rs b/src/platform_impl/macos/app_state.rs index d373f595a3..2a009721be 100644 --- a/src/platform_impl/macos/app_state.rs +++ b/src/platform_impl/macos/app_state.rs @@ -187,14 +187,14 @@ impl Handler { } } - fn create_hidpi_factor_changed_event(&mut self, ns_window: IdRef) -> Event<'_, Never> { - let hidpi_factor = unsafe { NSWindow::backingScaleFactor(*ns_window) } as f64; - let ns_size = unsafe { NSWindow::frame(*ns_window).size }; + fn create_hidpi_factor_changed_event(&mut self, ns_window: &IdRef) -> Event<'_, Never> { + let hidpi_factor = unsafe { NSWindow::backingScaleFactor(**ns_window) } as f64; + let ns_size = unsafe { NSWindow::frame(**ns_window).size }; let new_size = LogicalSize::new(ns_size.width, ns_size.height).to_physical(hidpi_factor); self.window_size = Box::new(Some(new_size)); // let new_inner_size: &'static mut Option = Event::WindowEvent { - window_id: WindowId(get_window_id(*ns_window)), + window_id: WindowId(get_window_id(**ns_window)), event: WindowEvent::HiDpiFactorChanged { hidpi_factor, new_inner_size: &mut *self.window_size, @@ -202,7 +202,7 @@ impl Handler { } } - fn make_event(&mut self, proxy: EventProxy) -> Event<'_, Never> { + fn make_event(&mut self, proxy: &EventProxy) -> Event<'_, Never> { match proxy { EventProxy::WindowEvent { ns_window, @@ -305,14 +305,14 @@ impl AppState { match wrapper { EventWrapper::StaticEvent(event) => HANDLER.handle_nonuser_event(event), EventWrapper::EventProxy(proxy) => { - let event = HANDLER.make_event(proxy); + let event = HANDLER.make_event(&proxy); HANDLER.handle_nonuser_event(event); if let Event::WindowEvent { event: window_event, .. } = event { - proxy.callback(window_event); + proxy.callback(&window_event); }; } }; diff --git a/src/platform_impl/macos/event.rs b/src/platform_impl/macos/event.rs index 431a7f5dc5..0f6fad0fe0 100644 --- a/src/platform_impl/macos/event.rs +++ b/src/platform_impl/macos/event.rs @@ -29,7 +29,7 @@ pub(crate) enum EventProxy { } impl EventProxy { - pub fn callback(self, event: WindowEvent<'_>) { + pub fn callback(self, event: &WindowEvent<'_>) { match self { EventProxy::WindowEvent { ns_window, proxy } => proxy.callback(ns_window, event), }; @@ -42,7 +42,7 @@ pub(crate) enum WindowEventProxy { } impl WindowEventProxy { - fn callback(self, ns_window: IdRef, event: WindowEvent<'_>) { + fn callback(self, ns_window: IdRef, event: &WindowEvent<'_>) { match self { WindowEventProxy::HiDpiFactorChangedProxy => { if let WindowEvent::HiDpiFactorChanged { @@ -52,7 +52,7 @@ impl WindowEventProxy { { let origin = unsafe { NSWindow::frame(*ns_window).origin }; if let Some(physical_size) = new_inner_size { - let logical_size = physical_size.to_logical(hidpi_factor); + let logical_size = physical_size.to_logical(*hidpi_factor); let size = NSSize::new(logical_size.width, logical_size.height); let rect = NSRect::new(origin, size); unsafe { ns_window.setFrame_display_(rect, cocoa::base::YES) }; From 189ca8c4eabc0d137b22063fc3453c67e12ee186 Mon Sep 17 00:00:00 2001 From: Vladimir Bogaevsky Date: Thu, 22 Aug 2019 20:22:24 +0200 Subject: [PATCH 16/25] resolves issue with HANDLER --- src/platform_impl/macos/app_state.rs | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/platform_impl/macos/app_state.rs b/src/platform_impl/macos/app_state.rs index 2a009721be..734c2e3975 100644 --- a/src/platform_impl/macos/app_state.rs +++ b/src/platform_impl/macos/app_state.rs @@ -100,7 +100,7 @@ struct Handler { deferred_events: Mutex>, pending_redraw: Mutex>, waker: Mutex, - window_size: Box>, + window_size: Mutex>, } unsafe impl Send for Handler {} @@ -123,6 +123,10 @@ impl Handler { self.waker.lock().unwrap() } + fn window_size(&self) -> MutexGuard<'_, Option> { + self.window_size.lock().unwrap() + } + fn is_ready(&self) -> bool { self.ready.load(Ordering::Acquire) } @@ -163,6 +167,14 @@ impl Handler { mem::replace(&mut *self.deferred(), Default::default()) } + fn take_window_size(&self) -> &mut Option { + &mut mem::replace(&mut *self.window_size(), Default::default()) + } + + fn set_window_size(&self, size: Option) { + mem::replace(&mut *self.window_size(), size); + } + fn should_redraw(&self) -> Vec { mem::replace(&mut *self.redraw(), Default::default()) } @@ -187,22 +199,22 @@ impl Handler { } } - fn create_hidpi_factor_changed_event(&mut self, ns_window: &IdRef) -> Event<'_, Never> { + fn create_hidpi_factor_changed_event(&self, ns_window: &IdRef) -> Event<'_, Never> { let hidpi_factor = unsafe { NSWindow::backingScaleFactor(**ns_window) } as f64; let ns_size = unsafe { NSWindow::frame(**ns_window).size }; let new_size = LogicalSize::new(ns_size.width, ns_size.height).to_physical(hidpi_factor); - self.window_size = Box::new(Some(new_size)); + self.set_window_size(Some(new_size)); // let new_inner_size: &'static mut Option = Event::WindowEvent { window_id: WindowId(get_window_id(**ns_window)), event: WindowEvent::HiDpiFactorChanged { hidpi_factor, - new_inner_size: &mut *self.window_size, + new_inner_size: self.take_window_size(), }, } } - fn make_event(&mut self, proxy: &EventProxy) -> Event<'_, Never> { + fn make_event(&self, proxy: &EventProxy) -> Event<'_, Never> { match proxy { EventProxy::WindowEvent { ns_window, From a76f8e71978bdcebe221d70947ba6f5454b4b286 Mon Sep 17 00:00:00 2001 From: Vladimir Bogaevsky Date: Fri, 23 Aug 2019 10:41:21 +0200 Subject: [PATCH 17/25] crate visible type error --- src/platform_impl/macos/app_state.rs | 41 ++++++++++++--------- src/platform_impl/macos/event.rs | 43 +++++++--------------- src/platform_impl/macos/window_delegate.rs | 13 ++++--- 3 files changed, 45 insertions(+), 52 deletions(-) diff --git a/src/platform_impl/macos/app_state.rs b/src/platform_impl/macos/app_state.rs index 734c2e3975..83c8c48b74 100644 --- a/src/platform_impl/macos/app_state.rs +++ b/src/platform_impl/macos/app_state.rs @@ -12,6 +12,7 @@ use std::{ use cocoa::{ appkit::{NSApp, NSWindow}, + foundation::{NSRect, NSSize}, base::nil, }; @@ -20,7 +21,7 @@ use crate::{ event::{Event, StartCause, WindowEvent}, event_loop::{ControlFlow, EventLoopWindowTarget as RootWindowTarget}, platform_impl::platform::{ - event::{EventProxy, EventWrapper, WindowEventProxy}, + event::{EventProxy, EventWrapper}, observer::EventLoopWaker, util::{IdRef, Never}, window::get_window_id, @@ -167,8 +168,8 @@ impl Handler { mem::replace(&mut *self.deferred(), Default::default()) } - fn take_window_size(&self) -> &mut Option { - &mut mem::replace(&mut *self.window_size(), Default::default()) + fn take_window_size(&self) -> Box> { + Box::new(mem::replace(&mut *self.window_size(), Default::default())) } fn set_window_size(&self, size: Option) { @@ -199,29 +200,37 @@ impl Handler { } } - fn create_hidpi_factor_changed_event(&self, ns_window: &IdRef) -> Event<'_, Never> { - let hidpi_factor = unsafe { NSWindow::backingScaleFactor(**ns_window) } as f64; + fn create_hidpi_factor_changed_event(&self, ns_window: &IdRef, hidpi_factor: f64) -> Event<'_, Never> { let ns_size = unsafe { NSWindow::frame(**ns_window).size }; let new_size = LogicalSize::new(ns_size.width, ns_size.height).to_physical(hidpi_factor); self.set_window_size(Some(new_size)); - // let new_inner_size: &'static mut Option = Event::WindowEvent { window_id: WindowId(get_window_id(**ns_window)), event: WindowEvent::HiDpiFactorChanged { hidpi_factor, - new_inner_size: self.take_window_size(), + new_inner_size: Box::leak(self.take_window_size()), }, } } fn make_event(&self, proxy: &EventProxy) -> Event<'_, Never> { match proxy { - EventProxy::WindowEvent { + EventProxy::HiDpiFactorChangedProxy { ns_window, - proxy: WindowEventProxy::HiDpiFactorChangedProxy, - } => self.create_hidpi_factor_changed_event(ns_window), + hidpi_factor, + } => self.create_hidpi_factor_changed_event(ns_window, *hidpi_factor), } } + + fn handle_post_hidipi_changed_effects(&self, ns_window: IdRef, hidpi_factor: f64) { + let origin = unsafe { NSWindow::frame(*ns_window).origin }; + if let Some(physical_size) = Box::leak(self.take_window_size()) { + let logical_size = physical_size.to_logical(hidpi_factor); + let size = NSSize::new(logical_size.width, logical_size.height); + let rect = NSRect::new(origin, size); + unsafe { ns_window.setFrame_display_(rect, cocoa::base::YES) }; + }; + } } pub enum AppState {} @@ -319,13 +328,11 @@ impl AppState { EventWrapper::EventProxy(proxy) => { let event = HANDLER.make_event(&proxy); HANDLER.handle_nonuser_event(event); - if let Event::WindowEvent { - event: window_event, - .. - } = event - { - proxy.callback(&window_event); - }; + if let EventProxy::HiDpiFactorChangedProxy { + ns_window, hidpi_factor, + } = proxy { + HANDLER.handle_post_hidipi_changed_effects(ns_window, hidpi_factor); + } } }; } diff --git a/src/platform_impl/macos/event.rs b/src/platform_impl/macos/event.rs index 0f6fad0fe0..82c840079c 100644 --- a/src/platform_impl/macos/event.rs +++ b/src/platform_impl/macos/event.rs @@ -7,6 +7,7 @@ use cocoa::{ }; use crate::{ + dpi::PhysicalSize, event::{ElementState, Event, KeyboardInput, ModifiersState, VirtualKeyCode, WindowEvent}, platform_impl::platform::{ util::{IdRef, Never}, @@ -22,46 +23,28 @@ pub(crate) enum EventWrapper { #[derive(Debug, PartialEq)] pub(crate) enum EventProxy { - WindowEvent { + HiDpiFactorChangedProxy { ns_window: IdRef, - proxy: WindowEventProxy, + hidpi_factor: f64, }, } impl EventProxy { - pub fn callback(self, event: &WindowEvent<'_>) { + pub fn callback(self, new_size: &Option) { match self { - EventProxy::WindowEvent { ns_window, proxy } => proxy.callback(ns_window, event), + EventProxy::HiDpiFactorChangedProxy { ns_window, hidpi_factor } => { + let origin = unsafe { NSWindow::frame(*ns_window).origin }; + if let Some(physical_size) = new_size { + let logical_size = physical_size.to_logical(hidpi_factor); + let size = NSSize::new(logical_size.width, logical_size.height); + let rect = NSRect::new(origin, size); + unsafe { ns_window.setFrame_display_(rect, cocoa::base::YES) }; + }; + }, }; } } -#[derive(Debug, PartialEq)] -pub(crate) enum WindowEventProxy { - HiDpiFactorChangedProxy, -} - -impl WindowEventProxy { - fn callback(self, ns_window: IdRef, event: &WindowEvent<'_>) { - match self { - WindowEventProxy::HiDpiFactorChangedProxy => { - if let WindowEvent::HiDpiFactorChanged { - hidpi_factor, - new_inner_size, - } = event - { - let origin = unsafe { NSWindow::frame(*ns_window).origin }; - if let Some(physical_size) = new_inner_size { - let logical_size = physical_size.to_logical(*hidpi_factor); - let size = NSSize::new(logical_size.width, logical_size.height); - let rect = NSRect::new(origin, size); - unsafe { ns_window.setFrame_display_(rect, cocoa::base::YES) }; - }; - }; - } - } - } -} pub fn char_to_keycode(c: char) -> Option { // We only translate keys that are affected by keyboard layout. diff --git a/src/platform_impl/macos/window_delegate.rs b/src/platform_impl/macos/window_delegate.rs index c52c0c3d27..9e2c0fbf09 100644 --- a/src/platform_impl/macos/window_delegate.rs +++ b/src/platform_impl/macos/window_delegate.rs @@ -19,7 +19,7 @@ use crate::{ event::{Event, WindowEvent}, platform_impl::platform::{ app_state::AppState, - event::{EventProxy, EventWrapper, WindowEventProxy}, + event::{EventProxy, EventWrapper}, util::{self, IdRef}, window::{get_window_id, UnownedWindow}, }, @@ -82,10 +82,13 @@ impl WindowDelegateState { } pub fn emit_static_hidpi_factor_changed_event(&self) { - let wrapper = EventWrapper::EventProxy(EventProxy::WindowEvent { - ns_window: IdRef::retain(*self.ns_window), - proxy: WindowEventProxy::HiDpiFactorChangedProxy, - }); + let hidpi_factor = unsafe { NSWindow::backingScaleFactor(*self.ns_window) } as f64; + let wrapper = EventWrapper::EventProxy( + EventProxy::HiDpiFactorChangedProxy { + ns_window: IdRef::retain(*self.ns_window), + hidpi_factor, + } + ); AppState::send_event_immediately(wrapper); } From c2d99b6936e1b4cde6733f7b9cb90ce7dba77a53 Mon Sep 17 00:00:00 2001 From: Vladimir Bogaevsky Date: Fri, 23 Aug 2019 11:22:06 +0200 Subject: [PATCH 18/25] fixes visibility issues --- src/platform_impl/macos/event.rs | 21 ++------------------- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/src/platform_impl/macos/event.rs b/src/platform_impl/macos/event.rs index 82c840079c..b6eeaf5883 100644 --- a/src/platform_impl/macos/event.rs +++ b/src/platform_impl/macos/event.rs @@ -16,36 +16,19 @@ use crate::{ }; #[derive(Debug)] -pub(crate) enum EventWrapper { +pub enum EventWrapper { StaticEvent(Event<'static, Never>), EventProxy(EventProxy), } #[derive(Debug, PartialEq)] -pub(crate) enum EventProxy { +pub enum EventProxy { HiDpiFactorChangedProxy { ns_window: IdRef, hidpi_factor: f64, }, } -impl EventProxy { - pub fn callback(self, new_size: &Option) { - match self { - EventProxy::HiDpiFactorChangedProxy { ns_window, hidpi_factor } => { - let origin = unsafe { NSWindow::frame(*ns_window).origin }; - if let Some(physical_size) = new_size { - let logical_size = physical_size.to_logical(hidpi_factor); - let size = NSSize::new(logical_size.width, logical_size.height); - let rect = NSRect::new(origin, size); - unsafe { ns_window.setFrame_display_(rect, cocoa::base::YES) }; - }; - }, - }; - } -} - - pub fn char_to_keycode(c: char) -> Option { // We only translate keys that are affected by keyboard layout. // From 8ad50d5c9627e93f0437cc2c14fcc61179c9017e Mon Sep 17 00:00:00 2001 From: Vladimir Bogaevsky Date: Fri, 23 Aug 2019 11:25:21 +0200 Subject: [PATCH 19/25] applies fmt --- src/platform_impl/macos/app_state.rs | 14 ++++++++++---- src/platform_impl/macos/event.rs | 5 +---- src/platform_impl/macos/window_delegate.rs | 10 ++++------ 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/src/platform_impl/macos/app_state.rs b/src/platform_impl/macos/app_state.rs index 83c8c48b74..581ece2f84 100644 --- a/src/platform_impl/macos/app_state.rs +++ b/src/platform_impl/macos/app_state.rs @@ -12,8 +12,8 @@ use std::{ use cocoa::{ appkit::{NSApp, NSWindow}, - foundation::{NSRect, NSSize}, base::nil, + foundation::{NSRect, NSSize}, }; use crate::{ @@ -200,7 +200,11 @@ impl Handler { } } - fn create_hidpi_factor_changed_event(&self, ns_window: &IdRef, hidpi_factor: f64) -> Event<'_, Never> { + fn create_hidpi_factor_changed_event( + &self, + ns_window: &IdRef, + hidpi_factor: f64, + ) -> Event<'_, Never> { let ns_size = unsafe { NSWindow::frame(**ns_window).size }; let new_size = LogicalSize::new(ns_size.width, ns_size.height).to_physical(hidpi_factor); self.set_window_size(Some(new_size)); @@ -329,8 +333,10 @@ impl AppState { let event = HANDLER.make_event(&proxy); HANDLER.handle_nonuser_event(event); if let EventProxy::HiDpiFactorChangedProxy { - ns_window, hidpi_factor, - } = proxy { + ns_window, + hidpi_factor, + } = proxy + { HANDLER.handle_post_hidipi_changed_effects(ns_window, hidpi_factor); } } diff --git a/src/platform_impl/macos/event.rs b/src/platform_impl/macos/event.rs index b6eeaf5883..4991cf755a 100644 --- a/src/platform_impl/macos/event.rs +++ b/src/platform_impl/macos/event.rs @@ -23,10 +23,7 @@ pub enum EventWrapper { #[derive(Debug, PartialEq)] pub enum EventProxy { - HiDpiFactorChangedProxy { - ns_window: IdRef, - hidpi_factor: f64, - }, + HiDpiFactorChangedProxy { ns_window: IdRef, hidpi_factor: f64 }, } pub fn char_to_keycode(c: char) -> Option { diff --git a/src/platform_impl/macos/window_delegate.rs b/src/platform_impl/macos/window_delegate.rs index 9e2c0fbf09..5848ba8595 100644 --- a/src/platform_impl/macos/window_delegate.rs +++ b/src/platform_impl/macos/window_delegate.rs @@ -83,12 +83,10 @@ impl WindowDelegateState { pub fn emit_static_hidpi_factor_changed_event(&self) { let hidpi_factor = unsafe { NSWindow::backingScaleFactor(*self.ns_window) } as f64; - let wrapper = EventWrapper::EventProxy( - EventProxy::HiDpiFactorChangedProxy { - ns_window: IdRef::retain(*self.ns_window), - hidpi_factor, - } - ); + let wrapper = EventWrapper::EventProxy(EventProxy::HiDpiFactorChangedProxy { + ns_window: IdRef::retain(*self.ns_window), + hidpi_factor, + }); AppState::send_event_immediately(wrapper); } From 938da69cc9eb1e057c5c1e2e96d0e18e5302a054 Mon Sep 17 00:00:00 2001 From: Vladimir Bogaevsky Date: Fri, 23 Aug 2019 18:47:50 +0200 Subject: [PATCH 20/25] deals with warnings --- src/platform_impl/macos/app_state.rs | 13 +++++++------ src/platform_impl/macos/event.rs | 4 +--- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/platform_impl/macos/app_state.rs b/src/platform_impl/macos/app_state.rs index 581ece2f84..ca090c1cf2 100644 --- a/src/platform_impl/macos/app_state.rs +++ b/src/platform_impl/macos/app_state.rs @@ -332,12 +332,13 @@ impl AppState { EventWrapper::EventProxy(proxy) => { let event = HANDLER.make_event(&proxy); HANDLER.handle_nonuser_event(event); - if let EventProxy::HiDpiFactorChangedProxy { - ns_window, - hidpi_factor, - } = proxy - { - HANDLER.handle_post_hidipi_changed_effects(ns_window, hidpi_factor); + match proxy { + EventProxy::HiDpiFactorChangedProxy { + ns_window, + hidpi_factor, + } => { + HANDLER.handle_post_hidipi_changed_effects(ns_window, hidpi_factor) + } } } }; diff --git a/src/platform_impl/macos/event.rs b/src/platform_impl/macos/event.rs index 4991cf755a..8cd063dcdb 100644 --- a/src/platform_impl/macos/event.rs +++ b/src/platform_impl/macos/event.rs @@ -1,13 +1,11 @@ use std::os::raw::c_ushort; use cocoa::{ - appkit::{NSEvent, NSEventModifierFlags, NSWindow}, + appkit::{NSEvent, NSEventModifierFlags}, base::id, - foundation::{NSRect, NSSize}, }; use crate::{ - dpi::PhysicalSize, event::{ElementState, Event, KeyboardInput, ModifiersState, VirtualKeyCode, WindowEvent}, platform_impl::platform::{ util::{IdRef, Never}, From 4fc725ca164592d570bb29e418fe6b1a807b026c Mon Sep 17 00:00:00 2001 From: Vladimir Bogaevsky Date: Sun, 25 Aug 2019 22:25:58 +0200 Subject: [PATCH 21/25] simplifies new_inner_size setting algorthm --- src/platform_impl/macos/app_state.rs | 66 ++++++++-------------------- 1 file changed, 19 insertions(+), 47 deletions(-) diff --git a/src/platform_impl/macos/app_state.rs b/src/platform_impl/macos/app_state.rs index ca090c1cf2..275c482628 100644 --- a/src/platform_impl/macos/app_state.rs +++ b/src/platform_impl/macos/app_state.rs @@ -17,7 +17,7 @@ use cocoa::{ }; use crate::{ - dpi::{LogicalSize, PhysicalSize}, + dpi::LogicalSize, event::{Event, StartCause, WindowEvent}, event_loop::{ControlFlow, EventLoopWindowTarget as RootWindowTarget}, platform_impl::platform::{ @@ -101,7 +101,6 @@ struct Handler { deferred_events: Mutex>, pending_redraw: Mutex>, waker: Mutex, - window_size: Mutex>, } unsafe impl Send for Handler {} @@ -124,10 +123,6 @@ impl Handler { self.waker.lock().unwrap() } - fn window_size(&self) -> MutexGuard<'_, Option> { - self.window_size.lock().unwrap() - } - fn is_ready(&self) -> bool { self.ready.load(Ordering::Acquire) } @@ -168,14 +163,6 @@ impl Handler { mem::replace(&mut *self.deferred(), Default::default()) } - fn take_window_size(&self) -> Box> { - Box::new(mem::replace(&mut *self.window_size(), Default::default())) - } - - fn set_window_size(&self, size: Option) { - mem::replace(&mut *self.window_size(), size); - } - fn should_redraw(&self) -> Vec { mem::replace(&mut *self.redraw(), Default::default()) } @@ -200,41 +187,37 @@ impl Handler { } } - fn create_hidpi_factor_changed_event( - &self, - ns_window: &IdRef, - hidpi_factor: f64, - ) -> Event<'_, Never> { + fn handle_hidpi_factor_changed_event(&self, ns_window: &IdRef, hidpi_factor: f64) { let ns_size = unsafe { NSWindow::frame(**ns_window).size }; let new_size = LogicalSize::new(ns_size.width, ns_size.height).to_physical(hidpi_factor); - self.set_window_size(Some(new_size)); - Event::WindowEvent { + let new_inner_size = &mut Some(new_size); + let event = Event::WindowEvent { window_id: WindowId(get_window_id(**ns_window)), event: WindowEvent::HiDpiFactorChanged { hidpi_factor, - new_inner_size: Box::leak(self.take_window_size()), + new_inner_size, }, - } - } + }; - fn make_event(&self, proxy: &EventProxy) -> Event<'_, Never> { - match proxy { - EventProxy::HiDpiFactorChangedProxy { - ns_window, - hidpi_factor, - } => self.create_hidpi_factor_changed_event(ns_window, *hidpi_factor), - } - } + self.handle_nonuser_event(event); - fn handle_post_hidipi_changed_effects(&self, ns_window: IdRef, hidpi_factor: f64) { - let origin = unsafe { NSWindow::frame(*ns_window).origin }; - if let Some(physical_size) = Box::leak(self.take_window_size()) { + let origin = unsafe { NSWindow::frame(**ns_window).origin }; + if let Some(physical_size) = new_inner_size { let logical_size = physical_size.to_logical(hidpi_factor); let size = NSSize::new(logical_size.width, logical_size.height); let rect = NSRect::new(origin, size); unsafe { ns_window.setFrame_display_(rect, cocoa::base::YES) }; }; } + + fn handle_event(&self, proxy: &EventProxy) { + match proxy { + EventProxy::HiDpiFactorChangedProxy { + ns_window, + hidpi_factor, + } => self.handle_hidpi_factor_changed_event(ns_window, *hidpi_factor), + } + } } pub enum AppState {} @@ -329,18 +312,7 @@ impl AppState { for wrapper in HANDLER.take_deferred() { match wrapper { EventWrapper::StaticEvent(event) => HANDLER.handle_nonuser_event(event), - EventWrapper::EventProxy(proxy) => { - let event = HANDLER.make_event(&proxy); - HANDLER.handle_nonuser_event(event); - match proxy { - EventProxy::HiDpiFactorChangedProxy { - ns_window, - hidpi_factor, - } => { - HANDLER.handle_post_hidipi_changed_effects(ns_window, hidpi_factor) - } - } - } + EventWrapper::EventProxy(proxy) => HANDLER.handle_event(&proxy), }; } HANDLER.set_in_callback(false); From 5aa604f2461f55534455184d52d8b6020004986f Mon Sep 17 00:00:00 2001 From: Vladimir Bogaevsky Date: Sun, 25 Aug 2019 22:30:14 +0200 Subject: [PATCH 22/25] moves proxy instead of referencing it and removes double deref from proxy.ns_window --- src/platform_impl/macos/app_state.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/platform_impl/macos/app_state.rs b/src/platform_impl/macos/app_state.rs index 275c482628..d016035801 100644 --- a/src/platform_impl/macos/app_state.rs +++ b/src/platform_impl/macos/app_state.rs @@ -187,12 +187,12 @@ impl Handler { } } - fn handle_hidpi_factor_changed_event(&self, ns_window: &IdRef, hidpi_factor: f64) { - let ns_size = unsafe { NSWindow::frame(**ns_window).size }; + fn handle_hidpi_factor_changed_event(&self, ns_window: IdRef, hidpi_factor: f64) { + let ns_size = unsafe { NSWindow::frame(*ns_window).size }; let new_size = LogicalSize::new(ns_size.width, ns_size.height).to_physical(hidpi_factor); let new_inner_size = &mut Some(new_size); let event = Event::WindowEvent { - window_id: WindowId(get_window_id(**ns_window)), + window_id: WindowId(get_window_id(*ns_window)), event: WindowEvent::HiDpiFactorChanged { hidpi_factor, new_inner_size, @@ -201,7 +201,7 @@ impl Handler { self.handle_nonuser_event(event); - let origin = unsafe { NSWindow::frame(**ns_window).origin }; + let origin = unsafe { NSWindow::frame(*ns_window).origin }; if let Some(physical_size) = new_inner_size { let logical_size = physical_size.to_logical(hidpi_factor); let size = NSSize::new(logical_size.width, logical_size.height); @@ -210,12 +210,12 @@ impl Handler { }; } - fn handle_event(&self, proxy: &EventProxy) { + fn handle_event(&self, proxy: EventProxy) { match proxy { EventProxy::HiDpiFactorChangedProxy { ns_window, hidpi_factor, - } => self.handle_hidpi_factor_changed_event(ns_window, *hidpi_factor), + } => self.handle_hidpi_factor_changed_event(ns_window, hidpi_factor), } } } @@ -312,7 +312,7 @@ impl AppState { for wrapper in HANDLER.take_deferred() { match wrapper { EventWrapper::StaticEvent(event) => HANDLER.handle_nonuser_event(event), - EventWrapper::EventProxy(proxy) => HANDLER.handle_event(&proxy), + EventWrapper::EventProxy(proxy) => HANDLER.handle_event(proxy), }; } HANDLER.set_in_callback(false); From 7f0d3ea0bf5244953c2d04da67d5e557d9e87f31 Mon Sep 17 00:00:00 2001 From: Vladimir Bogaevsky Date: Thu, 29 Aug 2019 12:39:19 +0200 Subject: [PATCH 23/25] makes @Osspial tests (https://github.com/rust-windowing/winit/pull/997\#discussion_r301852354) pass --- src/platform_impl/macos/app_state.rs | 30 ++++++++++++---------- src/platform_impl/macos/event.rs | 7 ++++- src/platform_impl/macos/window_delegate.rs | 15 ++++++----- 3 files changed, 31 insertions(+), 21 deletions(-) diff --git a/src/platform_impl/macos/app_state.rs b/src/platform_impl/macos/app_state.rs index d016035801..38cd438b0c 100644 --- a/src/platform_impl/macos/app_state.rs +++ b/src/platform_impl/macos/app_state.rs @@ -13,7 +13,7 @@ use std::{ use cocoa::{ appkit::{NSApp, NSWindow}, base::nil, - foundation::{NSRect, NSSize}, + foundation::NSSize, }; use crate::{ @@ -187,10 +187,14 @@ impl Handler { } } - fn handle_hidpi_factor_changed_event(&self, ns_window: IdRef, hidpi_factor: f64) { - let ns_size = unsafe { NSWindow::frame(*ns_window).size }; - let new_size = LogicalSize::new(ns_size.width, ns_size.height).to_physical(hidpi_factor); - let new_inner_size = &mut Some(new_size); + fn handle_hidpi_factor_changed_event( + &self, + ns_window: IdRef, + suggested_size: LogicalSize, + hidpi_factor: f64, + ) { + let size = suggested_size.to_physical(hidpi_factor); + let new_inner_size = &mut Some(size); let event = Event::WindowEvent { window_id: WindowId(get_window_id(*ns_window)), event: WindowEvent::HiDpiFactorChanged { @@ -201,21 +205,21 @@ impl Handler { self.handle_nonuser_event(event); - let origin = unsafe { NSWindow::frame(*ns_window).origin }; - if let Some(physical_size) = new_inner_size { - let logical_size = physical_size.to_logical(hidpi_factor); - let size = NSSize::new(logical_size.width, logical_size.height); - let rect = NSRect::new(origin, size); - unsafe { ns_window.setFrame_display_(rect, cocoa::base::YES) }; - }; + // let origin = unsafe { NSWindow::frame(*ns_window).origin }; + let physical_size = new_inner_size.unwrap_or(size); + let logical_size = physical_size.to_logical(hidpi_factor); + let size = NSSize::new(logical_size.width, logical_size.height); + // let rect = NSRect::new(origin, size); + unsafe { NSWindow::setContentSize_(*ns_window, size) }; } fn handle_event(&self, proxy: EventProxy) { match proxy { EventProxy::HiDpiFactorChangedProxy { ns_window, + suggested_size, hidpi_factor, - } => self.handle_hidpi_factor_changed_event(ns_window, hidpi_factor), + } => self.handle_hidpi_factor_changed_event(ns_window, suggested_size, hidpi_factor), } } } diff --git a/src/platform_impl/macos/event.rs b/src/platform_impl/macos/event.rs index 8cd063dcdb..29b3df7c10 100644 --- a/src/platform_impl/macos/event.rs +++ b/src/platform_impl/macos/event.rs @@ -6,6 +6,7 @@ use cocoa::{ }; use crate::{ + dpi::LogicalSize, event::{ElementState, Event, KeyboardInput, ModifiersState, VirtualKeyCode, WindowEvent}, platform_impl::platform::{ util::{IdRef, Never}, @@ -21,7 +22,11 @@ pub enum EventWrapper { #[derive(Debug, PartialEq)] pub enum EventProxy { - HiDpiFactorChangedProxy { ns_window: IdRef, hidpi_factor: f64 }, + HiDpiFactorChangedProxy { + ns_window: IdRef, + suggested_size: LogicalSize, + hidpi_factor: f64, + }, } pub fn char_to_keycode(c: char) -> Option { diff --git a/src/platform_impl/macos/window_delegate.rs b/src/platform_impl/macos/window_delegate.rs index 5848ba8595..17b1580885 100644 --- a/src/platform_impl/macos/window_delegate.rs +++ b/src/platform_impl/macos/window_delegate.rs @@ -49,7 +49,7 @@ pub struct WindowDelegateState { impl WindowDelegateState { pub fn new(window: &Arc, initial_fullscreen: bool) -> Self { let hidpi_factor = window.hidpi_factor(); - let mut delegate_state = WindowDelegateState { + let delegate_state = WindowDelegateState { ns_window: window.ns_window.clone(), ns_view: window.ns_view.clone(), window: Arc::downgrade(&window), @@ -60,7 +60,6 @@ impl WindowDelegateState { if hidpi_factor != 1.0 { delegate_state.emit_static_hidpi_factor_changed_event(); - delegate_state.emit_resize_event(); } delegate_state @@ -85,16 +84,15 @@ impl WindowDelegateState { let hidpi_factor = unsafe { NSWindow::backingScaleFactor(*self.ns_window) } as f64; let wrapper = EventWrapper::EventProxy(EventProxy::HiDpiFactorChangedProxy { ns_window: IdRef::retain(*self.ns_window), + suggested_size: self.view_size(), hidpi_factor, }); AppState::send_event_immediately(wrapper); } pub fn emit_resize_event(&mut self) { - let rect = unsafe { NSView::frame(*self.ns_view) }; - let size = LogicalSize::new(rect.size.width as f64, rect.size.height as f64); let hidpi_factor = self.previous_dpi_factor; - let physical_size = size.to_physical(hidpi_factor); + let physical_size = self.view_size().to_physical(hidpi_factor); let event = Event::WindowEvent { window_id: WindowId(get_window_id(*self.ns_window)), event: WindowEvent::Resized(physical_size), @@ -113,6 +111,11 @@ impl WindowDelegateState { self.emit_event(WindowEvent::Moved((x, y).into())); } } + + fn view_size(&self) -> LogicalSize { + let ns_size = unsafe { NSView::frame(*self.ns_view).size }; + LogicalSize::new(ns_size.width as f64, ns_size.height as f64) + } } pub fn new_delegate(window: &Arc, initial_fullscreen: bool) -> IdRef { @@ -288,7 +291,6 @@ extern "C" fn window_did_change_screen(this: &Object, _: Sel, _: id) { trace!("Triggered `windowDidChangeScreen:`"); with_state(this, |state| { state.emit_static_hidpi_factor_changed_event(); - state.emit_resize_event(); }); trace!("Completed `windowDidChangeScreen:`"); } @@ -298,7 +300,6 @@ extern "C" fn window_did_change_backing_properties(this: &Object, _: Sel, _: id) trace!("Triggered `windowDidChangeBackingProperties:`"); with_state(this, |state| { state.emit_static_hidpi_factor_changed_event(); - state.emit_resize_event(); }); trace!("Completed `windowDidChangeBackingProperties:`"); } From c6559d07022be0e38844c1351d9b9f3af9070c2c Mon Sep 17 00:00:00 2001 From: Vladimir Bogaevsky Date: Fri, 30 Aug 2019 00:45:40 +0200 Subject: [PATCH 24/25] complies with @aleksijuvani suggested changes --- src/platform_impl/macos/window.rs | 4 +-- src/platform_impl/macos/window_delegate.rs | 30 ++++++++++------------ 2 files changed, 15 insertions(+), 19 deletions(-) diff --git a/src/platform_impl/macos/window.rs b/src/platform_impl/macos/window.rs index bccf68cc55..1bc8641e81 100644 --- a/src/platform_impl/macos/window.rs +++ b/src/platform_impl/macos/window.rs @@ -509,8 +509,8 @@ impl UnownedWindow { pub fn set_max_inner_size(&self, dimensions: Option) { unsafe { let dimensions = dimensions.unwrap_or(Logical(LogicalSize { - width: 0.0, - height: 0.0, + width: std::f64::MAX, + height: std::f64::MAX, })); let dpi_factor = self.hidpi_factor(); set_max_inner_size(*self.ns_window, dimensions.to_logical(dpi_factor)); diff --git a/src/platform_impl/macos/window_delegate.rs b/src/platform_impl/macos/window_delegate.rs index 17b1580885..6bb73bbf6b 100644 --- a/src/platform_impl/macos/window_delegate.rs +++ b/src/platform_impl/macos/window_delegate.rs @@ -49,7 +49,7 @@ pub struct WindowDelegateState { impl WindowDelegateState { pub fn new(window: &Arc, initial_fullscreen: bool) -> Self { let hidpi_factor = window.hidpi_factor(); - let delegate_state = WindowDelegateState { + let mut delegate_state = WindowDelegateState { ns_window: window.ns_window.clone(), ns_view: window.ns_view.clone(), window: Arc::downgrade(&window), @@ -80,8 +80,13 @@ impl WindowDelegateState { AppState::queue_event(event); } - pub fn emit_static_hidpi_factor_changed_event(&self) { - let hidpi_factor = unsafe { NSWindow::backingScaleFactor(*self.ns_window) } as f64; + pub fn emit_static_hidpi_factor_changed_event(&mut self) { + let hidpi_factor = self.get_hidpi_factor(); + if hidpi_factor == self.previous_dpi_factor { + return (); + }; + + self.previous_dpi_factor = hidpi_factor; let wrapper = EventWrapper::EventProxy(EventProxy::HiDpiFactorChangedProxy { ns_window: IdRef::retain(*self.ns_window), suggested_size: self.view_size(), @@ -91,7 +96,7 @@ impl WindowDelegateState { } pub fn emit_resize_event(&mut self) { - let hidpi_factor = self.previous_dpi_factor; + let hidpi_factor = self.get_hidpi_factor(); let physical_size = self.view_size().to_physical(hidpi_factor); let event = Event::WindowEvent { window_id: WindowId(get_window_id(*self.ns_window)), @@ -112,6 +117,10 @@ impl WindowDelegateState { } } + fn get_hidpi_factor(&self) -> f64 { + (unsafe { NSWindow::backingScaleFactor(*self.ns_window) }) as f64 + } + fn view_size(&self) -> LogicalSize { let ns_size = unsafe { NSView::frame(*self.ns_view).size }; LogicalSize::new(ns_size.width as f64, ns_size.height as f64) @@ -159,10 +168,6 @@ lazy_static! { sel!(windowDidMove:), window_did_move as extern "C" fn(&Object, Sel, id), ); - decl.add_method( - sel!(windowDidChangeScreen:), - window_did_change_screen as extern "C" fn(&Object, Sel, id), - ); decl.add_method( sel!(windowDidChangeBackingProperties:), window_did_change_backing_properties as extern "C" fn(&Object, Sel, id), @@ -287,15 +292,6 @@ extern "C" fn window_did_move(this: &Object, _: Sel, _: id) { trace!("Completed `windowDidMove:`"); } -extern "C" fn window_did_change_screen(this: &Object, _: Sel, _: id) { - trace!("Triggered `windowDidChangeScreen:`"); - with_state(this, |state| { - state.emit_static_hidpi_factor_changed_event(); - }); - trace!("Completed `windowDidChangeScreen:`"); -} - -// This will always be called before `window_did_change_screen`. extern "C" fn window_did_change_backing_properties(this: &Object, _: Sel, _: id) { trace!("Triggered `windowDidChangeBackingProperties:`"); with_state(this, |state| { From 1101152ca7665ff9ebecb401e753f930543445f3 Mon Sep 17 00:00:00 2001 From: Vladimir Bogaevsky Date: Fri, 30 Aug 2019 09:59:26 +0200 Subject: [PATCH 25/25] makes max window size std::f32::MAX --- src/platform_impl/macos/window.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/platform_impl/macos/window.rs b/src/platform_impl/macos/window.rs index 1bc8641e81..789543af12 100644 --- a/src/platform_impl/macos/window.rs +++ b/src/platform_impl/macos/window.rs @@ -509,8 +509,8 @@ impl UnownedWindow { pub fn set_max_inner_size(&self, dimensions: Option) { unsafe { let dimensions = dimensions.unwrap_or(Logical(LogicalSize { - width: std::f64::MAX, - height: std::f64::MAX, + 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));