SDL: Fixed incorrect modifier keys handling on macOS

From 4de6ddd07f486baea70d8fe9dd274628ddb85ecc Mon Sep 17 00:00:00 2001
From: Deve <[EMAIL REDACTED]>
Date: Wed, 8 Mar 2023 23:57:08 +0100
Subject: [PATCH] Fixed incorrect modifier keys handling on macOS

---
 src/video/cocoa/SDL_cocoakeyboard.m | 93 ++++++++++++++++-------------
 1 file changed, 51 insertions(+), 42 deletions(-)

diff --git a/src/video/cocoa/SDL_cocoakeyboard.m b/src/video/cocoa/SDL_cocoakeyboard.m
index da6afa02043b..a7c90035dc19 100644
--- a/src/video/cocoa/SDL_cocoakeyboard.m
+++ b/src/video/cocoa/SDL_cocoakeyboard.m
@@ -183,48 +183,57 @@ - (NSArray *)validAttributesForMarkedText
 
 @end
 
-static void HandleModifiers(_THIS, unsigned short scancode, unsigned int modifierFlags)
+bool IsModifierKeyPressed(unsigned int flags,
+                          unsigned int target_mask,
+                          unsigned int other_mask,
+                          unsigned int either_mask)
 {
-    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(0, SDL_PRESSED, code);
-            } else {
-                SDL_SendKeyboardKey(0, SDL_RELEASED, code);
-            }
-        }
+    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, SDL_Scancode code, unsigned int modifierFlags)
+{
+    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(0, SDL_PRESSED, code);
+    } else {
+        SDL_SendKeyboardKey(0, SDL_RELEASED, code);
     }
 }
 
@@ -416,7 +425,7 @@ void Cocoa_HandleKeyEvent(_THIS, NSEvent *event)
         SDL_SendKeyboardKey(Cocoa_GetEventTimestamp([event timestamp]), 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;