From c25e10492a399ccdc6a33dd1e249b753c4d47266 Mon Sep 17 00:00:00 2001 From: John Drouhard Date: Thu, 24 Apr 2025 14:00:23 -0500 Subject: [PATCH] scroll: round up fractional mouse scroll ticks Scrolling with a mouse on macos doesn't work very well when doing small, single tick scrolls. macos attempts to mimic precision scrolling by changing the magnitude of the scroll deltas based on scrolling speed. Slow scrolls only send deltas with a magnitude of 0.1, which isn't enough to send a single scroll event with the default scroll multiplier of 3. Changing the scroll multiplier to 10 as a workaround (so even single small scroll ticks are enough to register a scroll event) cause scrolling to be way too fast if the scroll speed is ramped up. This commit causes the yoffset delta to be rounded out to at least a magnitude of 1 in the appropriate direction. For small single scroll ticks, it's enough to register a scroll event, but as scroll speed is ramped up, the true delta reported to the surface is used again. Setting a scroll multiplier of 1 with the changes here makes mouse scrolling feel just as good as trackpad precision scrolling. --- src/Surface.zig | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/Surface.zig b/src/Surface.zig index a4a8d46df..e5e2b39bc 100644 --- a/src/Surface.zig +++ b/src/Surface.zig @@ -2761,8 +2761,21 @@ pub fn scrollCallback( // that a wheel tick of 1 results in single scroll event. const yoff_adjusted: f64 = if (scroll_mods.precision) yoff - else - yoff * cell_size * self.config.mouse_scroll_multiplier; + else yoff_adjusted: { + // Round out the yoff to an absolute minimum of 1. macos tries to + // simulate precision scrolling with non precision events by + // ramping up the magnitude of the offsets as it detects faster + // scrolling. Single click (very slow) scrolls are reported with a + // magnitude of 0.1 which would normally require a few clicks + // before we register an actual scroll event (depending on cell + // height and the mouse_scroll_multiplier setting). + const yoff_max: f64 = if (yoff > 0) + @max(yoff, 1) + else + @min(yoff, -1); + + break :yoff_adjusted yoff_max * cell_size * self.config.mouse_scroll_multiplier; + }; // Add our previously saved pending amount to the offset to get the // new offset value. The signs of the pending and yoff should match