adds GDK suspend/resume basic handling (#6596)

(cherry picked from commit f6144dfe03)
This commit is contained in:
Ciro Mondueri
2022-11-23 16:41:14 -03:00
committed by Sam Lantinga
parent a5b0583b7c
commit 896e200d94
4 changed files with 54 additions and 0 deletions

View File

@@ -20,16 +20,24 @@
*/
#include "../../SDL_internal.h"
extern "C" {
#include "SDL_system.h"
#include "../windows/SDL_windows.h"
#include "SDL_messagebox.h"
#include "SDL_main.h"
#include "SDL_events.h"
#include "../../events/SDL_events_c.h"
}
#include <XGameRuntime.h>
#include <xsapi-c/services_c.h>
#include <shellapi.h> /* CommandLineToArgvW() */
#include <appnotify.h>
static XTaskQueueHandle GDK_GlobalTaskQueue;
PAPPSTATE_REGISTRATION hPLM = {};
HANDLE plmSuspendComplete = nullptr;
extern "C" DECLSPEC int
SDL_GDKGetTaskQueue(XTaskQueueHandle * outTaskQueue)
{
@@ -144,9 +152,40 @@ SDL_GDKRunApp(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_APP_DIDENTERBACKGROUND);
// 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_APP_WILLENTERFOREGROUND);
}
};
if (RegisterAppStateChangeNotification(rascn, NULL, &hPLM)) {
SDL_SetError("[GDK] Unable to call RegisterAppStateChangeNotification");
return -1;
}
/* Run the application main() code */
result = mainFunction(argc, argv);
/* Unregister suspend/resume handling */
UnregisterAppStateChangeNotification(hPLM);
CloseHandle(plmSuspendComplete);
/* !!! FIXME: This follows the docs exactly, but for some reason still leaks handles on exit? */
/* Terminate the task queue and dispatch any pending tasks */
XTaskQueueTerminate(taskQueue, false, nullptr, nullptr);
@@ -173,3 +212,10 @@ SDL_GDKRunApp(SDL_main_func mainFunction, void *reserved)
return result;
}
extern "C" DECLSPEC void
SDL_GDKSuspendComplete() {
if (plmSuspendComplete) {
SetEvent(plmSuspendComplete);
}
}