diff --git a/src/video/x11/SDL_x11events.c b/src/video/x11/SDL_x11events.c index 1b08f6dc19..d639346b6b 100644 --- a/src/video/x11/SDL_x11events.c +++ b/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); diff --git a/src/video/x11/SDL_x11events.h b/src/video/x11/SDL_x11events.h index bb76f836f8..bc0c226dfa 100644 --- a/src/video/x11/SDL_x11events.h +++ b/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_ diff --git a/src/video/x11/SDL_x11xinput2.c b/src/video/x11/SDL_x11xinput2.c index 98080ccfd8..eb212378c6 100644 --- a/src/video/x11/SDL_x11xinput2.c +++ b/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,