Skip to content

Commit 51ce3f8

Browse files
committed
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.
1 parent 4246356 commit 51ce3f8

File tree

3 files changed

+12
-7
lines changed

3 files changed

+12
-7
lines changed

src/video/x11/SDL_x11events.c

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ static bool X11_KeyRepeat(Display *display, XEvent *event)
194194
return d.found;
195195
}
196196

197-
static bool X11_IsWheelEvent(Display *display, int button, int *xticks, int *yticks)
197+
bool X11_IsWheelEvent(int button, int *xticks, int *yticks)
198198
{
199199
/* according to the xlib docs, no specific mouse wheel events exist.
200200
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_
10161016
void X11_HandleButtonPress(SDL_VideoDevice *_this, SDL_WindowData *windowdata, SDL_MouseID mouseID, int button, float x, float y, unsigned long time)
10171017
{
10181018
SDL_Window *window = windowdata->window;
1019-
const SDL_VideoData *videodata = _this->internal;
1020-
Display *display = videodata->display;
10211019
int xticks = 0, yticks = 0;
10221020
Uint64 timestamp = X11_GetEventTimestamp(time);
10231021

@@ -1031,7 +1029,7 @@ void X11_HandleButtonPress(SDL_VideoDevice *_this, SDL_WindowData *windowdata, S
10311029
SDL_SendMouseMotion(timestamp, window, mouseID, false, x, y);
10321030
}
10331031

1034-
if (X11_IsWheelEvent(display, button, &xticks, &yticks)) {
1032+
if (X11_IsWheelEvent(button, &xticks, &yticks)) {
10351033
SDL_SendMouseWheel(timestamp, window, mouseID, (float)-xticks, (float)yticks, SDL_MOUSEWHEEL_NORMAL);
10361034
} else {
10371035
bool ignore_click = false;
@@ -1063,16 +1061,14 @@ void X11_HandleButtonPress(SDL_VideoDevice *_this, SDL_WindowData *windowdata, S
10631061
void X11_HandleButtonRelease(SDL_VideoDevice *_this, SDL_WindowData *windowdata, SDL_MouseID mouseID, int button, unsigned long time)
10641062
{
10651063
SDL_Window *window = windowdata->window;
1066-
const SDL_VideoData *videodata = _this->internal;
1067-
Display *display = videodata->display;
10681064
// The X server sends a Release event for each Press for wheels. Ignore them.
10691065
int xticks = 0, yticks = 0;
10701066
Uint64 timestamp = X11_GetEventTimestamp(time);
10711067

10721068
#ifdef DEBUG_XEVENTS
10731069
SDL_Log("window 0x%lx: ButtonRelease (X11 button = %d)", windowdata->xwindow, button);
10741070
#endif
1075-
if (!X11_IsWheelEvent(display, button, &xticks, &yticks)) {
1071+
if (!X11_IsWheelEvent(button, &xticks, &yticks)) {
10761072
if (button > 7) {
10771073
// see explanation at case ButtonPress
10781074
button -= (8 - SDL_BUTTON_X1);

src/video/x11/SDL_x11events.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,5 +36,6 @@ extern void X11_HandleButtonRelease(SDL_VideoDevice *_this, SDL_WindowData *wind
3636
extern SDL_WindowData *X11_FindWindow(SDL_VideoDevice *_this, Window window);
3737
extern bool X11_ProcessHitTest(SDL_VideoDevice *_this, SDL_WindowData *data, const float x, const float y, bool force_new_result);
3838
extern bool X11_TriggerHitTestAction(SDL_VideoDevice *_this, SDL_WindowData *data, const float x, const float y);
39+
extern bool X11_IsWheelEvent(int button, int *xticks, int *yticks);
3940

4041
#endif // SDL_x11events_h_

src/video/x11/SDL_x11xinput2.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,14 @@ void X11_HandleXinput2Event(SDL_VideoDevice *_this, XGenericEventCookie *cookie)
425425
} else {
426426
// Otherwise assume a regular mouse
427427
SDL_WindowData *windowdata = xinput2_get_sdlwindowdata(videodata, xev->event);
428+
int x_ticks = 0, y_ticks = 0;
429+
430+
/* Discard wheel events from "Master" devices to avoid duplicates,
431+
* as coarse wheel events are stateless and can't be deduplicated.
432+
*/
433+
if (xev->deviceid != xev->sourceid && X11_IsWheelEvent(button, &x_ticks, &y_ticks)) {
434+
break;
435+
}
428436

429437
if (down) {
430438
X11_HandleButtonPress(_this, windowdata, (SDL_MouseID)xev->sourceid, button,

0 commit comments

Comments
 (0)