From a58400a82c9506200a4f68d8837bafb676235604 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Mon, 11 Apr 2022 19:13:28 +0200 Subject: [PATCH] Fix `TouchPhase::Ended` reporting on Wayland When all the receive from the compositor is `TouchEvent::Down` and `TouchEvent::Up` for the same id, we would record the touch position in the touch_points vector the first time. On `TouchEvent::Up` we'd find it and report `TouchPhase::Ended` with that location. The next time we receive `TouchEvent::Down` for the same id, we'd however unconditionally append a new `TouchPoint` to `inner.touch_points`, with the new position. On release however we'd find the earlier point and report its location, which basically means that `TouchPhase::Ended` always and forever reported the location of the very first touch down event. Instead, this patch updates an existing touch point location with the same id on `TouchDown`. Fixes #1996 --- CHANGELOG.md | 2 ++ .../linux/wayland/seat/touch/handlers.rs | 12 +++++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 82ce7aee..2235fa83 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,8 @@ And please only add new entries to the top of this list, right below the `# Unre - On Windows, fix race issue creating fullscreen windows with `WindowBuilder::with_fullscreen` - On Android, `virtual_keycode` for `KeyboardInput` events is now filled in where a suitable match is found. - Added helper methods on `ControlFlow` to set its value. +- On Wayland, fix `TouchPhase::Ended` always reporting the location of the first touch down, unless the compositor + sent a cancel or frame event. # 0.26.1 (2022-01-05) diff --git a/src/platform_impl/linux/wayland/seat/touch/handlers.rs b/src/platform_impl/linux/wayland/seat/touch/handlers.rs index 8a17b393..d8790944 100644 --- a/src/platform_impl/linux/wayland/seat/touch/handlers.rs +++ b/src/platform_impl/linux/wayland/seat/touch/handlers.rs @@ -44,9 +44,15 @@ pub(super) fn handle_touch( window_id, ); - inner - .touch_points - .push(TouchPoint::new(surface, position, id)); + // For `TouchEvent::Up` we don't receive a position, so we're tracking active + // touch points. Update either a known touch id or register a new one. + if let Some(i) = inner.touch_points.iter().position(|p| p.id == id) { + inner.touch_points[i].position = position; + } else { + inner + .touch_points + .push(TouchPoint::new(surface, position, id)); + } } TouchEvent::Up { id, .. } => { let touch_point = match inner.touch_points.iter().find(|p| p.id == id) {