From 54ca4d387954e687db0d28758d43cf08a1cc1353 Mon Sep 17 00:00:00 2001 From: Deve Date: Wed, 8 Mar 2023 23:57:08 +0100 Subject: [PATCH] Fixed incorrect modifier keys handling on macOS (cherry-picked from commit 45a58b7882a253db29b1b1393bc2a1fe030d5955) --- src/video/cocoa/SDL_cocoakeyboard.m | 88 ++++++++++++++++------------- 1 file changed, 49 insertions(+), 39 deletions(-) diff --git a/src/video/cocoa/SDL_cocoakeyboard.m b/src/video/cocoa/SDL_cocoakeyboard.m index e7f09c66f..1503b8692 100644 --- a/src/video/cocoa/SDL_cocoakeyboard.m +++ b/src/video/cocoa/SDL_cocoakeyboard.m @@ -182,48 +182,58 @@ @end -static void -HandleModifiers(_THIS, unsigned short scancode, unsigned int modifierFlags) +static bool IsModifierKeyPressed(unsigned int flags, + unsigned int target_mask, + unsigned int other_mask, + unsigned int either_mask) { - SDL_Scancode code = darwin_scancode_table[scancode]; + bool target_pressed = (flags & target_mask) != 0; + bool other_pressed = (flags & other_mask) != 0; + bool either_pressed = (flags & either_mask) != 0; - 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, }; + if (either_pressed != (target_pressed || other_pressed)) + return either_pressed; - 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 }; + return target_pressed; +} - 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); - } +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(SDL_PRESSED, code); + } else { + SDL_SendKeyboardKey(SDL_RELEASED, code); } } @@ -424,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;