From 7e48d4522ba203823ba9345286551b9b9169a7f3 Mon Sep 17 00:00:00 2001 From: Daniel Ludwig Date: Wed, 24 Jul 2024 15:11:03 +0200 Subject: [PATCH] GDK build: move suspend/constrain setup back to previous compilation unit --- src/core/gdk/SDL_gdk.cpp | 60 +++++++++++++++++++++++++++++ src/core/gdk/SDL_gdk.h | 4 ++ src/main/gdk/SDL_sysmain_runapp.cpp | 49 ++--------------------- 3 files changed, 67 insertions(+), 46 deletions(-) diff --git a/src/core/gdk/SDL_gdk.cpp b/src/core/gdk/SDL_gdk.cpp index 58000d6bda..f5f15f20cf 100644 --- a/src/core/gdk/SDL_gdk.cpp +++ b/src/core/gdk/SDL_gdk.cpp @@ -73,6 +73,66 @@ void GDK_DispatchTaskQueue(void) } } +extern "C" +int GDK_RegisterChangeNotifications(void) +{ + /* Register suspend/resume handling */ + plmSuspendComplete = CreateEventEx(nullptr, nullptr, 0, EVENT_MODIFY_STATE | SYNCHRONIZE); + if (!plmSuspendComplete) { + SDL_SetError("[GDK] Unable to create plmSuspendComplete event"); + return -1; + } + auto rascn = [](BOOLEAN quiesced, PVOID context) { + SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION, "[GDK] in RegisterAppStateChangeNotification handler"); + if (quiesced) { + ResetEvent(plmSuspendComplete); + SDL_SendAppEvent(SDL_EVENT_DID_ENTER_BACKGROUND); + + // To defer suspension, we must wait to exit this callback. + // IMPORTANT: The app must call SDL_GDKSuspendComplete() to release this lock. + (void)WaitForSingleObject(plmSuspendComplete, INFINITE); + + SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION, "[GDK] in RegisterAppStateChangeNotification handler: plmSuspendComplete event signaled."); + } else { + SDL_SendAppEvent(SDL_EVENT_WILL_ENTER_FOREGROUND); + } + }; + if (RegisterAppStateChangeNotification(rascn, NULL, &hPLM)) { + SDL_SetError("[GDK] Unable to call RegisterAppStateChangeNotification"); + return -1; + } + + /* Register constrain/unconstrain handling */ + auto raccn = [](BOOLEAN constrained, PVOID context) { + SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION, "[GDK] in RegisterAppConstrainedChangeNotification handler"); + SDL_VideoDevice *_this = SDL_GetVideoDevice(); + if (_this) { + if (constrained) { + SDL_SetKeyboardFocus(NULL); + } else { + SDL_SetKeyboardFocus(_this->windows); + } + } + }; + if (RegisterAppConstrainedChangeNotification(raccn, NULL, &hCPLM)) { + SDL_SetError("[GDK] Unable to call RegisterAppConstrainedChangeNotification"); + return -1; + } + + return 0; +} + +extern "C" +void GDK_UnregisterChangeNotifications(void) +{ + /* Unregister suspend/resume handling */ + UnregisterAppStateChangeNotification(hPLM); + CloseHandle(plmSuspendComplete); + + /* Unregister constrain/unconstrain handling */ + UnregisterAppConstrainedChangeNotification(hCPLM); +} + extern "C" void SDL_GDKSuspendComplete() { diff --git a/src/core/gdk/SDL_gdk.h b/src/core/gdk/SDL_gdk.h index d500c41fd0..913bae46da 100644 --- a/src/core/gdk/SDL_gdk.h +++ b/src/core/gdk/SDL_gdk.h @@ -22,3 +22,7 @@ /* This is called from WIN_PumpEvents on GDK */ extern void GDK_DispatchTaskQueue(void); + +extern int GDK_RegisterChangeNotifications(void); + +extern void GDK_UnregisterChangeNotifications(void); diff --git a/src/main/gdk/SDL_sysmain_runapp.cpp b/src/main/gdk/SDL_sysmain_runapp.cpp index 6ac6dee603..35de9e192d 100644 --- a/src/main/gdk/SDL_sysmain_runapp.cpp +++ b/src/main/gdk/SDL_sysmain_runapp.cpp @@ -21,6 +21,7 @@ #include "SDL_internal.h" extern "C" { +#include "../../core/gdk/SDL_gdk.h" #include "../../core/windows/SDL_windows.h" #include "../../events/SDL_events_c.h" } @@ -105,58 +106,14 @@ int SDL_RunApp(int, char**, SDL_main_func mainFunction, void *reserved) SDL_SetMainReady(); - /* Register suspend/resume handling */ - plmSuspendComplete = CreateEventEx(nullptr, nullptr, 0, EVENT_MODIFY_STATE | SYNCHRONIZE); - if (!plmSuspendComplete) { - SDL_SetError("[GDK] Unable to create plmSuspendComplete event"); - return -1; - } - auto rascn = [](BOOLEAN quiesced, PVOID context) { - SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION, "[GDK] in RegisterAppStateChangeNotification handler"); - if (quiesced) { - ResetEvent(plmSuspendComplete); - SDL_SendAppEvent(SDL_EVENT_DID_ENTER_BACKGROUND); - - // To defer suspension, we must wait to exit this callback. - // IMPORTANT: The app must call SDL_GDKSuspendComplete() to release this lock. - (void)WaitForSingleObject(plmSuspendComplete, INFINITE); - - SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION, "[GDK] in RegisterAppStateChangeNotification handler: plmSuspendComplete event signaled."); - } else { - SDL_SendAppEvent(SDL_EVENT_WILL_ENTER_FOREGROUND); - } - }; - if (RegisterAppStateChangeNotification(rascn, NULL, &hPLM)) { - SDL_SetError("[GDK] Unable to call RegisterAppStateChangeNotification"); - return -1; - } - - /* Register constrain/unconstrain handling */ - auto raccn = [](BOOLEAN constrained, PVOID context) { - SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION, "[GDK] in RegisterAppConstrainedChangeNotification handler"); - SDL_VideoDevice *_this = SDL_GetVideoDevice(); - if (_this) { - if (constrained) { - SDL_SetKeyboardFocus(NULL); - } else { - SDL_SetKeyboardFocus(_this->windows); - } - } - }; - if (RegisterAppConstrainedChangeNotification(raccn, NULL, &hCPLM)) { - SDL_SetError("[GDK] Unable to call RegisterAppConstrainedChangeNotification"); + if (GDK_RegisterChangeNotifications() != 0) { return -1; } /* Run the application main() code */ result = mainFunction(argc, argv); - /* Unregister suspend/resume handling */ - UnregisterAppStateChangeNotification(hPLM); - CloseHandle(plmSuspendComplete); - - /* Unregister constrain/unconstrain handling */ - UnregisterAppConstrainedChangeNotification(hCPLM); + GDK_UnregisterChangeNotifications(); /* !!! FIXME: This follows the docs exactly, but for some reason still leaks handles on exit? */ /* Terminate the task queue and dispatch any pending tasks */