WinRT: Made app-backgrounded events get sent at separate, distinct times. SDL_APP_WILLENTERBACKGROUND is now sent as soon as the app is told that it is about to go to the background. SDL_APP_DIDENTERBACKGROUND is sent via a WinRT 'deferral operation', which is how WinRT gives apps a bit of extra time (multiple seconds worth) to prepare for an app-backgrounding. The distinction may be important as the deferral operation's code is always run in a separate thread. For Direct3D-only apps, this means that between the two SDL app-backgrounded events, SDL_APP_WILLENTERBACKGROUND will be the only one run from the main thread. Given that some WinRT operations can only be done on the main thread (operations to the CoreWindow fall into this category), this could be important. It is important to note that pre-deferral code may only have a very short bit of time to execute code, less so than code run in the deferral operation (where SDL_APP_DIDENTERBACKGROUND is sent from), which usually gets several seconds to run.
diff --git a/src/core/winrt/SDL_winrtapp_direct3d.cpp b/src/core/winrt/SDL_winrtapp_direct3d.cpp
index 02c1890..49880f2 100644
--- a/src/core/winrt/SDL_winrtapp_direct3d.cpp
+++ b/src/core/winrt/SDL_winrtapp_direct3d.cpp
@@ -564,6 +564,16 @@ void SDL_WinRTApp::OnSuspending(Platform::Object^ sender, SuspendingEventArgs^ a
// indicates that the application is busy performing suspending operations. Be
// aware that a deferral may not be held indefinitely. After about five seconds,
// the app will be forced to exit.
+
+ // ... but first, let the app know it's about to go to the background.
+ // The separation of events may be important, given that the deferral
+ // runs in a separate thread. This'll make SDL_APP_WILLENTERBACKGROUND
+ // the only event among the two that runs in the main thread. Given
+ // that a few WinRT operations can only be done from the main thread
+ // (things that access the WinRT CoreWindow are one example of this),
+ // this could be important.
+ SDL_SendAppEvent(SDL_APP_WILLENTERBACKGROUND);
+
SuspendingDeferral^ deferral = args->SuspendingOperation->GetDeferral();
create_task([this, deferral]()
{
@@ -585,7 +595,6 @@ void SDL_WinRTApp::OnSuspending(Platform::Object^ sender, SuspendingEventArgs^ a
SDL_FilterEvents(RemoveAppSuspendAndResumeEvents, 0);
}
- SDL_SendAppEvent(SDL_APP_WILLENTERBACKGROUND);
SDL_SendAppEvent(SDL_APP_DIDENTERBACKGROUND);
deferral->Complete();