diff --git a/src/video/x11/SDL_x11events.c b/src/video/x11/SDL_x11events.c index b82590071e..979ce0ea04 100644 --- a/src/video/x11/SDL_x11events.c +++ b/src/video/x11/SDL_x11events.c @@ -1862,8 +1862,8 @@ static void X11_DispatchEvent(SDL_VideoDevice *_this, XEvent *xevent) case ButtonPress: { - if (data->xinput2_mouse_enabled) { - // This input is being handled by XInput2 + if (data->xinput2_mouse_enabled && xevent->xbutton.serial == videodata->xinput_last_button_serial) { + // This input event was handled by XInput2. break; } @@ -1873,8 +1873,8 @@ static void X11_DispatchEvent(SDL_VideoDevice *_this, XEvent *xevent) case ButtonRelease: { - if (data->xinput2_mouse_enabled) { - // This input is being handled by XInput2 + if (data->xinput2_mouse_enabled && xevent->xbutton.serial == videodata->xinput_last_button_serial) { + // This input event was handled by XInput2. break; } diff --git a/src/video/x11/SDL_x11video.h b/src/video/x11/SDL_x11video.h index 2dc4d3ab60..c6069b2624 100644 --- a/src/video/x11/SDL_x11video.h +++ b/src/video/x11/SDL_x11video.h @@ -138,6 +138,7 @@ struct SDL_VideoData Uint32 global_mouse_buttons; SDL_XInput2DeviceInfo *mouse_device_info; + unsigned long xinput_last_button_serial; int xinput_master_pointer_device; bool xinput_hierarchy_changed; diff --git a/src/video/x11/SDL_x11xinput2.c b/src/video/x11/SDL_x11xinput2.c index 51a18a66e5..21c0f5b15d 100644 --- a/src/video/x11/SDL_x11xinput2.c +++ b/src/video/x11/SDL_x11xinput2.c @@ -607,8 +607,16 @@ void X11_HandleXinput2Event(SDL_VideoDevice *_this, XGenericEventCookie *cookie) SDL_WindowData *windowdata = X11_FindWindow(videodata, xev->event); int x_ticks = 0, y_ticks = 0; - // Slave pointer devices don't have button remapping applied automatically, so do it manually. + // Store the button serial to filter out redundant core button events. + videodata->xinput_last_button_serial = xev->serial; + if (xev->deviceid != videodata->xinput_master_pointer_device) { + // Ignore slave button events on non-focused windows, or focus can be incorrectly set while a grab is active. + if (SDL_GetMouseFocus() != windowdata->window) { + break; + } + + // Slave pointer devices don't have button remapping applied automatically, so do it manually. if (button <= xinput2_pointer_button_map_size) { button = xinput2_pointer_button_map[button - 1]; }