From c95a32def80e73b1e789c7109d48a6986379a65e Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Wed, 16 Dec 2020 14:07:13 +0100 Subject: [PATCH] gdk/x11: Transform XI_Motion based scroll into discrete Depending on the input driver, we will get XI_Motion based scroll events for regular mouse wheels. These are intended to be handled as discrete scroll, so detect smooth scroll events that move by exactly 1.0 in either direction. Fixes: https://gitlab.gnome.org/GNOME/gtk/-/issues/3459 --- gdk/x11/gdkdevicemanager-xi2.c | 46 ++++++++++++++++++++++++++++------ 1 file changed, 38 insertions(+), 8 deletions(-) diff --git a/gdk/x11/gdkdevicemanager-xi2.c b/gdk/x11/gdkdevicemanager-xi2.c index 8e6c05d15c..3165205a5f 100644 --- a/gdk/x11/gdkdevicemanager-xi2.c +++ b/gdk/x11/gdkdevicemanager-xi2.c @@ -1716,19 +1716,49 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator, scroll_valuators_changed (GDK_X11_DEVICE_XI2 (source_device), &xev->valuators, &delta_x, &delta_y)) { + GdkModifierType state; + GDK_DISPLAY_NOTE (display, EVENTS, g_message ("smooth scroll: \n\tdevice: %u\n\tsource device: %u\n\twindow %ld\n\tdeltas: %f %f", xev->deviceid, xev->sourceid, xev->event, delta_x, delta_y)); - event = gdk_scroll_event_new (surface, - device, - NULL, - xev->time, - _gdk_x11_device_xi2_translate_state (&xev->mods, &xev->buttons, &xev->group), - delta_x, - delta_y, - delta_x == 0.0 && delta_y == 0.0); + state = _gdk_x11_device_xi2_translate_state (&xev->mods, &xev->buttons, &xev->group); + + if (gdk_device_get_source (source_device) != GDK_SOURCE_TOUCHPAD && + ((delta_x == 0.0 && ABS (delta_y) == 1.0) || + (ABS (delta_x) == 1.0 && delta_y == 0.0))) + { + GdkScrollDirection direction; + + if (delta_x > 0) + direction = GDK_SCROLL_RIGHT; + else if (delta_x < 0) + direction = GDK_SCROLL_LEFT; + else if (delta_y > 0) + direction = GDK_SCROLL_DOWN; + else + direction = GDK_SCROLL_UP; + + event = gdk_scroll_event_new_discrete (surface, + device, + NULL, + xev->time, + state, + direction, + FALSE); + } + else + { + event = gdk_scroll_event_new (surface, + device, + NULL, + xev->time, + state, + delta_x, + delta_y, + delta_x == 0.0 && delta_y == 0.0); + } break; }