Commit 1c2f825230d8a1d406179f80192e3421054d688b

Deve 2023-03-08T23:57:08

Fixed incorrect modifier keys handling on macOS (cherry-picked from commit 45a58b7882a253db29b1b1393bc2a1fe030d5955)

diff --git a/src/video/cocoa/SDL_cocoakeyboard.m b/src/video/cocoa/SDL_cocoakeyboard.m
index 78c8a16..f085ccc 100644
--- a/src/video/cocoa/SDL_cocoakeyboard.m
+++ b/src/video/cocoa/SDL_cocoakeyboard.m
@@ -182,47 +182,58 @@
 
 @end
 
+static bool IsModifierKeyPressed(unsigned int flags,
+                                 unsigned int target_mask,
+                                 unsigned int other_mask,
+                                 unsigned int either_mask)
+{
+    bool target_pressed = (flags & target_mask) != 0;
+    bool other_pressed = (flags & other_mask) != 0;
+    bool either_pressed = (flags & either_mask) != 0;
+
+    if (either_pressed != (target_pressed || other_pressed))
+        return either_pressed;
+
+    return target_pressed;
+}
+
 static void
-HandleModifiers(_THIS, unsigned short scancode, unsigned int modifierFlags)
+HandleModifiers(_THIS, SDL_Scancode code, unsigned int modifierFlags)
 {
-    SDL_Scancode code = darwin_scancode_table[scancode];
-
-    const SDL_Scancode codes[] = { 
-        SDL_SCANCODE_LSHIFT, 
-        SDL_SCANCODE_LCTRL, 
-        SDL_SCANCODE_LALT, 
-        SDL_SCANCODE_LGUI, 
-        SDL_SCANCODE_RSHIFT, 
-        SDL_SCANCODE_RCTRL, 
-        SDL_SCANCODE_RALT, 
-        SDL_SCANCODE_RGUI, 
-        SDL_SCANCODE_LSHIFT, 
-        SDL_SCANCODE_LCTRL, 
-        SDL_SCANCODE_LALT, 
-        SDL_SCANCODE_LGUI, };
-
-    const unsigned int modifiers[] = { 
-        NX_DEVICELSHIFTKEYMASK, 
-        NX_DEVICELCTLKEYMASK, 
-        NX_DEVICELALTKEYMASK, 
-        NX_DEVICELCMDKEYMASK, 
-        NX_DEVICERSHIFTKEYMASK, 
-        NX_DEVICERCTLKEYMASK, 
-        NX_DEVICERALTKEYMASK, 
-        NX_DEVICERCMDKEYMASK,
-        NX_SHIFTMASK,
-        NX_CONTROLMASK, 
-        NX_ALTERNATEMASK,
-        NX_COMMANDMASK };
-
-    for (int i = 0; i < 12; i++) {
-        if (code == codes[i]) {
-            if (modifierFlags & modifiers[i]) {
-                SDL_SendKeyboardKey(SDL_PRESSED, code);
-            } else {
-                SDL_SendKeyboardKey(SDL_RELEASED, code);
-            }
-        }
+    bool pressed = false;
+
+    if (code == SDL_SCANCODE_LSHIFT) {
+        pressed = IsModifierKeyPressed(modifierFlags, NX_DEVICELSHIFTKEYMASK,
+                                       NX_DEVICERSHIFTKEYMASK, NX_SHIFTMASK);
+    } else if (code == SDL_SCANCODE_LCTRL) {
+        pressed = IsModifierKeyPressed(modifierFlags, NX_DEVICELCTLKEYMASK,
+                                       NX_DEVICERCTLKEYMASK, NX_CONTROLMASK);
+    } else if (code == SDL_SCANCODE_LALT) {
+        pressed = IsModifierKeyPressed(modifierFlags, NX_DEVICELALTKEYMASK,
+                                       NX_DEVICERALTKEYMASK, NX_ALTERNATEMASK);
+    } else if (code == SDL_SCANCODE_LGUI) {
+        pressed = IsModifierKeyPressed(modifierFlags, NX_DEVICELCMDKEYMASK,
+                                       NX_DEVICERCMDKEYMASK, NX_COMMANDMASK);
+    } else if (code == SDL_SCANCODE_RSHIFT) {
+        pressed = IsModifierKeyPressed(modifierFlags, NX_DEVICERSHIFTKEYMASK,
+                                       NX_DEVICELSHIFTKEYMASK, NX_SHIFTMASK);
+    } else if (code == SDL_SCANCODE_RCTRL) {
+        pressed = IsModifierKeyPressed(modifierFlags, NX_DEVICERCTLKEYMASK,
+                                       NX_DEVICELCTLKEYMASK, NX_CONTROLMASK);
+    } else if (code == SDL_SCANCODE_RALT) {
+        pressed = IsModifierKeyPressed(modifierFlags, NX_DEVICERALTKEYMASK,
+                                       NX_DEVICELALTKEYMASK, NX_ALTERNATEMASK);
+    } else if (code == SDL_SCANCODE_RGUI) {
+        pressed = IsModifierKeyPressed(modifierFlags, NX_DEVICERCMDKEYMASK,
+                                       NX_DEVICELCMDKEYMASK, NX_COMMANDMASK);
+    } else {
+        return;
+    }
+
+    if (pressed) {
+        SDL_SendKeyboardKey(SDL_PRESSED, code);
+    } else {
+        SDL_SendKeyboardKey(SDL_RELEASED, code);
     }
 }
 
@@ -423,7 +434,7 @@ Cocoa_HandleKeyEvent(_THIS, NSEvent *event)
         SDL_SendKeyboardKey(SDL_RELEASED, code);
         break;
     case NSEventTypeFlagsChanged:
-        HandleModifiers(_this, scancode, (unsigned int)[event modifierFlags]);	
+        HandleModifiers(_this, code, (unsigned int)[event modifierFlags]);
         break;
     default: /* just to avoid compiler warnings */
         break;