From 9604dae2299f49b0803ca5e257df4c0f2862b717 Mon Sep 17 00:00:00 2001 From: Lucas Meurer Date: Tue, 18 Mar 2025 11:41:53 +0100 Subject: [PATCH] Fix kinetic scrolling on touch devices (#5778) Fixes kinetic scrolling on android (and possibly other touch devices), by calculating the final velocity before clearing the position history on PointerGone events. * Closes #5311 * [X] I have followed the instructions in the PR template --- crates/egui/src/input_state/mod.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/crates/egui/src/input_state/mod.rs b/crates/egui/src/input_state/mod.rs index 7864ce62..bc32528d 100644 --- a/crates/egui/src/input_state/mod.rs +++ b/crates/egui/src/input_state/mod.rs @@ -927,6 +927,7 @@ impl PointerState { self.motion = Some(Vec2::ZERO); } + let mut clear_history_after_velocity_calculation = false; for event in &new.events { match event { Event::PointerMoved(pos) => { @@ -1013,7 +1014,10 @@ impl PointerState { // When dragging a slider and the mouse leaves the viewport, we still want the drag to work, // so we don't treat this as a `PointerEvent::Released`. // NOTE: we do NOT clear `self.interact_pos` here. It will be cleared next frame. - self.pos_history.clear(); + + // Delay the clearing until after the final velocity calculation, so we can + // get the final velocity when `drag_stopped` is true. + clear_history_after_velocity_calculation = true; } Event::MouseMoved(delta) => *self.motion.get_or_insert(Vec2::ZERO) += *delta, _ => {} @@ -1044,6 +1048,9 @@ impl PointerState { if self.velocity != Vec2::ZERO { self.last_move_time = time; } + if clear_history_after_velocity_calculation { + self.pos_history.clear(); + } self.direction = self.pos_history.velocity().unwrap_or_default().normalized();