diff --git a/client/displayservers/X11/x11.c b/client/displayservers/X11/x11.c index 2efb69a4..9f3f2e3b 100644 --- a/client/displayservers/X11/x11.c +++ b/client/displayservers/X11/x11.c @@ -903,6 +903,32 @@ static int x11EventThread(void * unused) return 0; } +static enum Modifiers keySymToModifier(KeySym sym) +{ + switch (sym) + { + case XK_Control_L: return MOD_CTRL_LEFT; + case XK_Control_R: return MOD_CTRL_RIGHT; + case XK_Shift_L: return MOD_SHIFT_LEFT; + case XK_Shift_R: return MOD_SHIFT_RIGHT; + case XK_Alt_L: return MOD_ALT_LEFT; + case XK_Alt_R: return MOD_ALT_RIGHT; + case XK_Super_L: return MOD_SUPER_LEFT; + case XK_Super_R: return MOD_SUPER_RIGHT; + default: return -1; + } +} + +static void updateModifiers(void) +{ + app_handleKeyboardModifiers( + x11.modifiers[MOD_CTRL_LEFT] || x11.modifiers[MOD_CTRL_RIGHT], + x11.modifiers[MOD_SHIFT_LEFT] || x11.modifiers[MOD_SHIFT_RIGHT], + x11.modifiers[MOD_ALT_LEFT] || x11.modifiers[MOD_ALT_RIGHT], + x11.modifiers[MOD_SUPER_LEFT] || x11.modifiers[MOD_SUPER_RIGHT] + ); +} + static void x11XInputEvent(XGenericEventCookie *cookie) { static int button_state = 0; @@ -1009,6 +1035,16 @@ static void x11XInputEvent(XGenericEventCookie *cookie) buffer[count] = '\0'; app_handleKeyboardTyped(buffer); } + + if (status == XLookupKeySym || status == XLookupBoth) + { + int modifier = keySymToModifier(sym); + if (modifier >= 0) + { + x11.modifiers[modifier] = true; + updateModifiers(); + } + } return; } @@ -1019,6 +1055,25 @@ static void x11XInputEvent(XGenericEventCookie *cookie) XIDeviceEvent *device = cookie->data; app_handleKeyRelease(device->detail - 8); + + if (!x11.xic || !app_isOverlayMode()) + return; + + XKeyPressedEvent ev = { + .display = x11.display, + .window = x11.window, + .type = KeyRelease, + .keycode = device->detail, + .state = device->mods.effective, + }; + KeySym sym = XLookupKeysym(&ev, 0); + int modifier = keySymToModifier(sym); + + if (modifier >= 0) + { + x11.modifiers[modifier] = false; + updateModifiers(); + } return; } diff --git a/client/displayservers/X11/x11.h b/client/displayservers/X11/x11.h index 51eb121a..5f339d69 100644 --- a/client/displayservers/X11/x11.h +++ b/client/displayservers/X11/x11.h @@ -34,6 +34,20 @@ #include "common/thread.h" #include "common/types.h" +enum Modifiers +{ + MOD_CTRL_LEFT = 0, + MOD_CTRL_RIGHT, + MOD_SHIFT_LEFT, + MOD_SHIFT_RIGHT, + MOD_ALT_LEFT, + MOD_ALT_RIGHT, + MOD_SUPER_LEFT, + MOD_SUPER_RIGHT, +}; + +#define MOD_COUNT (MOD_SUPER_RIGHT + 1) + struct X11DSState { Display * display; @@ -72,6 +86,7 @@ struct X11DSState XIM xim; XIC xic; + bool modifiers[MOD_COUNT]; // XFixes vars int eventBase;