diff --git a/src/video/SDL_sysvideo.h b/src/video/SDL_sysvideo.h index 2132c57fd307c..ff1c8b30d499d 100644 --- a/src/video/SDL_sysvideo.h +++ b/src/video/SDL_sysvideo.h @@ -225,6 +225,15 @@ struct SDL_VideoDevice */ bool (*VideoInit)(SDL_VideoDevice *_this); + /* + * Called when Video subsystem is beginning to terminate. This allows for + * special case code that need to happen before internal SDL bits + * clean up that must happen before VideoQuit(). An example is stopping + * a hotplug thread that might add mice/keyboards after SDL has cleaned + * up its internal list. Most work is meant to happen in VideoQuit, though. + */ + void (*VideoPreQuit)(SDL_VideoDevice *_this); + /* * Reverse the effects VideoInit() -- called if VideoInit() fails or * if the application is shutting down the video subsystem. diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index 874065afbfb32..bd8ae2d8a981e 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -4718,6 +4718,10 @@ void SDL_QuitVideo(void) _this->is_quitting = true; + if (_this->VideoPreQuit) { + _this->VideoPreQuit(_this); + } + // Halt event processing before doing anything else #if 0 // This was moved to the end to fix a memory leak SDL_QuitPen(); diff --git a/src/video/windows/SDL_windowsvideo.c b/src/video/windows/SDL_windowsvideo.c index 4824b76f69e51..30e4e5339553a 100644 --- a/src/video/windows/SDL_windowsvideo.c +++ b/src/video/windows/SDL_windowsvideo.c @@ -136,6 +136,7 @@ struct ITaskbarList3 // Initialization/Query functions static bool WIN_VideoInit(SDL_VideoDevice *_this); static void WIN_VideoQuit(SDL_VideoDevice *_this); +static void WIN_VideoPreQuit(SDL_VideoDevice *_this); // Hints bool g_WindowsEnableMessageLoop = true; @@ -327,6 +328,7 @@ static SDL_VideoDevice *WIN_CreateDevice(void) // Set the function pointers device->VideoInit = WIN_VideoInit; + device->VideoPreQuit = WIN_VideoPreQuit; device->VideoQuit = WIN_VideoQuit; #if !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES) device->RefreshDisplays = WIN_RefreshDisplays; @@ -669,6 +671,13 @@ static bool WIN_VideoInit(SDL_VideoDevice *_this) return true; } +void WIN_VideoPreQuit(SDL_VideoDevice *_this) +{ +#if !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES) + WIN_QuitDeviceNotification(); // stop hotplug thread before the rest of the video subsystem cleans up. +#endif +} + void WIN_VideoQuit(SDL_VideoDevice *_this) { SDL_VideoData *data = _this->internal; @@ -685,7 +694,6 @@ void WIN_VideoQuit(SDL_VideoDevice *_this) #if !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES) WIN_QuitModes(_this); - WIN_QuitDeviceNotification(); WIN_QuitKeyboard(_this); WIN_QuitMouse(_this);