From 97213463878c84e23f6713892585398f3621eb4b Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 29 Mar 2026 14:43:48 +0530 Subject: [PATCH] XWayland: Fix a regression where some wheel mice were not scrolling properly We assume increment == 1 and delta * 120 == integer means we have V120 events in units of 1/120. Fixes #9770 --- docs/changelog.rst | 2 ++ glfw/x11_platform.h | 1 + glfw/x11_window.c | 16 ++++++++++++---- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index 0bde3d5ad..8e5128aa9 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -187,6 +187,8 @@ Detailed list of changes - X11: Fix a regression in the previous release that caused an occasional crash on input device removal (:iss:`9723`) +- XWayland: Fix a regression where some wheel mice were not scrolling properly (:pull:`9770`) + - Command palette: Improve searching to use word level matching (:pull:`9727`) - hints kitten: A new option to set the background color of matched text (:pull:`9745`) diff --git a/glfw/x11_platform.h b/glfw/x11_platform.h index fe78d17c8..d44a44f4e 100644 --- a/glfw/x11_platform.h +++ b/glfw/x11_platform.h @@ -247,6 +247,7 @@ typedef struct XIScrollDevice { char name[32]; unsigned num_events; GLFWOffsetType offset_type; + bool v120_offset_needs_scaling; } XIScrollDevice; typedef struct XdndSelectionRequest { diff --git a/glfw/x11_window.c b/glfw/x11_window.c index 6be8e14ca..1924f8abf 100644 --- a/glfw/x11_window.c +++ b/glfw/x11_window.c @@ -1466,15 +1466,17 @@ handle_xi_motion_event(_GLFWwindow *window, XIDeviceEvent *de) { *off = delta; d->num_events++; if (!d->type_detected) { + debug_input("Detecting scroll device type: delta: %.3f delta*120: %.3f v->increment: %.3f\n", delta, delta * 120, v->increment); if (v->increment == 120.) { d->type_detected = true; d->offset_type = GLFW_SCROLL_OFFEST_V120; + d->v120_offset_needs_scaling = false; } else { - bool delta_is_fractional = number_has_fractional_part(delta); - if (delta_is_fractional) { + if (number_has_fractional_part(delta)) { if (fabs(delta * 120 - round(delta * 120)) < 0.01) { d->type_detected = d->num_events > 2; d->offset_type = GLFW_SCROLL_OFFEST_V120; + d->v120_offset_needs_scaling = v->increment == 1.; } else { d->type_detected = true; d->offset_type = GLFW_SCROLL_OFFEST_HIGHRES; @@ -1485,8 +1487,14 @@ handle_xi_motion_event(_GLFWwindow *window, XIDeviceEvent *de) { } } } - if (d->offset_type == GLFW_SCROLL_OFFSET_LINES) { - if (v->increment != 0) *off /= v->increment; + if (v->increment != 0) { + if (d->offset_type == GLFW_SCROLL_OFFSET_LINES) { + *off /= v->increment; + } else if (d->offset_type == GLFW_SCROLL_OFFEST_V120 && d->v120_offset_needs_scaling) { + // On XWayland, scroll deltas are in scroll-increment units (typically + // where increment=1.0 means one line or one v120). + *off *= 120.; + } } } type = d->offset_type;