Disable XInput2 keyboard events

It turns out they're only delivered to the window with mouse focus, not keyboard focus.

Fixes https://github.com/libsdl-org/SDL/issues/9374
main
Sam Lantinga 2024-03-28 08:50:47 -07:00
parent fb5307c1b3
commit c8489a3710
4 changed files with 29 additions and 12 deletions

View File

@ -1528,7 +1528,7 @@ static void X11_DispatchEvent(SDL_VideoDevice *_this, XEvent *xevent)
case KeyPress: case KeyPress:
case KeyRelease: case KeyRelease:
{ {
if (data->using_xinput2) { if (data->xinput2_keyboard_enabled) {
// This input is being handled by XInput2 // This input is being handled by XInput2
break; break;
} }
@ -1538,7 +1538,7 @@ static void X11_DispatchEvent(SDL_VideoDevice *_this, XEvent *xevent)
case MotionNotify: case MotionNotify:
{ {
if (data->using_xinput2) { if (data->xinput2_mouse_enabled) {
// This input is being handled by XInput2 // This input is being handled by XInput2
break; break;
} }
@ -1556,7 +1556,7 @@ static void X11_DispatchEvent(SDL_VideoDevice *_this, XEvent *xevent)
case ButtonPress: case ButtonPress:
{ {
if (data->using_xinput2) { if (data->xinput2_mouse_enabled) {
// This input is being handled by XInput2 // This input is being handled by XInput2
break; break;
} }
@ -1567,7 +1567,7 @@ static void X11_DispatchEvent(SDL_VideoDevice *_this, XEvent *xevent)
case ButtonRelease: case ButtonRelease:
{ {
if (data->using_xinput2) { if (data->xinput2_mouse_enabled) {
// This input is being handled by XInput2 // This input is being handled by XInput2
break; break;
} }

View File

@ -796,9 +796,14 @@ int X11_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesI
{ {
unsigned int x11_keyboard_events = KeyPressMask | KeyReleaseMask; unsigned int x11_keyboard_events = KeyPressMask | KeyReleaseMask;
unsigned int x11_pointer_events = ButtonPressMask | ButtonReleaseMask | PointerMotionMask; unsigned int x11_pointer_events = ButtonPressMask | ButtonReleaseMask | PointerMotionMask;
if (X11_Xinput2SelectMouseAndKeyboard(_this, window)) {
/* If XInput2 can handle pointer and keyboard events, we don't track them here */ X11_Xinput2SelectMouseAndKeyboard(_this, window);
/* If XInput2 can handle pointer and keyboard events, we don't track them here */
if (windowdata->xinput2_keyboard_enabled) {
x11_keyboard_events = 0; x11_keyboard_events = 0;
}
if (windowdata->xinput2_mouse_enabled) {
x11_pointer_events = 0; x11_pointer_events = 0;
} }

View File

@ -59,7 +59,8 @@ struct SDL_WindowData
int border_right; int border_right;
int border_top; int border_top;
int border_bottom; int border_bottom;
SDL_bool using_xinput2; SDL_bool xinput2_mouse_enabled;
SDL_bool xinput2_keyboard_enabled;
SDL_bool mouse_grabbed; SDL_bool mouse_grabbed;
Uint64 last_focus_event_time; Uint64 last_focus_event_time;
PendingFocusEnum pending_focus; PendingFocusEnum pending_focus;

View File

@ -607,27 +607,38 @@ SDL_bool X11_Xinput2SelectMouseAndKeyboard(SDL_VideoDevice *_this, SDL_Window *w
eventmask.mask = mask; eventmask.mask = mask;
eventmask.deviceid = XIAllDevices; eventmask.deviceid = XIAllDevices;
/* This is not enabled by default because these events are only delivered to the window with mouse focus, not keyboard focus */
#ifdef USE_XINPUT2_KEYBOARD
XISetMask(mask, XI_KeyPress); XISetMask(mask, XI_KeyPress);
XISetMask(mask, XI_KeyRelease); XISetMask(mask, XI_KeyRelease);
windowdata->xinput2_keyboard_enabled = SDL_TRUE;
#endif
XISetMask(mask, XI_ButtonPress); XISetMask(mask, XI_ButtonPress);
XISetMask(mask, XI_ButtonRelease); XISetMask(mask, XI_ButtonRelease);
XISetMask(mask, XI_Motion); XISetMask(mask, XI_Motion);
windowdata->xinput2_mouse_enabled = SDL_TRUE;
XISetMask(mask, XI_Enter); XISetMask(mask, XI_Enter);
XISetMask(mask, XI_Leave); XISetMask(mask, XI_Leave);
/* Hotplugging: */ /* Hotplugging: */
XISetMask(mask, XI_DeviceChanged); XISetMask(mask, XI_DeviceChanged);
XISetMask(mask, XI_HierarchyChanged); XISetMask(mask, XI_HierarchyChanged);
XISetMask(mask, XI_PropertyEvent); /* E.g., when swapping tablet pens */ XISetMask(mask, XI_PropertyEvent); /* E.g., when swapping tablet pens */
if (X11_XISelectEvents(data->display, windowdata->xwindow, &eventmask, 1) == Success) { if (X11_XISelectEvents(data->display, windowdata->xwindow, &eventmask, 1) != Success) {
windowdata->using_xinput2 = SDL_TRUE;
} else {
SDL_LogWarn(SDL_LOG_CATEGORY_INPUT, "Could not enable XInput2 event handling\n"); SDL_LogWarn(SDL_LOG_CATEGORY_INPUT, "Could not enable XInput2 event handling\n");
windowdata->using_xinput2 = SDL_FALSE; windowdata->xinput2_keyboard_enabled = SDL_FALSE;
windowdata->xinput2_mouse_enabled = SDL_FALSE;
} }
} }
#endif #endif
return windowdata->using_xinput2;
if (windowdata->xinput2_keyboard_enabled || windowdata->xinput2_mouse_enabled) {
return SDL_TRUE;
}
return SDL_FALSE;
} }
int X11_Xinput2IsMultitouchSupported(void) int X11_Xinput2IsMultitouchSupported(void)