From 7bd3d9e82f69f810d97d36e63199815f2d3638cd Mon Sep 17 00:00:00 2001 From: Harald Date: Mon, 9 Nov 2026 22:34:27 +0100 Subject: [PATCH] fix(touch): hand on a touch lift without waiting for the next frame (Issues #28, #55) Co-Authored-By: Claude Opus 5.5 --- vendor/winit/README.ink-notes.md | 4 ++ .../linux/wayland/seat/touch/mod.rs | 38 +++++++++++++++++-- 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/vendor/winit/README.ink-notes.md b/vendor/winit/README.ink-notes.md index 0ffaf53..69f43c8 100644 --- a/vendor/winit/README.ink-notes.md +++ b/vendor/winit/README.ink-notes.md @@ -22,6 +22,10 @@ docs of the original crate were removed. the app (`AboutToWait`), also when the events belong to another queue on the same connection. octotablet's pen events live on such a queue and only `dispatch_pending` it, so before, pen strokes waited until something else woke the loop (Issue #53). +- `src/platform_impl/linux/wayland/seat/touch/mod.rs`: a touch lift (`wl_touch.up`) is handed + on right away instead of waiting for the next `wl_touch.frame`. On a GNOME laptop the lift + of a swipe only arrived with the next touch, which fits a frame sent before the lift: the page did not glide after a + swipe (Issue #28), and a ruler moved with the finger followed the hovering pen (Issue #55). - `Cargo.toml`: `[lints.rust] warnings = "allow"`, because a path dependency is not built with capped lints like a crates.io dependency. diff --git a/vendor/winit/src/platform_impl/linux/wayland/seat/touch/mod.rs b/vendor/winit/src/platform_impl/linux/wayland/seat/touch/mod.rs index f160738..00e4b6c 100644 --- a/vendor/winit/src/platform_impl/linux/wayland/seat/touch/mod.rs +++ b/vendor/winit/src/platform_impl/linux/wayland/seat/touch/mod.rs @@ -2,14 +2,15 @@ use sctk::reexports::client::protocol::wl_seat::WlSeat; use sctk::reexports::client::protocol::wl_surface::WlSurface; -use sctk::reexports::client::protocol::wl_touch::WlTouch; -use sctk::reexports::client::{Connection, Proxy, QueueHandle}; +use sctk::reexports::client::protocol::wl_touch::{self, WlTouch}; +use sctk::reexports::client::{Connection, Dispatch, Proxy, QueueHandle}; use sctk::reexports::csd_frame::FrameClick; use std::time::Duration; use sctk::compositor::SurfaceData; use sctk::seat::touch::{TouchData, TouchHandler}; +use sctk::seat::SeatState; use crate::dpi::LogicalPosition; use crate::event::{Touch, TouchPhase, WindowEvent}; @@ -286,4 +287,35 @@ impl TouchDataExt for WlTouch { } } -sctk::delegate_touch!(WinitState); +// ink-notes patch: sctk holds every touch event back until the compositor sends the +// `wl_touch.frame` that closes its group. On a GNOME laptop the lift of a swipe only arrived +// together with the next touch, which fits a frame sent before the matching `up`: the page could +// not glide (Issue #28) and a ruler moved with the finger followed the hovering pen (Issue #55). +// A lift is now handed on right away, after the events that came before it. +impl Dispatch for WinitState { + fn event( + state: &mut Self, + touch: &WlTouch, + event: wl_touch::Event, + data: &TouchData, + conn: &Connection, + qh: &QueueHandle, + ) { + if let wl_touch::Event::Up { serial, time, id } = event { + // Hand on what sctk still holds, then the lift itself + >::event( + state, + touch, + wl_touch::Event::Frame, + data, + conn, + qh, + ); + state.up(conn, qh, touch, serial, time, id); + } else { + >::event( + state, touch, event, data, conn, qh, + ); + } + } +}