Skip to content

Commit

Permalink
Work around touch up events delivered too late with certain Weston ve…
Browse files Browse the repository at this point in the history
…rsions

Weston <= 10 at least has a bug where the frame event isn't always sent
when the last touch point was released.

This is tracked in
https://gitlab.freedesktop.org/wayland/weston/-/issues/44 and it would
seem that
https://gitlab.freedesktop.org/wayland/weston/-/commit/5448580111b5ff992ce2603cb6e99b9f54db7ad8
may fix it.

Meanwhile, work around the issue by processing all buffered events when
there are no more active touch points.
  • Loading branch information
tronical authored and wash2 committed Mar 1, 2024
1 parent ace6907 commit 8708dd5
Showing 1 changed file with 41 additions and 11 deletions.
52 changes: 41 additions & 11 deletions src/seat/touch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ impl TouchData {
#[derive(Debug, Default)]
pub(crate) struct TouchDataInner {
events: Vec<TouchEvent>,
active_touch_points: Vec<i32>,
}

#[macro_export]
Expand Down Expand Up @@ -163,31 +164,60 @@ where
qh: &QueueHandle<D>,
) {
let udata = udata.touch_data();
match event {
let mut guard: std::sync::MutexGuard<'_, TouchDataInner> = udata.inner.lock().unwrap();

let mut save_event = false;
let mut process_events = false;

match &event {
// Buffer events until frame is received.
TouchEvent::Down { .. }
| TouchEvent::Up { .. }
| TouchEvent::Motion { .. }
TouchEvent::Down { id, .. } => {
save_event = true;
if let Err(insert_pos) = guard.active_touch_points.binary_search(id) {
guard.active_touch_points.insert(insert_pos, *id);
}
}
TouchEvent::Up { id, .. } => {
save_event = true;
if let Ok(remove_pos) = guard.active_touch_points.binary_search(id) {
guard.active_touch_points.remove(remove_pos);
}

// Weston doesn't always send a frame even after the last touch point was released:
// https://gitlab.freedesktop.org/wayland/weston/-/issues/44
// Work around this by processing pending events when there are no more touch points
// active.
if guard.active_touch_points.is_empty() {
process_events = true;
}
}
TouchEvent::Motion { .. }
| TouchEvent::Shape { .. }
| TouchEvent::Orientation { .. } => {
let mut guard = udata.inner.lock().unwrap();
guard.events.push(event);
save_event = true;
}
// Process all buffered events.
TouchEvent::Frame => {
let mut guard = udata.inner.lock().unwrap();
for event in guard.events.drain(..) {
process_framed_event(data, touch, conn, qh, event);
}
process_events = true;
}
TouchEvent::Cancel => {
let mut guard = udata.inner.lock().unwrap();
guard.events.clear();
guard.active_touch_points.clear();

data.cancel(conn, qh, touch);
}
_ => unreachable!(),
}

if save_event {
guard.events.push(event);
}

if process_events {
for event in guard.events.drain(..) {
process_framed_event(data, touch, conn, qh, event);
}
}
}
}

Expand Down

0 comments on commit 8708dd5

Please sign in to comment.