From 80a9bdb999ced0b9bb740e4de870ed15a0c2337f Mon Sep 17 00:00:00 2001 From: Evan Goode Date: Sun, 19 Oct 2025 11:09:02 -0400 Subject: [PATCH] Smoothly handle VALUE120 scroll events --- glfw/wl_init.c | 14 ++++++++------ kitty/mouse.c | 19 +++++++++++++++---- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/glfw/wl_init.c b/glfw/wl_init.c index d62aaafcf..eaa52d8de 100644 --- a/glfw/wl_init.c +++ b/glfw/wl_init.c @@ -202,21 +202,23 @@ pointer_handle_frame(void *data UNUSED, struct wl_pointer *pointer UNUSED) { _GLFWwindow* window = _glfw.wl.pointerFocus; if (!window) return; float x = 0, y = 0; - int highres = 0; + const int HIGHRES = 1; + const int VALUE120 = 1 << 4; + int flags = 0; if (info.discrete.y_axis_type != AXIS_EVENT_UNKNOWN) { y = info.discrete.y; - if (info.discrete.y_axis_type == AXIS_EVENT_VALUE120) y /= 120.f; + if (info.discrete.y_axis_type == AXIS_EVENT_VALUE120) flags |= VALUE120; } else if (info.continuous.y_axis_type != AXIS_EVENT_UNKNOWN) { - highres = 1; + flags |= HIGHRES; y = info.continuous.y; } if (info.discrete.x_axis_type != AXIS_EVENT_UNKNOWN) { x = info.discrete.x; - if (info.discrete.x_axis_type == AXIS_EVENT_VALUE120) x /= 120.f; + if (info.discrete.x_axis_type == AXIS_EVENT_VALUE120) flags |= VALUE120; } else if (info.continuous.x_axis_type != AXIS_EVENT_UNKNOWN) { - highres = 1; + flags |= HIGHRES; x = info.continuous.x; } /* clear pointer_curr_axis_info for next frame */ @@ -225,7 +227,7 @@ pointer_handle_frame(void *data UNUSED, struct wl_pointer *pointer UNUSED) { if (x != 0.0f || y != 0.0f) { float scale = (float)_glfwWaylandWindowScale(window); y *= scale; x *= scale; - _glfwInputScroll(window, -x, y, highres, _glfw.wl.xkb.states.modifiers); + _glfwInputScroll(window, -x, y, flags, _glfw.wl.xkb.states.modifiers); } } diff --git a/kitty/mouse.c b/kitty/mouse.c index 18193e6b4..92537857c 100644 --- a/kitty/mouse.c +++ b/kitty/mouse.c @@ -1162,7 +1162,7 @@ mouse_event(const int button, int modifiers, int action) { } static int -scale_scroll(MouseTrackingMode mouse_tracking_mode, double offset, bool is_high_resolution, double *pending_scroll_pixels, int cell_size) { +scale_scroll(MouseTrackingMode mouse_tracking_mode, double offset, bool is_high_resolution, bool is_value120, double *pending_scroll_pixels, int cell_size) { // scale the scroll by the multiplier unless the mouse is grabbed. If the mouse is grabbed only change direction. #define SCALE_SCROLL(which) { double scale = OPT(which); if (mouse_tracking_mode) scale /= fabs(scale); offset *= scale; } int s = 0; @@ -1175,6 +1175,16 @@ scale_scroll(MouseTrackingMode mouse_tracking_mode, double offset, bool is_high_ } s = (int)round(pixels) / cell_size; *pending_scroll_pixels = pixels - s * cell_size; + } else if (is_value120) { + SCALE_SCROLL(wheel_scroll_multiplier); + const double offset_lines = offset / 120.; + const double pixels = *pending_scroll_pixels + offset_lines * cell_size; + if (fabs(pixels) < cell_size) { + *pending_scroll_pixels = pixels; + return 0; + } + s = (int)round(pixels) / cell_size; + *pending_scroll_pixels = pixels - s * cell_size; } else { SCALE_SCROLL(wheel_scroll_multiplier); s = (int) round(offset); @@ -1253,10 +1263,11 @@ scroll_event(double xoffset, double yoffset, int flags, int modifiers) { break; } int s; - bool is_high_resolution = flags & 1; + const bool is_high_resolution = flags & 1; + const bool is_value120 = flags & (1 << 4); if (yoffset != 0.0) { - s = scale_scroll(screen->modes.mouse_tracking_mode, yoffset, is_high_resolution, &screen->pending_scroll_pixels_y, global_state.callback_os_window->fonts_data->fcm.cell_height); + s = scale_scroll(screen->modes.mouse_tracking_mode, yoffset, is_high_resolution, is_value120, &screen->pending_scroll_pixels_y, global_state.callback_os_window->fonts_data->fcm.cell_height); if (s) { bool upwards = s > 0; if (screen->modes.mouse_tracking_mode) { @@ -1277,7 +1288,7 @@ scroll_event(double xoffset, double yoffset, int flags, int modifiers) { } } if (xoffset != 0.0) { - s = scale_scroll(screen->modes.mouse_tracking_mode, xoffset, is_high_resolution, &screen->pending_scroll_pixels_x, global_state.callback_os_window->fonts_data->fcm.cell_width); + s = scale_scroll(screen->modes.mouse_tracking_mode, xoffset, is_high_resolution, is_value120, &screen->pending_scroll_pixels_x, global_state.callback_os_window->fonts_data->fcm.cell_width); if (s) { if (screen->modes.mouse_tracking_mode) { int sz = encode_mouse_scroll(w, s > 0 ? 6 : 7, modifiers);