diff --git a/CHANGELOG.md b/CHANGELOG.md index 029bf121..a971693f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ # Unreleased +- On macOS, fix `CursorMoved` event reporting the cursor position using logical coordinates. - On macOS, fix issue where unbundled applications would sometimes open without being focused. - On macOS, fix `run_return` does not return unless it receives a message. - On Windows, fix bug where `RedrawRequested` would only get emitted every other iteration of the event loop. diff --git a/src/platform_impl/macos/view.rs b/src/platform_impl/macos/view.rs index 4bc8bcc7..c0b2adc5 100644 --- a/src/platform_impl/macos/view.rs +++ b/src/platform_impl/macos/view.rs @@ -17,6 +17,7 @@ use objc::{ }; use crate::{ + dpi::LogicalPosition, event::{ DeviceEvent, ElementState, Event, KeyboardInput, ModifiersState, MouseButton, MouseScrollDelta, TouchPhase, VirtualKeyCode, WindowEvent, @@ -59,6 +60,12 @@ struct ViewState { tracking_rect: Option, } +impl ViewState { + fn get_scale_factor(&self) -> f64 { + (unsafe { NSWindow::backingScaleFactor(self.ns_window) }) as f64 + } +} + pub fn new_view(ns_window: id) -> (IdRef, Weak>) { let cursor_state = Default::default(); let cursor_access = Arc::downgrade(&cursor_state); @@ -885,12 +892,13 @@ fn mouse_motion(this: &Object, event: id) { let x = view_point.x as f64; let y = view_rect.size.height as f64 - view_point.y as f64; + let logical_position = LogicalPosition::new(x, y); let window_event = Event::WindowEvent { window_id: WindowId(get_window_id(state.ns_window)), event: WindowEvent::CursorMoved { device_id: DEVICE_ID, - position: (x, y).into(), + position: logical_position.to_physical(state.get_scale_factor()), modifiers: event_mods(event), }, }; @@ -928,27 +936,8 @@ extern "C" fn mouse_entered(this: &Object, _sel: Sel, event: id) { }, }; - let move_event = { - let window_point = event.locationInWindow(); - let view_point: NSPoint = msg_send![this, - convertPoint:window_point - fromView:nil // convert from window coordinates - ]; - let view_rect: NSRect = msg_send![this, frame]; - let x = view_point.x as f64; - let y = (view_rect.size.height - view_point.y) as f64; - Event::WindowEvent { - window_id: WindowId(get_window_id(state.ns_window)), - event: WindowEvent::CursorMoved { - device_id: DEVICE_ID, - position: (x, y).into(), - modifiers: event_mods(event), - }, - } - }; - AppState::queue_event(EventWrapper::StaticEvent(enter_event)); - AppState::queue_event(EventWrapper::StaticEvent(move_event)); + mouse_motion(this, event); } trace!("Completed `mouseEntered`"); }