Ver Fonte

windows: support flag RIDEV_INPUTSINK in raw input (#15182)

(cherry picked from commit ae3ae4ba4407484f8c39b160cde95e39b55be778)
Mike Egger há 21 horas atrás
pai
commit
c2a910ab02

+ 17 - 0
include/SDL3/SDL_hints.h

@@ -4518,6 +4518,23 @@ extern "C" {
  */
  */
 #define SDL_HINT_WINDOWS_RAW_KEYBOARD_EXCLUDE_HOTKEYS "SDL_WINDOWS_RAW_KEYBOARD_EXCLUDE_HOTKEYS"
 #define SDL_HINT_WINDOWS_RAW_KEYBOARD_EXCLUDE_HOTKEYS "SDL_WINDOWS_RAW_KEYBOARD_EXCLUDE_HOTKEYS"
 
 
+/**
+ * A variable controlling whether the RIDEV_INPUTSINK flag is set when
+ * enabling Windows raw keyboard events.
+ *
+ * This enables the window to still receive input even if not in foreground.
+ *
+ * Focused windows that receive text input will still prevent input events from triggering.
+ *
+ * - "0": Input is not received when not in focus or foreground. (default)
+ * - "1": Input will be received even when not in focus or foreground.
+ *
+ * This hint can be set anytime.
+ *
+ * \since This hint is available since SDL 3.4.4.
+ */
+#define SDL_HINT_WINDOWS_RAW_KEYBOARD_INPUTSINK "SDL_WINDOWS_RAW_KEYBOARD_INPUTSINK"
+
 /**
 /**
  * A variable controlling whether SDL uses Kernel Semaphores on Windows.
  * A variable controlling whether SDL uses Kernel Semaphores on Windows.
  *
  *

+ 2 - 1
src/video/windows/SDL_windowsevents.c

@@ -774,7 +774,8 @@ static void WIN_HandleRawKeyboardInput(Uint64 timestamp, SDL_VideoData *data, HA
 
 
     if (down) {
     if (down) {
         SDL_Window *focus = SDL_GetKeyboardFocus();
         SDL_Window *focus = SDL_GetKeyboardFocus();
-        if (!focus || focus->text_input_active) {
+        // With input sink flag we want to receive input even if not focused
+        if ((!data->raw_keyboard_flag_inputsink && !focus) || (focus && focus->text_input_active)) {
             return;
             return;
         }
         }
     }
     }

+ 17 - 1
src/video/windows/SDL_windowsrawinput.c

@@ -35,6 +35,7 @@
 #define ENABLE_RAW_MOUSE_INPUT      0x01
 #define ENABLE_RAW_MOUSE_INPUT      0x01
 #define ENABLE_RAW_KEYBOARD_INPUT   0x02
 #define ENABLE_RAW_KEYBOARD_INPUT   0x02
 #define RAW_KEYBOARD_FLAG_NOHOTKEYS 0x04
 #define RAW_KEYBOARD_FLAG_NOHOTKEYS 0x04
+#define RAW_KEYBOARD_FLAG_INPUTSINK 0x08
 
 
 typedef struct
 typedef struct
 {
 {
@@ -85,6 +86,9 @@ static DWORD WINAPI WIN_RawInputThread(LPVOID param)
         if (data->flags & RAW_KEYBOARD_FLAG_NOHOTKEYS) {
         if (data->flags & RAW_KEYBOARD_FLAG_NOHOTKEYS) {
             devices[count].dwFlags |= RIDEV_NOHOTKEYS;
             devices[count].dwFlags |= RIDEV_NOHOTKEYS;
         }
         }
+        if (data->flags & RAW_KEYBOARD_FLAG_INPUTSINK) {
+            devices[count].dwFlags |= RIDEV_INPUTSINK;
+        }
         devices[count].hwndTarget = window;
         devices[count].hwndTarget = window;
         ++count;
         ++count;
     }
     }
@@ -215,6 +219,9 @@ static bool WIN_UpdateRawInputEnabled(SDL_VideoDevice *_this)
         if (data->raw_keyboard_flag_nohotkeys) {
         if (data->raw_keyboard_flag_nohotkeys) {
             flags |= RAW_KEYBOARD_FLAG_NOHOTKEYS;
             flags |= RAW_KEYBOARD_FLAG_NOHOTKEYS;
         }
         }
+        if (data->raw_keyboard_flag_inputsink) {
+            flags |= RAW_KEYBOARD_FLAG_INPUTSINK;
+        }
     }
     }
     if (flags != data->raw_input_enabled) {
     if (flags != data->raw_input_enabled) {
         if (WIN_SetRawInputEnabled(_this, flags)) {
         if (WIN_SetRawInputEnabled(_this, flags)) {
@@ -263,7 +270,8 @@ bool WIN_SetRawKeyboardEnabled(SDL_VideoDevice *_this, bool enabled)
 }
 }
 
 
 typedef enum WIN_RawKeyboardFlag {
 typedef enum WIN_RawKeyboardFlag {
-    NOHOTKEYS
+    NOHOTKEYS,
+    INPUTSINK,
 } WIN_RawKeyboardFlag;
 } WIN_RawKeyboardFlag;
 
 
 static bool WIN_SetRawKeyboardFlag(SDL_VideoDevice *_this, WIN_RawKeyboardFlag flag, bool enabled)
 static bool WIN_SetRawKeyboardFlag(SDL_VideoDevice *_this, WIN_RawKeyboardFlag flag, bool enabled)
@@ -274,6 +282,9 @@ static bool WIN_SetRawKeyboardFlag(SDL_VideoDevice *_this, WIN_RawKeyboardFlag f
         case NOHOTKEYS:
         case NOHOTKEYS:
             data->raw_keyboard_flag_nohotkeys = enabled;
             data->raw_keyboard_flag_nohotkeys = enabled;
             break;
             break;
+        case INPUTSINK:
+            data->raw_keyboard_flag_inputsink = enabled;
+            break;
         default:
         default:
             return false;
             return false;
     }
     }
@@ -290,6 +301,11 @@ bool WIN_SetRawKeyboardFlag_NoHotkeys(SDL_VideoDevice *_this, bool enabled)
     return WIN_SetRawKeyboardFlag(_this, NOHOTKEYS, enabled);
     return WIN_SetRawKeyboardFlag(_this, NOHOTKEYS, enabled);
 }
 }
 
 
+bool WIN_SetRawKeyboardFlag_Inputsink(SDL_VideoDevice *_this, bool enabled)
+{
+    return WIN_SetRawKeyboardFlag(_this, INPUTSINK, enabled);
+}
+
 #else
 #else
 
 
 bool WIN_SetRawMouseEnabled(SDL_VideoDevice *_this, bool enabled)
 bool WIN_SetRawMouseEnabled(SDL_VideoDevice *_this, bool enabled)

+ 1 - 0
src/video/windows/SDL_windowsrawinput.h

@@ -26,5 +26,6 @@
 extern bool WIN_SetRawMouseEnabled(SDL_VideoDevice *_this, bool enabled);
 extern bool WIN_SetRawMouseEnabled(SDL_VideoDevice *_this, bool enabled);
 extern bool WIN_SetRawKeyboardEnabled(SDL_VideoDevice *_this, bool enabled);
 extern bool WIN_SetRawKeyboardEnabled(SDL_VideoDevice *_this, bool enabled);
 extern bool WIN_SetRawKeyboardFlag_NoHotkeys(SDL_VideoDevice *_this, bool enabled);
 extern bool WIN_SetRawKeyboardFlag_NoHotkeys(SDL_VideoDevice *_this, bool enabled);
+extern bool WIN_SetRawKeyboardFlag_Inputsink(SDL_VideoDevice *_this, bool enabled);
 
 
 #endif // SDL_windowsrawinput_h_
 #endif // SDL_windowsrawinput_h_

+ 9 - 0
src/video/windows/SDL_windowsvideo.c

@@ -156,6 +156,13 @@ static void SDLCALL UpdateWindowsRawKeyboardNoHotkeys(void *userdata, const char
     WIN_SetRawKeyboardFlag_NoHotkeys(_this, enabled);
     WIN_SetRawKeyboardFlag_NoHotkeys(_this, enabled);
 }
 }
 
 
+static void SDLCALL UpdateWindowsRawKeyboardInputsink(void *userdata, const char *name, const char *oldValue, const char *newValue)
+{
+    SDL_VideoDevice *_this = (SDL_VideoDevice *)userdata;
+    bool enabled = SDL_GetStringBoolean(newValue, false);
+    WIN_SetRawKeyboardFlag_Inputsink(_this, enabled);
+}
+
 static void SDLCALL UpdateWindowsEnableMessageLoop(void *userdata, const char *name, const char *oldValue, const char *newValue)
 static void SDLCALL UpdateWindowsEnableMessageLoop(void *userdata, const char *name, const char *oldValue, const char *newValue)
 {
 {
     g_WindowsEnableMessageLoop = SDL_GetStringBoolean(newValue, true);
     g_WindowsEnableMessageLoop = SDL_GetStringBoolean(newValue, true);
@@ -640,6 +647,7 @@ static bool WIN_VideoInit(SDL_VideoDevice *_this)
 
 
     SDL_AddHintCallback(SDL_HINT_WINDOWS_RAW_KEYBOARD, UpdateWindowsRawKeyboard, _this);
     SDL_AddHintCallback(SDL_HINT_WINDOWS_RAW_KEYBOARD, UpdateWindowsRawKeyboard, _this);
     SDL_AddHintCallback(SDL_HINT_WINDOWS_RAW_KEYBOARD_EXCLUDE_HOTKEYS, UpdateWindowsRawKeyboardNoHotkeys, _this);
     SDL_AddHintCallback(SDL_HINT_WINDOWS_RAW_KEYBOARD_EXCLUDE_HOTKEYS, UpdateWindowsRawKeyboardNoHotkeys, _this);
+    SDL_AddHintCallback(SDL_HINT_WINDOWS_RAW_KEYBOARD_INPUTSINK, UpdateWindowsRawKeyboardInputsink, _this);
     SDL_AddHintCallback(SDL_HINT_WINDOWS_ENABLE_MESSAGELOOP, UpdateWindowsEnableMessageLoop, NULL);
     SDL_AddHintCallback(SDL_HINT_WINDOWS_ENABLE_MESSAGELOOP, UpdateWindowsEnableMessageLoop, NULL);
     SDL_AddHintCallback(SDL_HINT_WINDOWS_ENABLE_MENU_MNEMONICS, UpdateWindowsEnableMenuMnemonics, NULL);
     SDL_AddHintCallback(SDL_HINT_WINDOWS_ENABLE_MENU_MNEMONICS, UpdateWindowsEnableMenuMnemonics, NULL);
     SDL_AddHintCallback(SDL_HINT_WINDOW_FRAME_USABLE_WHILE_CURSOR_HIDDEN, UpdateWindowFrameUsableWhileCursorHidden, NULL);
     SDL_AddHintCallback(SDL_HINT_WINDOW_FRAME_USABLE_WHILE_CURSOR_HIDDEN, UpdateWindowFrameUsableWhileCursorHidden, NULL);
@@ -658,6 +666,7 @@ void WIN_VideoQuit(SDL_VideoDevice *_this)
 
 
     SDL_RemoveHintCallback(SDL_HINT_WINDOWS_RAW_KEYBOARD, UpdateWindowsRawKeyboard, _this);
     SDL_RemoveHintCallback(SDL_HINT_WINDOWS_RAW_KEYBOARD, UpdateWindowsRawKeyboard, _this);
     SDL_RemoveHintCallback(SDL_HINT_WINDOWS_RAW_KEYBOARD_EXCLUDE_HOTKEYS, UpdateWindowsRawKeyboardNoHotkeys, _this);
     SDL_RemoveHintCallback(SDL_HINT_WINDOWS_RAW_KEYBOARD_EXCLUDE_HOTKEYS, UpdateWindowsRawKeyboardNoHotkeys, _this);
+    SDL_RemoveHintCallback(SDL_HINT_WINDOWS_RAW_KEYBOARD_INPUTSINK, UpdateWindowsRawKeyboardInputsink, _this);
     SDL_RemoveHintCallback(SDL_HINT_WINDOWS_ENABLE_MESSAGELOOP, UpdateWindowsEnableMessageLoop, NULL);
     SDL_RemoveHintCallback(SDL_HINT_WINDOWS_ENABLE_MESSAGELOOP, UpdateWindowsEnableMessageLoop, NULL);
     SDL_RemoveHintCallback(SDL_HINT_WINDOWS_ENABLE_MENU_MNEMONICS, UpdateWindowsEnableMenuMnemonics, NULL);
     SDL_RemoveHintCallback(SDL_HINT_WINDOWS_ENABLE_MENU_MNEMONICS, UpdateWindowsEnableMenuMnemonics, NULL);
     SDL_RemoveHintCallback(SDL_HINT_WINDOW_FRAME_USABLE_WHILE_CURSOR_HIDDEN, UpdateWindowFrameUsableWhileCursorHidden, NULL);
     SDL_RemoveHintCallback(SDL_HINT_WINDOW_FRAME_USABLE_WHILE_CURSOR_HIDDEN, UpdateWindowFrameUsableWhileCursorHidden, NULL);

+ 1 - 0
src/video/windows/SDL_windowsvideo.h

@@ -594,6 +594,7 @@ struct SDL_VideoData
     bool raw_mouse_enabled;
     bool raw_mouse_enabled;
     bool raw_keyboard_enabled;
     bool raw_keyboard_enabled;
     bool raw_keyboard_flag_nohotkeys;
     bool raw_keyboard_flag_nohotkeys;
+    bool raw_keyboard_flag_inputsink;
     bool pending_E1_key_sequence;
     bool pending_E1_key_sequence;
     Uint32 raw_input_enabled;
     Uint32 raw_input_enabled;
     SDL_PenID raw_input_fake_pen_id;
     SDL_PenID raw_input_fake_pen_id;