diff --git a/src/video/x11/SDL_x11events.c b/src/video/x11/SDL_x11events.c index 15af66124f..961c8b08e2 100644 --- a/src/video/x11/SDL_x11events.c +++ b/src/video/x11/SDL_x11events.c @@ -1834,12 +1834,16 @@ static void X11_DispatchEvent(SDL_VideoDevice *_this, XEvent *xevent) case KeyPress: case KeyRelease: { + SDL_KeyboardID keyboardID = SDL_GLOBAL_KEYBOARD_ID; if (data->xinput2_keyboard_enabled) { - // This input is being handled by XInput2 + // This input is being handled by XInput2. break; + } else if (xevent->xkey.serial == videodata->xinput_last_key_serial) { + // Use the device ID from the XInput2 event if the serials match. + keyboardID = videodata->xinput_last_keyboard_device; } - X11_HandleKeyEvent(_this, data, SDL_GLOBAL_KEYBOARD_ID, xevent); + X11_HandleKeyEvent(_this, data, keyboardID, xevent); } break; case MotionNotify: diff --git a/src/video/x11/SDL_x11video.h b/src/video/x11/SDL_x11video.h index 01c2e5b9fb..7bc858d98b 100644 --- a/src/video/x11/SDL_x11video.h +++ b/src/video/x11/SDL_x11video.h @@ -140,6 +140,8 @@ struct SDL_VideoData SDL_XInput2DeviceInfo *mouse_device_info; unsigned long xinput_last_button_serial; + unsigned long xinput_last_key_serial; + int xinput_last_keyboard_device; 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 d6c704e3f6..3a94c6a1f0 100644 --- a/src/video/x11/SDL_x11xinput2.c +++ b/src/video/x11/SDL_x11xinput2.c @@ -303,6 +303,12 @@ bool X11_InitXinput2(SDL_VideoDevice *_this) eventmask.mask_len = sizeof(mask); eventmask.mask = mask; +#ifndef USE_XINPUT2_KEYBOARD + // If not using the full keyboard handling, register for keypresses to get the event source devices. + XISetMask(mask, XI_KeyPress); + XISetMask(mask, XI_KeyRelease); +#endif + XISetMask(mask, XI_HierarchyChanged); X11_XISelectEvents(data->display, DefaultRootWindow(data->display), &eventmask, 1); @@ -535,6 +541,8 @@ void X11_HandleXinput2Event(SDL_VideoDevice *_this, XGenericEventCookie *cookie) case XI_KeyRelease: { const XIDeviceEvent *xev = (const XIDeviceEvent *)cookie->data; + +#ifdef XINPUT2_USE_KEYBOARD SDL_WindowData *windowdata = X11_FindWindow(videodata, xev->event); XEvent xevent; @@ -564,6 +572,13 @@ void X11_HandleXinput2Event(SDL_VideoDevice *_this, XGenericEventCookie *cookie) xevent.xkey.same_screen = 1; X11_HandleKeyEvent(_this, windowdata, (SDL_KeyboardID)xev->sourceid, &xevent); +#else + /* Keys are handled through core X events, however, note the device ID and + * associated serial, so that the source device ID can be passed through. + */ + videodata->xinput_last_key_serial = xev->serial; + videodata->xinput_last_keyboard_device = xev->sourceid; +#endif } break; case XI_RawButtonPress: