backend.input: keep sub-pixel precision in events

libinput provides sub-pixel precision for pointer motion & touch events.
Keep this precision by switching all coordinates values from input
events to f64 (rather than i32 or u32). Otherwise, values are rounded
and part of the movment is lost.

Potentially fixes #224
This commit is contained in:
Victor Berger 2020-07-12 20:08:44 +02:00 committed by Victor Berger
parent 25365ed69a
commit 49dda88c63
4 changed files with 53 additions and 54 deletions

View File

@ -132,7 +132,7 @@ impl AnvilState {
let screen_size = self.current_output_size(x);
// monitor coordinates
let (ux, uy) = evt.position_transformed(screen_size);
((ux + self.current_output_offset(x)) as f64, uy as f64)
(ux + self.current_output_offset(x) as f64, uy as f64)
} else {
// we are started in winit
evt.position()

View File

@ -243,22 +243,22 @@ impl PointerAxisEvent for UnusedEvent {
/// Trait for pointer events generated by relative device movement.
pub trait PointerMotionEvent: Event {
/// Delta between the last and new pointer device position interpreted as pixel movement
fn delta(&self) -> (i32, i32) {
fn delta(&self) -> (f64, f64) {
(self.delta_x(), self.delta_y())
}
/// Delta on the x axis between the last and new pointer device position interpreted as pixel movement
fn delta_x(&self) -> i32;
fn delta_x(&self) -> f64;
/// Delta on the y axis between the last and new pointer device position interpreted as pixel movement
fn delta_y(&self) -> i32;
fn delta_y(&self) -> f64;
}
impl PointerMotionEvent for UnusedEvent {
fn delta_x(&self) -> i32 {
fn delta_x(&self) -> f64 {
match *self {}
}
fn delta_y(&self) -> i32 {
fn delta_y(&self) -> f64 {
match *self {}
}
}
@ -284,7 +284,7 @@ pub trait PointerMotionAbsoluteEvent: Event {
/// Device position converted to the targets coordinate space.
/// E.g. the focused output's resolution.
fn position_transformed(&self, coordinate_space: (u32, u32)) -> (u32, u32) {
fn position_transformed(&self, coordinate_space: (u32, u32)) -> (f64, f64) {
(
self.x_transformed(coordinate_space.0),
self.y_transformed(coordinate_space.1),
@ -293,11 +293,11 @@ pub trait PointerMotionAbsoluteEvent: Event {
/// Device x position converted to the targets coordinate space's width.
/// E.g. the focused output's width.
fn x_transformed(&self, width: u32) -> u32;
fn x_transformed(&self, width: u32) -> f64;
/// Device y position converted to the targets coordinate space's height.
/// E.g. the focused output's height.
fn y_transformed(&self, height: u32) -> u32;
fn y_transformed(&self, height: u32) -> f64;
}
impl PointerMotionAbsoluteEvent for UnusedEvent {
@ -309,11 +309,11 @@ impl PointerMotionAbsoluteEvent for UnusedEvent {
match *self {}
}
fn x_transformed(&self, _width: u32) -> u32 {
fn x_transformed(&self, _width: u32) -> f64 {
match *self {}
}
fn y_transformed(&self, _height: u32) -> u32 {
fn y_transformed(&self, _height: u32) -> f64 {
match *self {}
}
}
@ -348,7 +348,7 @@ pub trait TouchDownEvent: Event {
/// Touch position converted into the target coordinate space.
/// E.g. the focused output's resolution.
fn position_transformed(&self, coordinate_space: (u32, u32)) -> (u32, u32) {
fn position_transformed(&self, coordinate_space: (u32, u32)) -> (f64, f64) {
(
self.x_transformed(coordinate_space.0),
self.y_transformed(coordinate_space.1),
@ -367,11 +367,11 @@ pub trait TouchDownEvent: Event {
/// Touch event's x position converted to the targets coordinate space's width.
/// E.g. the focused output's width.
fn x_transformed(&self, width: u32) -> u32;
fn x_transformed(&self, width: u32) -> f64;
/// Touch event's y position converted to the targets coordinate space's width.
/// E.g. the focused output's width.
fn y_transformed(&self, height: u32) -> u32;
fn y_transformed(&self, height: u32) -> f64;
}
impl TouchDownEvent for UnusedEvent {
@ -387,11 +387,11 @@ impl TouchDownEvent for UnusedEvent {
match *self {}
}
fn x_transformed(&self, _width: u32) -> u32 {
fn x_transformed(&self, _width: u32) -> f64 {
match *self {}
}
fn y_transformed(&self, _height: u32) -> u32 {
fn y_transformed(&self, _height: u32) -> f64 {
match *self {}
}
}
@ -410,7 +410,7 @@ pub trait TouchMotionEvent: Event {
/// Touch position converted into the target coordinate space.
/// E.g. the focused output's resolution.
fn position_transformed(&self, coordinate_space: (u32, u32)) -> (u32, u32) {
fn position_transformed(&self, coordinate_space: (u32, u32)) -> (f64, f64) {
(
self.x_transformed(coordinate_space.0),
self.y_transformed(coordinate_space.1),
@ -429,11 +429,11 @@ pub trait TouchMotionEvent: Event {
/// Touch event's x position converted to the targets coordinate space's width.
/// E.g. the focused output's width.
fn x_transformed(&self, width: u32) -> u32;
fn x_transformed(&self, width: u32) -> f64;
/// Touch event's y position converted to the targets coordinate space's width.
/// E.g. the focused output's width.
fn y_transformed(&self, height: u32) -> u32;
fn y_transformed(&self, height: u32) -> f64;
}
impl TouchMotionEvent for UnusedEvent {
@ -449,11 +449,11 @@ impl TouchMotionEvent for UnusedEvent {
match *self {}
}
fn x_transformed(&self, _width: u32) -> u32 {
fn x_transformed(&self, _width: u32) -> f64 {
match *self {}
}
fn y_transformed(&self, _height: u32) -> u32 {
fn y_transformed(&self, _height: u32) -> f64 {
match *self {}
}
}

View File

@ -152,11 +152,11 @@ impl backend::Event for event::pointer::PointerMotionEvent {
}
impl backend::PointerMotionEvent for event::pointer::PointerMotionEvent {
fn delta_x(&self) -> i32 {
self.dx() as i32
fn delta_x(&self) -> f64 {
self.dx()
}
fn delta_y(&self) -> i32 {
self.dy() as i32
fn delta_y(&self) -> f64 {
self.dy()
}
}
@ -175,12 +175,12 @@ impl backend::PointerMotionAbsoluteEvent for event::pointer::PointerMotionAbsolu
self.absolute_y()
}
fn x_transformed(&self, width: u32) -> u32 {
self.absolute_x_transformed(width) as u32
fn x_transformed(&self, width: u32) -> f64 {
self.absolute_x_transformed(width)
}
fn y_transformed(&self, height: u32) -> u32 {
self.absolute_y_transformed(height) as u32
fn y_transformed(&self, height: u32) -> f64 {
self.absolute_y_transformed(height)
}
}
@ -203,12 +203,12 @@ impl backend::TouchDownEvent for event::touch::TouchDownEvent {
event::touch::TouchEventPosition::y(self)
}
fn x_transformed(&self, width: u32) -> u32 {
event::touch::TouchEventPosition::x_transformed(self, width) as u32
fn x_transformed(&self, width: u32) -> f64 {
event::touch::TouchEventPosition::x_transformed(self, width)
}
fn y_transformed(&self, height: u32) -> u32 {
event::touch::TouchEventPosition::y_transformed(self, height) as u32
fn y_transformed(&self, height: u32) -> f64 {
event::touch::TouchEventPosition::y_transformed(self, height)
}
}
@ -231,12 +231,12 @@ impl backend::TouchMotionEvent for event::touch::TouchMotionEvent {
event::touch::TouchEventPosition::y(self)
}
fn x_transformed(&self, width: u32) -> u32 {
event::touch::TouchEventPosition::x_transformed(self, width) as u32
fn x_transformed(&self, width: u32) -> f64 {
event::touch::TouchEventPosition::x_transformed(self, width)
}
fn y_transformed(&self, height: u32) -> u32 {
event::touch::TouchEventPosition::y_transformed(self, height) as u32
fn y_transformed(&self, height: u32) -> f64 {
event::touch::TouchEventPosition::y_transformed(self, height)
}
}

View File

@ -15,7 +15,6 @@ use crate::backend::{
use nix::libc::c_void;
use std::{
cell::{Ref, RefCell},
cmp,
convert::TryInto,
rc::Rc,
time::Instant,
@ -415,16 +414,16 @@ impl PointerMotionAbsoluteEvent for WinitMouseMovedEvent {
self.logical_position.y * wsize.scale_factor
}
fn x_transformed(&self, width: u32) -> u32 {
fn x_transformed(&self, width: u32) -> f64 {
let wsize = self.size.borrow();
let w_width = wsize.physical_size.to_logical::<f64>(wsize.scale_factor).width;
cmp::max((self.logical_position.x * width as f64 / w_width) as i32, 0) as u32
f64::max(self.logical_position.x * width as f64 / w_width, 0.0)
}
fn y_transformed(&self, height: u32) -> u32 {
fn y_transformed(&self, height: u32) -> f64 {
let wsize = self.size.borrow();
let w_height = wsize.physical_size.to_logical::<f64>(wsize.scale_factor).height;
cmp::max((self.logical_position.y * height as f64 / w_height) as i32, 0) as u32
f64::max(self.logical_position.y * height as f64 / w_height, 0.0)
}
}
@ -520,16 +519,16 @@ impl TouchDownEvent for WinitTouchStartedEvent {
self.location.1 * wsize.scale_factor
}
fn x_transformed(&self, width: u32) -> u32 {
fn x_transformed(&self, width: u32) -> f64 {
let wsize = self.size.borrow();
let w_width = wsize.physical_size.to_logical::<i32>(wsize.scale_factor).width;
cmp::min(self.location.0 as i32 * width as i32 / w_width, 0) as u32
let w_width = wsize.physical_size.to_logical::<f64>(wsize.scale_factor).width;
f64::max(self.location.0 * width as f64 / w_width, 0.0)
}
fn y_transformed(&self, height: u32) -> u32 {
fn y_transformed(&self, height: u32) -> f64 {
let wsize = self.size.borrow();
let w_height = wsize.physical_size.to_logical::<i32>(wsize.scale_factor).height;
cmp::min(self.location.1 as i32 * height as i32 / w_height, 0) as u32
let w_height = wsize.physical_size.to_logical::<f64>(wsize.scale_factor).height;
f64::max(self.location.1 * height as f64 / w_height, 0.0)
}
}
@ -563,16 +562,16 @@ impl TouchMotionEvent for WinitTouchMovedEvent {
self.location.1 * wsize.scale_factor
}
fn x_transformed(&self, width: u32) -> u32 {
fn x_transformed(&self, width: u32) -> f64 {
let wsize = self.size.borrow();
let w_width = wsize.physical_size.to_logical::<u32>(wsize.scale_factor).width;
self.location.0 as u32 * width / w_width
let w_width = wsize.physical_size.to_logical::<f64>(wsize.scale_factor).width;
f64::max(self.location.0 * width as f64 / w_width, 0.0)
}
fn y_transformed(&self, height: u32) -> u32 {
fn y_transformed(&self, height: u32) -> f64 {
let wsize = self.size.borrow();
let w_height = wsize.physical_size.to_logical::<u32>(wsize.scale_factor).height;
self.location.1 as u32 * height / w_height
let w_height = wsize.physical_size.to_logical::<f64>(wsize.scale_factor).height;
f64::max(self.location.1 * height as f64 / w_height, 0.0)
}
}