diff --git a/src/video/windows/SDL_windowsevents.c b/src/video/windows/SDL_windowsevents.c index ea57c1ca42..19f49e9b36 100644 --- a/src/video/windows/SDL_windowsevents.c +++ b/src/video/windows/SDL_windowsevents.c @@ -786,7 +786,7 @@ static void WIN_HandleRawKeyboardInput(Uint64 timestamp, SDL_VideoData *data, HA SDL_SendKeyboardKey(timestamp, keyboardID, rawcode, code, down); } -void WIN_PollRawInput(SDL_VideoDevice *_this, Uint64 poll_start, bool process_input) +void WIN_PollRawInput(SDL_VideoDevice *_this, Uint64 poll_start) { SDL_VideoData *data = _this->internal; UINT size, i, count, total = 0; @@ -832,7 +832,7 @@ void WIN_PollRawInput(SDL_VideoDevice *_this, Uint64 poll_start, bool process_in } } - if (total > 0 && process_input) { + if (total > 0) { Uint64 delta = poll_finish - poll_start; UINT mouse_total = 0; for (i = 0, input = (RAWINPUT *)data->rawinput; i < total; ++i, input = NEXTRAWINPUTBLOCK(input)) { diff --git a/src/video/windows/SDL_windowsevents.h b/src/video/windows/SDL_windowsevents.h index 21bd7a420c..45f5527dc6 100644 --- a/src/video/windows/SDL_windowsevents.h +++ b/src/video/windows/SDL_windowsevents.h @@ -29,7 +29,7 @@ extern HINSTANCE SDL_Instance; extern LRESULT CALLBACK WIN_KeyboardHookProc(int nCode, WPARAM wParam, LPARAM lParam); extern LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); -extern void WIN_PollRawInput(SDL_VideoDevice *_this, Uint64 poll_start, bool process_input); +extern void WIN_PollRawInput(SDL_VideoDevice *_this, Uint64 poll_start); extern void WIN_PumpEvents(SDL_VideoDevice *_this); extern void WIN_PumpEventsForHWND(SDL_VideoDevice *_this, HWND hwnd); extern void WIN_SendWakeupEvent(SDL_VideoDevice *_this, SDL_Window *window); diff --git a/src/video/windows/SDL_windowsrawinput.c b/src/video/windows/SDL_windowsrawinput.c index 3c5d80ab2b..5ae2f51d23 100644 --- a/src/video/windows/SDL_windowsrawinput.c +++ b/src/video/windows/SDL_windowsrawinput.c @@ -40,7 +40,6 @@ typedef struct { bool done; - bool paused; Uint32 flags; HANDLE ready_event; HANDLE signal_event; @@ -48,7 +47,6 @@ typedef struct } RawInputThreadData; static RawInputThreadData thread_data = { - false, false, 0, INVALID_HANDLE_VALUE, @@ -106,34 +104,22 @@ static DWORD WINAPI WIN_RawInputThread(LPVOID param) // Tell the parent we're ready to go! SetEvent(data->ready_event); - while (!data->done) { - Uint64 idle_begin = SDL_GetTicksNS(); - while (!data->done && !data->paused && - // The high-order word of GetQueueStatus() will let us know if there's currently raw input to be processed. - // If there isn't, then we'll wait for new data to arrive with MsgWaitForMultipleObjects(). - ((HIWORD(GetQueueStatus(QS_RAWINPUT)) & QS_RAWINPUT) || - (MsgWaitForMultipleObjects(1, &data->signal_event, FALSE, INFINITE, QS_RAWINPUT) == WAIT_OBJECT_0 + 1))) { + Uint64 idle_begin = SDL_GetTicksNS(); + while (!data->done && + // The high-order word of GetQueueStatus() will let us know if there's currently raw input to be processed. + // If there isn't, then we'll wait for new data to arrive with MsgWaitForMultipleObjects(). + ((HIWORD(GetQueueStatus(QS_RAWINPUT)) & QS_RAWINPUT) || + (MsgWaitForMultipleObjects(1, &data->signal_event, FALSE, INFINITE, QS_RAWINPUT) == WAIT_OBJECT_0 + 1))) { - Uint64 idle_end = SDL_GetTicksNS(); - Uint64 idle_time = idle_end - idle_begin; - Uint64 usb_8khz_interval = SDL_US_TO_NS(125); - Uint64 poll_start = idle_time < usb_8khz_interval ? _this->internal->last_rawinput_poll : idle_end; + Uint64 idle_end = SDL_GetTicksNS(); + Uint64 idle_time = idle_end - idle_begin; + Uint64 usb_8khz_interval = SDL_US_TO_NS(125); + Uint64 poll_start = idle_time < usb_8khz_interval ? _this->internal->last_rawinput_poll : idle_end; - WIN_PollRawInput(_this, poll_start, true); + WIN_PollRawInput(_this, poll_start); - // Reset idle_begin for the next go-around - idle_begin = SDL_GetTicksNS(); - } - - if (data->paused) { - // Wait for the resume signal - while (data->paused) { - WaitForSingleObject(data->signal_event, INFINITE); - } - - // Flush raw input queued while paused - WIN_PollRawInput(_this, SDL_GetTicksNS(), false); - } + // Reset idle_begin for the next go-around + idle_begin = SDL_GetTicksNS(); } if (_this->internal->raw_input_fake_pen_id) { @@ -155,7 +141,6 @@ static DWORD WINAPI WIN_RawInputThread(LPVOID param) static void CleanupRawInputThreadData(RawInputThreadData *data) { if (data->thread != INVALID_HANDLE_VALUE) { - data->paused = false; data->done = true; SetEvent(data->signal_event); WaitForSingleObject(data->thread, 3000); @@ -174,20 +159,10 @@ static void CleanupRawInputThreadData(RawInputThreadData *data) } } -bool WIN_SetRawInputEnabled(SDL_VideoDevice *_this, Uint32 flags, bool force) +bool WIN_SetRawInputEnabled(SDL_VideoDevice *_this, Uint32 flags) { bool result = false; - if (thread_data.thread != INVALID_HANDLE_VALUE && !force) { - if (flags) { - thread_data.paused = false; - } else { - thread_data.paused = true; - } - SetEvent(thread_data.signal_event); - return true; - } - CleanupRawInputThreadData(&thread_data); if (flags) { @@ -248,13 +223,14 @@ static bool WIN_UpdateRawInputEnabled(SDL_VideoDevice *_this) if (data->raw_keyboard_flag_inputsink) { flags |= RAW_KEYBOARD_FLAG_INPUTSINK; } + + // Leave the thread running, as it takes several ms to shut it down and spin it up. + // We'll continue processing them so they don't back up in the thread event queue, + // but we won't deliver raw events in the application. + flags |= (data->raw_input_enabled & (ENABLE_RAW_MOUSE_INPUT | ENABLE_RAW_KEYBOARD_INPUT)); + if (flags != data->raw_input_enabled) { - bool force = false; - if ((flags ^ data->raw_input_enabled) & (RAW_KEYBOARD_FLAG_NOHOTKEYS | RAW_KEYBOARD_FLAG_INPUTSINK)) { - // The keyboard flags have changed - force = true; - } - if (WIN_SetRawInputEnabled(_this, flags, force)) { + if (WIN_SetRawInputEnabled(_this, flags)) { data->raw_input_enabled = flags; } else { return false; @@ -338,7 +314,7 @@ bool WIN_SetRawKeyboardFlag_Inputsink(SDL_VideoDevice *_this, bool enabled) #else -bool WIN_SetRawInputEnabled(SDL_VideoDevice *_this, Uint32 flags, bool force) +bool WIN_SetRawInputEnabled(SDL_VideoDevice *_this, Uint32 flags) { return SDL_Unsupported(); } diff --git a/src/video/windows/SDL_windowsrawinput.h b/src/video/windows/SDL_windowsrawinput.h index e970666a9a..1adeb45f05 100644 --- a/src/video/windows/SDL_windowsrawinput.h +++ b/src/video/windows/SDL_windowsrawinput.h @@ -23,7 +23,7 @@ #ifndef SDL_windowsrawinput_h_ #define SDL_windowsrawinput_h_ -extern bool WIN_SetRawInputEnabled(SDL_VideoDevice *_this, Uint32 flags, bool force); +extern bool WIN_SetRawInputEnabled(SDL_VideoDevice *_this, Uint32 flags); extern bool WIN_SetRawMouseEnabled(SDL_VideoDevice *_this, bool enabled); extern bool WIN_SetRawKeyboardEnabled(SDL_VideoDevice *_this, bool enabled); extern bool WIN_SetRawKeyboardFlag_NoHotkeys(SDL_VideoDevice *_this, bool enabled); diff --git a/src/video/windows/SDL_windowsvideo.c b/src/video/windows/SDL_windowsvideo.c index edb28e838b..019a23c2d6 100644 --- a/src/video/windows/SDL_windowsvideo.c +++ b/src/video/windows/SDL_windowsvideo.c @@ -671,7 +671,9 @@ void WIN_VideoQuit(SDL_VideoDevice *_this) SDL_RemoveHintCallback(SDL_HINT_WINDOWS_ENABLE_MENU_MNEMONICS, UpdateWindowsEnableMenuMnemonics, NULL); SDL_RemoveHintCallback(SDL_HINT_WINDOW_FRAME_USABLE_WHILE_CURSOR_HIDDEN, UpdateWindowFrameUsableWhileCursorHidden, NULL); - WIN_SetRawInputEnabled(_this, 0, true); + WIN_SetRawMouseEnabled(_this, false); + WIN_SetRawKeyboardEnabled(_this, false); + WIN_SetRawInputEnabled(_this, 0); WIN_QuitGameInput(_this); #if !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)