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 <murarth@gmail.com>

Co-authored-by: Murarth <murarth@gmail.com>
This commit is contained in:
Benjamin Saunders 2020-01-09 20:19:50 -08:00 committed by Freya Gentz
parent 09c4ed0694
commit 4b618bd6a6
6 changed files with 9 additions and 11 deletions

View file

@ -3,6 +3,7 @@
- On Windows, fix bug where `RedrawRequested` would only get emitted every other iteration of the event loop. - 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. - On X11, fix deadlock on window state when handling certain window events.
- `WindowBuilder` now implements `Default`. - `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) # 0.20.0 (2020-01-05)

View file

@ -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 /// (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 /// 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. /// acceleration, it should not be used to implement non-cursor-like interactions such as 3D camera control.
position: PhysicalPosition<i32>, position: PhysicalPosition<f64>,
#[deprecated = "Deprecated in favor of DeviceEvent::ModifiersChanged"] #[deprecated = "Deprecated in favor of DeviceEvent::ModifiersChanged"]
modifiers: ModifiersState, modifiers: ModifiersState,
}, },

View file

@ -723,8 +723,7 @@ impl<T: 'static> EventProcessor<T> {
util::maybe_change(&mut shared_state_lock.cursor_pos, new_cursor_pos) util::maybe_change(&mut shared_state_lock.cursor_pos, new_cursor_pos)
}); });
if cursor_moved == Some(true) { if cursor_moved == Some(true) {
let position = let position = PhysicalPosition::new(xev.event_x, xev.event_y);
PhysicalPosition::new(xev.event_x as i32, xev.event_y as i32);
callback(Event::WindowEvent { callback(Event::WindowEvent {
window_id, window_id,
@ -830,8 +829,7 @@ impl<T: 'static> EventProcessor<T> {
event: CursorEntered { device_id }, event: CursorEntered { device_id },
}); });
let position = let position = PhysicalPosition::new(xev.event_x, xev.event_y);
PhysicalPosition::new(xev.event_x as i32, xev.event_y as i32);
// The mods field on this event isn't actually populated, so query the // 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 // pointer device. In the future, we can likely remove this round-trip by
@ -899,8 +897,7 @@ impl<T: 'static> EventProcessor<T> {
.map(|device| device.attachment) .map(|device| device.attachment)
.unwrap_or(2); .unwrap_or(2);
let position = let position = PhysicalPosition::new(xev.event_x, xev.event_y);
PhysicalPosition::new(xev.event_x as i32, xev.event_y as i32);
callback(Event::WindowEvent { callback(Event::WindowEvent {
window_id, window_id,

View file

@ -207,7 +207,7 @@ impl Canvas {
pub fn on_cursor_move<F>(&mut self, mut handler: F) pub fn on_cursor_move<F>(&mut self, mut handler: F)
where where
F: 'static + FnMut(i32, PhysicalPosition<i32>, ModifiersState), F: 'static + FnMut(i32, PhysicalPosition<f64>, ModifiersState),
{ {
// todo // todo
self.on_cursor_move = Some(self.add_event(move |event: PointerMoveEvent| { self.on_cursor_move = Some(self.add_event(move |event: PointerMoveEvent| {

View file

@ -216,7 +216,7 @@ impl Canvas {
pub fn on_cursor_move<F>(&mut self, mut handler: F) pub fn on_cursor_move<F>(&mut self, mut handler: F)
where where
F: 'static + FnMut(i32, PhysicalPosition<i32>, ModifiersState), F: 'static + FnMut(i32, PhysicalPosition<f64>, ModifiersState),
{ {
self.on_cursor_move = Some(self.add_event("pointermove", move |event: PointerEvent| { self.on_cursor_move = Some(self.add_event("pointermove", move |event: PointerEvent| {
handler( handler(

View file

@ -855,8 +855,8 @@ unsafe extern "system" fn public_window_callback<T: 'static>(
}); });
} }
let x = windowsx::GET_X_LPARAM(lparam) as i32; let x = windowsx::GET_X_LPARAM(lparam) as f64;
let y = windowsx::GET_Y_LPARAM(lparam) as i32; let y = windowsx::GET_Y_LPARAM(lparam) as f64;
let position = PhysicalPosition::new(x, y); let position = PhysicalPosition::new(x, y);
subclass_input.send_event(Event::WindowEvent { subclass_input.send_event(Event::WindowEvent {