@@ -1415,6 +1415,11 @@ handle_mouse_move_event(_GLFWwindow *window, const int x, const int y) {
14151415 window -> x11 .lastCursorPosY = y ;
14161416}
14171417
1418+ static bool
1419+ number_has_fractional_part (double x ) {
1420+ return fabs (x - round (x )) >= 1e-6 ;
1421+ }
1422+
14181423static void
14191424handle_xi_motion_event (_GLFWwindow * window , XIDeviceEvent * de ) {
14201425 XIScrollDevice * d = NULL ;
@@ -1442,24 +1447,35 @@ handle_xi_motion_event(_GLFWwindow *window, XIDeviceEvent *de) {
14421447 scroll_valuator_found = true;
14431448 double delta = value - v -> value ;
14441449 v -> value = value ;
1445- if ( v -> is_vertical ) delta *= -1 ;
1450+ delta *= -1 ;
14461451 double * off = v -> is_vertical ? & yOffset : & xOffset ;
14471452 * off = delta ;
1448- if (!d -> is_highres ) {
1449- if (v -> increment == 120. ) type = GLFW_SCROLL_OFFEST_V120 ;
1450- else {
1451- // XInput2 has no reliable way to distinguish high res scroll devices so we
1452- // assume that if fractional values are seen it must be high res. Sigh, Linux, the
1453- // land of truly wondrous wonders. See https://github.com/kovidgoyal/kitty/issues/9649
1454- double int_part ; bool delta_is_fractional = modf (delta , & int_part ) != 0. ;
1455- if (delta_is_fractional ) d -> is_highres = true;
1456- else {
1457- type = GLFW_SCROLL_OFFSET_LINES ;
1458- if (v -> increment != 0 ) * off /= v -> increment ;
1453+ d -> num_events ++ ;
1454+ if (!d -> type_detected ) {
1455+ if (v -> increment == 120. ) {
1456+ d -> type_detected = true;
1457+ d -> offset_type = GLFW_SCROLL_OFFEST_V120 ;
1458+ } else {
1459+ bool delta_is_fractional = number_has_fractional_part (delta );
1460+ if (delta_is_fractional ) {
1461+ if (fabs (delta * 120 - round (delta * 120 )) < 0.01 ) {
1462+ d -> type_detected = d -> num_events > 2 ;
1463+ d -> offset_type = GLFW_SCROLL_OFFEST_V120 ;
1464+ } else {
1465+ d -> type_detected = true;
1466+ d -> offset_type = GLFW_SCROLL_OFFEST_HIGHRES ;
1467+ }
1468+ } else {
1469+ d -> type_detected = d -> num_events > 2 ;
1470+ d -> offset_type = GLFW_SCROLL_OFFSET_LINES ;
14591471 }
14601472 }
14611473 }
1474+ if (d -> offset_type == GLFW_SCROLL_OFFSET_LINES ) {
1475+ if (v -> increment != 0 ) * off /= v -> increment ;
1476+ }
14621477 }
1478+ type = d -> offset_type ;
14631479 if (xOffset != 0 || yOffset != 0 ) {
14641480 // Get keyboard modifiers
14651481 int mods = translateState (de -> mods .effective );
@@ -1473,7 +1489,7 @@ handle_xi_motion_event(_GLFWwindow *window, XIDeviceEvent *de) {
14731489 };
14741490
14751491 // For high-resolution, finger-based scrolling, use timer-based momentum scrolling
1476- if (d -> is_highres && d -> is_finger_based && type == GLFW_SCROLL_OFFEST_HIGHRES ) {
1492+ if (d -> is_finger_based && type == GLFW_SCROLL_OFFEST_HIGHRES ) {
14771493 // Reset the timer on each scroll event
14781494 x11_cancel_momentum_scroll_timer ();
14791495
0 commit comments