From 4b618bd6a6c27bb4198182a45ba84ecc095503d1 Mon Sep 17 00:00:00 2001 From: Benjamin Saunders Date: Thu, 9 Jan 2020 20:19:50 -0800 Subject: [PATCH] Don't discard high-precision cursor position data (#1375) * Don't discard high-precision cursor position data Most platforms (X11, wayland, macos, stdweb, ...) provide physical positions in f64 units, which can contain meaningful fractional data. For example, this can be empirically observed on modern X11 using a typical laptop touchpad. This is useful for e.g. content creation tools, where cursor motion might map to brush strokes on a canvas with higher-than-screen resolution, or positioning of an object in a vector space. * Update CHANGELOG.md Co-Authored-By: Murarth Co-authored-by: Murarth --- CHANGELOG.md | 1 + src/event.rs | 2 +- src/platform_impl/linux/x11/event_processor.rs | 9 +++------ src/platform_impl/web/stdweb/canvas.rs | 2 +- src/platform_impl/web/web_sys/canvas.rs | 2 +- src/platform_impl/windows/event_loop.rs | 4 ++-- 6 files changed, 9 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2be5dfad..9df5e037 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ - On Windows, fix bug where `RedrawRequested` would only get emitted every other iteration of the event loop. - On X11, fix deadlock on window state when handling certain window events. - `WindowBuilder` now implements `Default`. +- **Breaking:** `WindowEvent::CursorMoved` changed to `f64` units, preserving high-precision data supplied by most backends # 0.20.0 (2020-01-05) diff --git a/src/event.rs b/src/event.rs index 9f30e881..10ab6217 100644 --- a/src/event.rs +++ b/src/event.rs @@ -242,7 +242,7 @@ pub enum WindowEvent<'a> { /// (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: PhysicalPosition, + position: PhysicalPosition, #[deprecated = "Deprecated in favor of DeviceEvent::ModifiersChanged"] modifiers: ModifiersState, }, diff --git a/src/platform_impl/linux/x11/event_processor.rs b/src/platform_impl/linux/x11/event_processor.rs index 14fc1b1f..424bb89c 100644 --- a/src/platform_impl/linux/x11/event_processor.rs +++ b/src/platform_impl/linux/x11/event_processor.rs @@ -723,8 +723,7 @@ impl EventProcessor { util::maybe_change(&mut shared_state_lock.cursor_pos, new_cursor_pos) }); if cursor_moved == Some(true) { - let position = - PhysicalPosition::new(xev.event_x as i32, xev.event_y as i32); + let position = PhysicalPosition::new(xev.event_x, xev.event_y); callback(Event::WindowEvent { window_id, @@ -830,8 +829,7 @@ impl EventProcessor { event: CursorEntered { device_id }, }); - let position = - PhysicalPosition::new(xev.event_x as i32, xev.event_y as i32); + let position = PhysicalPosition::new(xev.event_x, xev.event_y); // The mods field on this event isn't actually populated, so query the // pointer device. In the future, we can likely remove this round-trip by @@ -899,8 +897,7 @@ impl EventProcessor { .map(|device| device.attachment) .unwrap_or(2); - let position = - PhysicalPosition::new(xev.event_x as i32, xev.event_y as i32); + let position = PhysicalPosition::new(xev.event_x, xev.event_y); callback(Event::WindowEvent { window_id, diff --git a/src/platform_impl/web/stdweb/canvas.rs b/src/platform_impl/web/stdweb/canvas.rs index 94586d04..35bc8044 100644 --- a/src/platform_impl/web/stdweb/canvas.rs +++ b/src/platform_impl/web/stdweb/canvas.rs @@ -207,7 +207,7 @@ impl Canvas { pub fn on_cursor_move(&mut self, mut handler: F) where - F: 'static + FnMut(i32, PhysicalPosition, ModifiersState), + F: 'static + FnMut(i32, PhysicalPosition, ModifiersState), { // todo self.on_cursor_move = Some(self.add_event(move |event: PointerMoveEvent| { diff --git a/src/platform_impl/web/web_sys/canvas.rs b/src/platform_impl/web/web_sys/canvas.rs index 70b0ecc9..1d7e4746 100644 --- a/src/platform_impl/web/web_sys/canvas.rs +++ b/src/platform_impl/web/web_sys/canvas.rs @@ -216,7 +216,7 @@ impl Canvas { pub fn on_cursor_move(&mut self, mut handler: F) where - F: 'static + FnMut(i32, PhysicalPosition, ModifiersState), + F: 'static + FnMut(i32, PhysicalPosition, ModifiersState), { self.on_cursor_move = Some(self.add_event("pointermove", move |event: PointerEvent| { handler( diff --git a/src/platform_impl/windows/event_loop.rs b/src/platform_impl/windows/event_loop.rs index 8d90e247..beb3cef5 100644 --- a/src/platform_impl/windows/event_loop.rs +++ b/src/platform_impl/windows/event_loop.rs @@ -855,8 +855,8 @@ unsafe extern "system" fn public_window_callback( }); } - let x = windowsx::GET_X_LPARAM(lparam) as i32; - let y = windowsx::GET_Y_LPARAM(lparam) as i32; + let x = windowsx::GET_X_LPARAM(lparam) as f64; + let y = windowsx::GET_Y_LPARAM(lparam) as f64; let position = PhysicalPosition::new(x, y); subclass_input.send_event(Event::WindowEvent {