Browse Source

x11: Filter mouse wheel events from "Master" devices

Discard wheel events from "Master" devices to avoid duplicates, as wheel events are stateless and can't be deduplicated.
Frank Praznik 1 tháng trước cách đây
mục cha
commit
51ce3f8c8d

+ 3 - 7
src/video/x11/SDL_x11events.c

@@ -194,7 +194,7 @@ static bool X11_KeyRepeat(Display *display, XEvent *event)
     return d.found;
 }
 
-static bool X11_IsWheelEvent(Display *display, int button, int *xticks, int *yticks)
+bool X11_IsWheelEvent(int button, int *xticks, int *yticks)
 {
     /* according to the xlib docs, no specific mouse wheel events exist.
        However, the defacto standard is that the vertical wheel is X buttons
@@ -1016,8 +1016,6 @@ void X11_HandleKeyEvent(SDL_VideoDevice *_this, SDL_WindowData *windowdata, SDL_
 void X11_HandleButtonPress(SDL_VideoDevice *_this, SDL_WindowData *windowdata, SDL_MouseID mouseID, int button, float x, float y, unsigned long time)
 {
     SDL_Window *window = windowdata->window;
-    const SDL_VideoData *videodata = _this->internal;
-    Display *display = videodata->display;
     int xticks = 0, yticks = 0;
     Uint64 timestamp = X11_GetEventTimestamp(time);
 
@@ -1031,7 +1029,7 @@ void X11_HandleButtonPress(SDL_VideoDevice *_this, SDL_WindowData *windowdata, S
         SDL_SendMouseMotion(timestamp, window, mouseID, false, x, y);
     }
 
-    if (X11_IsWheelEvent(display, button, &xticks, &yticks)) {
+    if (X11_IsWheelEvent(button, &xticks, &yticks)) {
         SDL_SendMouseWheel(timestamp, window, mouseID, (float)-xticks, (float)yticks, SDL_MOUSEWHEEL_NORMAL);
     } else {
         bool ignore_click = false;
@@ -1063,8 +1061,6 @@ void X11_HandleButtonPress(SDL_VideoDevice *_this, SDL_WindowData *windowdata, S
 void X11_HandleButtonRelease(SDL_VideoDevice *_this, SDL_WindowData *windowdata, SDL_MouseID mouseID, int button, unsigned long time)
 {
     SDL_Window *window = windowdata->window;
-    const SDL_VideoData *videodata = _this->internal;
-    Display *display = videodata->display;
     // The X server sends a Release event for each Press for wheels. Ignore them.
     int xticks = 0, yticks = 0;
     Uint64 timestamp = X11_GetEventTimestamp(time);
@@ -1072,7 +1068,7 @@ void X11_HandleButtonRelease(SDL_VideoDevice *_this, SDL_WindowData *windowdata,
 #ifdef DEBUG_XEVENTS
     SDL_Log("window 0x%lx: ButtonRelease (X11 button = %d)", windowdata->xwindow, button);
 #endif
-    if (!X11_IsWheelEvent(display, button, &xticks, &yticks)) {
+    if (!X11_IsWheelEvent(button, &xticks, &yticks)) {
         if (button > 7) {
             // see explanation at case ButtonPress
             button -= (8 - SDL_BUTTON_X1);

+ 1 - 0
src/video/x11/SDL_x11events.h

@@ -36,5 +36,6 @@ extern void X11_HandleButtonRelease(SDL_VideoDevice *_this, SDL_WindowData *wind
 extern SDL_WindowData *X11_FindWindow(SDL_VideoDevice *_this, Window window);
 extern bool X11_ProcessHitTest(SDL_VideoDevice *_this, SDL_WindowData *data, const float x, const float y, bool force_new_result);
 extern bool X11_TriggerHitTestAction(SDL_VideoDevice *_this, SDL_WindowData *data, const float x, const float y);
+extern bool X11_IsWheelEvent(int button, int *xticks, int *yticks);
 
 #endif // SDL_x11events_h_

+ 8 - 0
src/video/x11/SDL_x11xinput2.c

@@ -425,6 +425,14 @@ void X11_HandleXinput2Event(SDL_VideoDevice *_this, XGenericEventCookie *cookie)
         } else {
             // Otherwise assume a regular mouse
             SDL_WindowData *windowdata = xinput2_get_sdlwindowdata(videodata, xev->event);
+            int x_ticks = 0, y_ticks = 0;
+
+            /* Discard wheel events from "Master" devices to avoid duplicates,
+             * as coarse wheel events are stateless and can't be deduplicated.
+             */
+            if (xev->deviceid != xev->sourceid && X11_IsWheelEvent(button, &x_ticks, &y_ticks)) {
+                break;
+            }
 
             if (down) {
                 X11_HandleButtonPress(_this, windowdata, (SDL_MouseID)xev->sourceid, button,