SDL: UWP: Use Windows.UI.Core.CoreDispatcher.AcceleratorKeyActivated event for keyboard

From 9a206adbee1af90430f36177a332417d9c7c230d Mon Sep 17 00:00:00 2001
From: Dimitriy Ryazantcev <[EMAIL REDACTED]>
Date: Tue, 28 Nov 2023 20:23:57 +0200
Subject: [PATCH] UWP: Use
 Windows.UI.Core.CoreDispatcher.AcceleratorKeyActivated event for keyboard

Only in this case we can see Left Alt and Right Alt keys.

Stole the idea from DirectXTK12 repo:
https://github.com/microsoft/DirectXTK12/blob/main/Src/Keyboard.cpp
---
 src/core/winrt/SDL_winrtapp_direct3d.cpp | 16 ++----
 src/core/winrt/SDL_winrtapp_direct3d.h   |  3 +-
 src/video/winrt/SDL_winrtevents_c.h      |  3 +-
 src/video/winrt/SDL_winrtkeyboard.cpp    | 73 ++++++++----------------
 4 files changed, 29 insertions(+), 66 deletions(-)

diff --git a/src/core/winrt/SDL_winrtapp_direct3d.cpp b/src/core/winrt/SDL_winrtapp_direct3d.cpp
index 167e5a9a0be4..f451203e25b5 100644
--- a/src/core/winrt/SDL_winrtapp_direct3d.cpp
+++ b/src/core/winrt/SDL_winrtapp_direct3d.cpp
@@ -296,11 +296,8 @@ void SDL_WinRTApp::SetWindow(CoreWindow ^ window)
         ref new TypedEventHandler<MouseDevice ^, MouseEventArgs ^>(this, &SDL_WinRTApp::OnMouseMoved);
 #endif
 
-    window->KeyDown +=
-        ref new TypedEventHandler<CoreWindow ^, KeyEventArgs ^>(this, &SDL_WinRTApp::OnKeyDown);
-
-    window->KeyUp +=
-        ref new TypedEventHandler<CoreWindow ^, KeyEventArgs ^>(this, &SDL_WinRTApp::OnKeyUp);
+    window->Dispatcher->AcceleratorKeyActivated +=
+        ref new TypedEventHandler<CoreDispatcher ^, AcceleratorKeyEventArgs ^>(this, &SDL_WinRTApp::OnAcceleratorKeyActivated);
 
     window->CharacterReceived +=
         ref new TypedEventHandler<CoreWindow ^, CharacterReceivedEventArgs ^>(this, &SDL_WinRTApp::OnCharacterReceived);
@@ -720,14 +717,9 @@ void SDL_WinRTApp::OnMouseMoved(MouseDevice ^ mouseDevice, MouseEventArgs ^ args
     WINRT_ProcessMouseMovedEvent(WINRT_GlobalSDLWindow, args);
 }
 
-void SDL_WinRTApp::OnKeyDown(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::KeyEventArgs ^ args)
-{
-    WINRT_ProcessKeyDownEvent(args);
-}
-
-void SDL_WinRTApp::OnKeyUp(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::KeyEventArgs ^ args)
+void SDL_WinRTApp::OnAcceleratorKeyActivated(Windows::UI::Core::CoreDispatcher ^ sender, Windows::UI::Core::AcceleratorKeyEventArgs ^ args)
 {
-    WINRT_ProcessKeyUpEvent(args);
+    WINRT_ProcessAcceleratorKeyActivated(args);
 }
 
 void SDL_WinRTApp::OnCharacterReceived(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::CharacterReceivedEventArgs ^ args)
diff --git a/src/core/winrt/SDL_winrtapp_direct3d.h b/src/core/winrt/SDL_winrtapp_direct3d.h
index 30867a69e264..a8795ff09c88 100644
--- a/src/core/winrt/SDL_winrtapp_direct3d.h
+++ b/src/core/winrt/SDL_winrtapp_direct3d.h
@@ -71,8 +71,7 @@ ref class SDL_WinRTApp sealed : public Windows::ApplicationModel::Core::IFramewo
     void OnPointerEntered(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::PointerEventArgs ^ args);
     void OnPointerExited(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::PointerEventArgs ^ args);
     void OnMouseMoved(Windows::Devices::Input::MouseDevice ^ mouseDevice, Windows::Devices::Input::MouseEventArgs ^ args);
-    void OnKeyDown(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::KeyEventArgs ^ args);
-    void OnKeyUp(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::KeyEventArgs ^ args);
+    void OnAcceleratorKeyActivated(Windows::UI::Core::CoreDispatcher ^ sender, Windows::UI::Core::AcceleratorKeyEventArgs ^ args);
     void OnCharacterReceived(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::CharacterReceivedEventArgs ^ args);
 
 #if NTDDI_VERSION >= NTDDI_WIN10
