فهرست منبع

Fix spurious LCtrl on RAlt key pressed

(cherry picked from commit 22c14442e22b432c69348211fc97c81248269d30)
Fabrice Desclaux 10 ماه پیش
والد
کامیت
f62a1bed16
1فایلهای تغییر یافته به همراه44 افزوده شده و 0 حذف شده
  1. 44 0
      src/video/windows/SDL_windowsevents.c

+ 44 - 0
src/video/windows/SDL_windowsevents.c

@@ -433,6 +433,10 @@ WIN_KeyboardHookProc(int nCode, WPARAM wParam, LPARAM lParam)
     if (nCode < 0 || nCode != HC_ACTION) {
         return CallNextHookEx(NULL, nCode, wParam, lParam);
     }
+    if (hookData->scanCode == 0x21d) {
+        // Skip fake LCtrl when RAlt is pressed
+        return 1;
+    }
 
     switch (hookData->vkCode) {
     case VK_LWIN:
@@ -950,6 +954,36 @@ void WIN_CheckKeyboardAndMouseHotplug(SDL_VideoDevice *_this, SDL_bool initial_c
 }
 #endif /*!defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)*/
 
+// Return SDL_TRUE if spurious LCtrl is pressed
+// LCtrl is sent when RAltGR is pressed
+static SDL_bool SkipAltGrLeftControl(WPARAM wParam, LPARAM lParam)
+{
+    if (wParam != VK_CONTROL) {
+        return SDL_FALSE;
+    }
+
+    // Is this an extended key (i.e. right key)?
+    if (lParam & 0x01000000) {
+        return SDL_FALSE;
+    }
+
+    // Here is a trick: "Alt Gr" sends LCTRL, then RALT. We only
+    // want the RALT message, so we try to see if the next message
+    // is a RALT message. In that case, this is a false LCTRL!
+    MSG next_msg;
+    DWORD msg_time = GetMessageTime();
+    if (PeekMessage(&next_msg, NULL, 0, 0, PM_NOREMOVE)) {
+        if (next_msg.message == WM_KEYDOWN ||
+            next_msg.message == WM_SYSKEYDOWN) {
+            if (next_msg.wParam == VK_MENU && (next_msg.lParam & 0x01000000) && next_msg.time == msg_time) {
+                // Next message is a RALT down message, which means that this is NOT a proper LCTRL message!
+                return SDL_TRUE;
+            }
+        }
+    }
+    return SDL_FALSE;
+}
+
 LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
 {
     SDL_WindowData *data;
@@ -1158,6 +1192,11 @@ LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara
     case WM_KEYDOWN:
     case WM_SYSKEYDOWN:
     {
+        if (SkipAltGrLeftControl(wParam, lParam)) {
+            returnCode = 0;
+            break;
+        }
+
         SDL_bool virtual_key = SDL_FALSE;
         SDL_Scancode code = WindowsScanCodeToSDLScanCode(lParam, wParam, &virtual_key);
         const Uint8 *keyboardState = SDL_GetKeyboardState(NULL);
@@ -1181,6 +1220,11 @@ LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara
     case WM_SYSKEYUP:
     case WM_KEYUP:
     {
+        if (SkipAltGrLeftControl(wParam, lParam)) {
+            returnCode = 0;
+            break;
+        }
+
         SDL_bool virtual_key = SDL_FALSE;
         SDL_Scancode code = WindowsScanCodeToSDLScanCode(lParam, wParam, &virtual_key);
         const Uint8 *keyboardState = SDL_GetKeyboardState(NULL);