On Wayland, fix coordinates in touch events when scale factor isn't 1 (#1439)

* On Wayland, fix coordinates in touch events when scale factor isn't 1

* Explicitly state that Wayland is using LogicalPosition internally

* Fix CHANGELOG
This commit is contained in:
Kirill Chibisov 2020-02-08 11:25:08 +03:00 committed by GitHub
parent 28f0eb598d
commit 4eddd1e5bc
3 changed files with 46 additions and 18 deletions

View file

@ -1,5 +1,7 @@
# Unreleased # Unreleased
- On Wayland, fix coordinates in touch events when scale factor isn't 1
# 0.21.0 (2020-02-04) # 0.21.0 (2020-02-04)
- On Windows, fixed "error: linking with `link.exe` failed: exit code: 1120" error on older versions of windows. - On Windows, fixed "error: linking with `link.exe` failed: exit code: 1120" error on older versions of windows.

View file

@ -1,5 +1,6 @@
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use crate::dpi::LogicalPosition;
use crate::event::{ use crate::event::{
DeviceEvent, ElementState, ModifiersState, MouseButton, MouseScrollDelta, TouchPhase, DeviceEvent, ElementState, ModifiersState, MouseButton, MouseScrollDelta, TouchPhase,
WindowEvent, WindowEvent,
@ -76,13 +77,16 @@ pub fn implement_pointer(
}, },
wid, wid,
); );
let position = LogicalPosition::new(surface_x, surface_y)
.to_physical(scale_factor);
sink.send_window_event( sink.send_window_event(
WindowEvent::CursorMoved { WindowEvent::CursorMoved {
device_id: crate::event::DeviceId( device_id: crate::event::DeviceId(
crate::platform_impl::DeviceId::Wayland(DeviceId), crate::platform_impl::DeviceId::Wayland(DeviceId),
), ),
position: (surface_x * scale_factor, surface_y * scale_factor) position,
.into(),
modifiers: modifiers_tracker.lock().unwrap().clone(), modifiers: modifiers_tracker.lock().unwrap().clone(),
}, },
wid, wid,
@ -109,15 +113,18 @@ pub fn implement_pointer(
.. ..
} => { } => {
if let Some(surface) = mouse_focus.as_ref() { if let Some(surface) = mouse_focus.as_ref() {
let scale_factor = surface::get_dpi_factor(&surface) as f64;
let wid = make_wid(surface); let wid = make_wid(surface);
let scale_factor = surface::get_dpi_factor(&surface) as f64;
let position = LogicalPosition::new(surface_x, surface_y)
.to_physical(scale_factor);
sink.send_window_event( sink.send_window_event(
WindowEvent::CursorMoved { WindowEvent::CursorMoved {
device_id: crate::event::DeviceId( device_id: crate::event::DeviceId(
crate::platform_impl::DeviceId::Wayland(DeviceId), crate::platform_impl::DeviceId::Wayland(DeviceId),
), ),
position: (surface_x * scale_factor, surface_y * scale_factor) position,
.into(),
modifiers: modifiers_tracker.lock().unwrap().clone(), modifiers: modifiers_tracker.lock().unwrap().clone(),
}, },
wid, wid,

View file

@ -1,17 +1,22 @@
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use crate::dpi::LogicalPosition;
use crate::event::{TouchPhase, WindowEvent}; use crate::event::{TouchPhase, WindowEvent};
use super::{event_loop::EventsSink, window::WindowStore, DeviceId, WindowId}; use super::{event_loop::EventsSink, make_wid, window::WindowStore, DeviceId};
use smithay_client_toolkit::surface;
use smithay_client_toolkit::reexports::client::protocol::{ use smithay_client_toolkit::reexports::client::protocol::{
wl_seat, wl_seat,
wl_surface::WlSurface,
wl_touch::{Event as TouchEvent, WlTouch}, wl_touch::{Event as TouchEvent, WlTouch},
}; };
// location is in logical coordinates.
struct TouchPoint { struct TouchPoint {
wid: WindowId, surface: WlSurface,
location: (f64, f64), position: LogicalPosition<f64>,
id: i32, id: i32,
} }
@ -31,21 +36,24 @@ pub(crate) fn implement_touch(
} => { } => {
let wid = store.find_wid(&surface); let wid = store.find_wid(&surface);
if let Some(wid) = wid { if let Some(wid) = wid {
let scale_factor = surface::get_dpi_factor(&surface) as f64;
let position = LogicalPosition::new(x, y);
sink.send_window_event( sink.send_window_event(
WindowEvent::Touch(crate::event::Touch { WindowEvent::Touch(crate::event::Touch {
device_id: crate::event::DeviceId( device_id: crate::event::DeviceId(
crate::platform_impl::DeviceId::Wayland(DeviceId), crate::platform_impl::DeviceId::Wayland(DeviceId),
), ),
phase: TouchPhase::Started, phase: TouchPhase::Started,
location: (x, y).into(), location: position.to_physical(scale_factor),
force: None, // TODO force: None, // TODO
id: id as u64, id: id as u64,
}), }),
wid, wid,
); );
pending_ids.push(TouchPoint { pending_ids.push(TouchPoint {
wid, surface,
location: (x, y), position,
id, id,
}); });
} }
@ -54,52 +62,63 @@ pub(crate) fn implement_touch(
let idx = pending_ids.iter().position(|p| p.id == id); let idx = pending_ids.iter().position(|p| p.id == id);
if let Some(idx) = idx { if let Some(idx) = idx {
let pt = pending_ids.remove(idx); let pt = pending_ids.remove(idx);
let scale_factor = surface::get_dpi_factor(&pt.surface) as f64;
let location = pt.position.to_physical(scale_factor);
sink.send_window_event( sink.send_window_event(
WindowEvent::Touch(crate::event::Touch { WindowEvent::Touch(crate::event::Touch {
device_id: crate::event::DeviceId( device_id: crate::event::DeviceId(
crate::platform_impl::DeviceId::Wayland(DeviceId), crate::platform_impl::DeviceId::Wayland(DeviceId),
), ),
phase: TouchPhase::Ended, phase: TouchPhase::Ended,
location: pt.location.into(), location,
force: None, // TODO force: None, // TODO
id: id as u64, id: id as u64,
}), }),
pt.wid, make_wid(&pt.surface),
); );
} }
} }
TouchEvent::Motion { id, x, y, .. } => { TouchEvent::Motion { id, x, y, .. } => {
let pt = pending_ids.iter_mut().find(|p| p.id == id); let pt = pending_ids.iter_mut().find(|p| p.id == id);
if let Some(pt) = pt { if let Some(pt) = pt {
pt.location = (x, y); pt.position = LogicalPosition::new(x, y);
let scale_factor = surface::get_dpi_factor(&pt.surface) as f64;
let location = pt.position.to_physical(scale_factor);
sink.send_window_event( sink.send_window_event(
WindowEvent::Touch(crate::event::Touch { WindowEvent::Touch(crate::event::Touch {
device_id: crate::event::DeviceId( device_id: crate::event::DeviceId(
crate::platform_impl::DeviceId::Wayland(DeviceId), crate::platform_impl::DeviceId::Wayland(DeviceId),
), ),
phase: TouchPhase::Moved, phase: TouchPhase::Moved,
location: (x, y).into(), location,
force: None, // TODO force: None, // TODO
id: id as u64, id: id as u64,
}), }),
pt.wid, make_wid(&pt.surface),
); );
} }
} }
TouchEvent::Frame => (), TouchEvent::Frame => (),
TouchEvent::Cancel => { TouchEvent::Cancel => {
for pt in pending_ids.drain(..) { for pt in pending_ids.drain(..) {
let scale_factor = surface::get_dpi_factor(&pt.surface) as f64;
let location = pt.position.to_physical(scale_factor);
sink.send_window_event( sink.send_window_event(
WindowEvent::Touch(crate::event::Touch { WindowEvent::Touch(crate::event::Touch {
device_id: crate::event::DeviceId( device_id: crate::event::DeviceId(
crate::platform_impl::DeviceId::Wayland(DeviceId), crate::platform_impl::DeviceId::Wayland(DeviceId),
), ),
phase: TouchPhase::Cancelled, phase: TouchPhase::Cancelled,
location: pt.location.into(), location,
force: None, // TODO force: None, // TODO
id: pt.id as u64, id: pt.id as u64,
}), }),
pt.wid, make_wid(&pt.surface),
); );
} }
} }