diff --git a/src/video/winrt/SDL_winrtevents_c.h b/src/video/winrt/SDL_winrtevents_c.h
index f5871caf34b4..7330c7442dc7 100644
--- a/src/video/winrt/SDL_winrtevents_c.h
+++ b/src/video/winrt/SDL_winrtevents_c.h
@@ -63,8 +63,7 @@ extern void WINRT_ProcessPointerWheelChangedEvent(SDL_Window *window, Windows::U
 extern void WINRT_ProcessMouseMovedEvent(SDL_Window *window, Windows::Devices::Input::MouseEventArgs ^ args);
 
 /* Keyboard */
-extern void WINRT_ProcessKeyDownEvent(Windows::UI::Core::KeyEventArgs ^ args);
-extern void WINRT_ProcessKeyUpEvent(Windows::UI::Core::KeyEventArgs ^ args);
+extern void WINRT_ProcessAcceleratorKeyActivated(Windows::UI::Core::AcceleratorKeyEventArgs ^ args);
 extern void WINRT_ProcessCharacterReceivedEvent(Windows::UI::Core::CharacterReceivedEventArgs ^ args);
 
 #if NTDDI_VERSION >= NTDDI_WIN10
diff --git a/src/video/winrt/SDL_winrtkeyboard.cpp b/src/video/winrt/SDL_winrtkeyboard.cpp
index f19f17e60331..0524db48f35a 100644
--- a/src/video/winrt/SDL_winrtkeyboard.cpp
+++ b/src/video/winrt/SDL_winrtkeyboard.cpp
@@ -34,16 +34,16 @@ extern "C" {
 #include "../../events/SDL_keyboard_c.h"
 }
 
-static SDL_Scancode WINRT_TranslateKeycode(Windows::UI::Core::KeyEventArgs ^ args)
+static SDL_Scancode WINRT_TranslateKeycode(Windows::System::VirtualKey virtualKey, const Windows::UI::Core::CorePhysicalKeyStatus& keyStatus)
 {
     SDL_Scancode code;
     Uint8 index;
-    Uint16 scanCode = args->KeyStatus.ScanCode | (args->KeyStatus.IsExtendedKey ? 0xe000 : 0);
+    Uint16 scanCode = keyStatus.ScanCode | (keyStatus.IsExtendedKey ? 0xe000 : 0);
 
     /* Pause/Break key have a special scan code with 0xe1 prefix
      * that is not properly reported under UWP.
      * Use Pause scan code that is used in Win32. */
-    if (args->VirtualKey == Windows::System::VirtualKey::Pause) {
+    if (virtualKey == Windows::System::VirtualKey::Pause) {
         scanCode = 0xe046;
     }
 
@@ -54,55 +54,28 @@ static SDL_Scancode WINRT_TranslateKeycode(Windows::UI::Core::KeyEventArgs ^ arg
     return code;
 }
 
-void WINRT_ProcessKeyDownEvent(Windows::UI::Core::KeyEventArgs ^ args)
+void WINRT_ProcessAcceleratorKeyActivated(Windows::UI::Core::AcceleratorKeyEventArgs ^ args)
 {
-    SDL_Scancode sdlScancode = WINRT_TranslateKeycode(args);
-
-#if 0
-    SDL_Keycode keycode = SDL_GetKeyFromScancode(sdlScancode);
-    SDL_Log("key down, handled=%s, ext?=%s, released?=%s, menu key down?=%s, "
-            "repeat count=%d, native scan code=0x%x, was down?=%s, vkey=%d, "
-            "sdl scan code=%d (%s), sdl key code=%d (%s)\n",
-        (args->Handled ? "1" : "0"),
-        (args->KeyStatus.IsExtendedKey ? "1" : "0"),
-        (args->KeyStatus.IsKeyReleased ? "1" : "0"),
-        (args->KeyStatus.IsMenuKeyDown ? "1" : "0"),
-        args->KeyStatus.RepeatCount,
-        args->KeyStatus.ScanCode,
-        (args->KeyStatus.WasKeyDown ? "1" : "0"),
-        args->VirtualKey,
-        sdlScancode,
-        SDL_GetScancodeName(sdlScancode),
-        keycode,
-        SDL_GetKeyName(keycode));
-    //args->Handled = true;
-#endif
-    SDL_SendKeyboardKey(0, SDL_PRESSED, sdlScancode);
-}
+    using namespace Windows::UI::Core;
 
-void WINRT_ProcessKeyUpEvent(Windows::UI::Core::KeyEventArgs ^ args)
-{
-    SDL_Scancode sdlScancode = WINRT_TranslateKeycode(args);
-#if 0
-    SDL_Keycode keycode = SDL_GetKeyFromScancode(sdlScancode);
-    SDL_Log("key up, handled=%s, ext?=%s, released?=%s, menu key down?=%s, "
-            "repeat count=%d, native scan code=0x%x, was down?=%s, vkey=%d, "
-            "sdl scan code=%d (%s), sdl key code=%d (%s)\n",
-        (args->Handled ? "1" : "0"),
-        (args->KeyStatus.IsExtendedKey ? "1" : "0"),
-        (args->KeyStatus.IsKeyReleased ? "1" : "0"),
-        (args->KeyStatus.IsMenuKeyDown ? "1" : "0"),
-        args->KeyStatus.RepeatCount,
-        args->KeyStatus.ScanCode,
-        (args->KeyStatus.WasKeyDown ? "1" : "0"),
-        args->VirtualKey,
-        sdlScancode,
-        SDL_GetScancodeName(sdlScancode),
-        keycode,
-        SDL_GetKeyName(keycode));
-    //args->Handled = true;
-#endif
-    SDL_SendKeyboardKey(0, SDL_RELEASED, sdlScancode);
+    Uint8 state;
+    SDL_Scancode code;
+
+    switch (args->EventType) {
+    case CoreAcceleratorKeyEventType::SystemKeyDown:
+    case CoreAcceleratorKeyEventType::KeyDown:
+        state = SDL_PRESSED;
+        break;
+    case CoreAcceleratorKeyEventType::SystemKeyUp:
+    case CoreAcceleratorKeyEventType::KeyUp:
+        state = SDL_RELEASED;
+        break;
+    default:
+        return;
+    }
+
+    code = WINRT_TranslateKeycode(args->VirtualKey, args->KeyStatus);
+    SDL_SendKeyboardKey(0, state, code);
 }
 
 void WINRT_ProcessCharacterReceivedEvent(Windows::UI::Core::CharacterReceivedEventArgs ^ args)