From 3232551c399440b6d51556a8f35db0342424f9e2 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 9 Jan 2026 13:10:16 +0530 Subject: [PATCH] Revert to using a fixed timer interval Sadly, we cant rely on the Wayland compositor to send us reliably timed scroll events. --- glfw/momentum-scroll.c | 25 +++++++------------------ 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/glfw/momentum-scroll.c b/glfw/momentum-scroll.c index 398a74f03..6922ab4b3 100644 --- a/glfw/momentum-scroll.c +++ b/glfw/momentum-scroll.c @@ -24,13 +24,13 @@ typedef struct MomentumScroller { min_velocity, // Minimum velocity before stopping max_velocity, // Maximum velocity to prevent runaway scrolling velocity_scale; // Scale factor for initial velocity + monotonic_t timer_interval; // animation speed GLFWid timer_id, window_id; ScrollSamples samples; ScrollerState state; struct { double x, y; } velocity; int keyboard_modifiers; - monotonic_t timer_interval; struct { monotonic_t start, duration; struct { double x, y; } displacement; @@ -42,11 +42,13 @@ static const MomentumScroller defaults = { .min_velocity = 0.5, .max_velocity = 100, .velocity_scale = 0.9, + .timer_interval = 10, }; static MomentumScroller s = defaults; GLFWAPI void -glfwConfigureMomentumScroller(double friction, double min_velocity, double max_velocity, double velocity_scale) { +glfwConfigureMomentumScroller(double friction, double min_velocity, double max_velocity, double velocity_scale, unsigned timer_interval_ms) { + s.timer_interval = ms_to_monotonic_t(timer_interval_ms); #define S(w) s.w = w >= 0 ? w : defaults.w S(friction); S(min_velocity); S(max_velocity); S(velocity_scale); #undef S @@ -118,29 +120,17 @@ set_velocity_from_samples(monotonic_t now) { monotonic_t first_time = deque_peek_front(&s.samples)->timestamp; monotonic_t last_time = deque_peek_back(&s.samples)->timestamp; double time_span = MAX(1, last_time - first_time); - double total_time_between_events = 0; - monotonic_t prev_timestamp = 0; - double ts_weight = 0; for (size_t i = 0; i < deque_size(&s.samples); i++) { const ScrollSample *ss = deque_at(&s.samples, i); double weight = 1.0 + (ss->timestamp - first_time) / time_span; total_dx += ss->dx * weight; total_dy += ss->dy * weight; total_weight += weight; - if (prev_timestamp) { - monotonic_t t = ss->timestamp - prev_timestamp; - total_time_between_events += t * weight; - ts_weight += weight; - } - prev_timestamp = ss->timestamp; } deque_clear(&s.samples); - if (ts_weight <= 0) return; - s.timer_interval = (monotonic_t)(total_time_between_events / ts_weight); + if (total_weight <= 0) return; double dy = total_dy / total_weight, dx = total_dx / total_weight; add_velocity(dx * s.velocity_scale, dy * s.velocity_scale); - if (false) timed_debug_print( - "momentum scroll: event velocity: %.1f final velocity: %.1f interval: %d ms\n", - dy, s.velocity.y, monotonic_t_to_ms(s.timer_interval)); + if (false) timed_debug_print("momentum scroll: event velocity: %.1f final velocity: %.1f\n", dy, s.velocity.y); } static void @@ -205,9 +195,8 @@ glfw_handle_scroll_event_for_momentum( s.physical_event.start = 0; } } else { + memset(&s.physical_event, 0, sizeof(s.physical_event)); s.physical_event.start = now; - s.physical_event.displacement.x = 0; - s.physical_event.displacement.y = 0; } if (s.window_id && s.window_id != w->id) cancel_existing_scroll(true); if (s.state != PHYSICAL_EVENT_IN_PROGRESS) cancel_existing_scroll(false);