|
|
@@ -20,6 +20,8 @@
|
|
|
*/
|
|
|
#include "../../SDL_internal.h"
|
|
|
|
|
|
+/* Standard C++11 includes: */
|
|
|
+#include <string>
|
|
|
/* Windows includes */
|
|
|
#include "ppltasks.h"
|
|
|
using namespace concurrency;
|
|
|
@@ -84,6 +86,57 @@ SDL_WinRTApp ^ SDL_WinRTGlobalApp = nullptr;
|
|
|
// Protocol activation URI storage
|
|
|
static Platform::String^ WINRT_ProtocolActivationURI = nullptr;
|
|
|
|
|
|
+// Store launchOnExit URI separately since WINRT_ProtocolActivationURI gets cleared
|
|
|
+static std::wstring WINRT_LaunchOnExitURI;
|
|
|
+
|
|
|
+// Helper function to extract and store launchOnExit from protocol URI
|
|
|
+static void WINRT_ExtractLaunchOnExitURI(Platform::String^ fullUri)
|
|
|
+{
|
|
|
+ if (fullUri == nullptr)
|
|
|
+ return;
|
|
|
+
|
|
|
+ std::wstring uri(fullUri->Data());
|
|
|
+
|
|
|
+ // Look for launchOnExit parameter in the URI
|
|
|
+ size_t launchPos = uri.find(L"launchOnExit=");
|
|
|
+ if (launchPos == std::wstring::npos)
|
|
|
+ return;
|
|
|
+
|
|
|
+ // Extract the launchOnExit URI value
|
|
|
+ launchPos += 13; // Skip past "launchOnExit="
|
|
|
+ size_t endPos = uri.find(L'&', launchPos);
|
|
|
+ if (endPos == std::wstring::npos)
|
|
|
+ endPos = uri.length();
|
|
|
+
|
|
|
+ std::wstring launchUri = uri.substr(launchPos, endPos - launchPos);
|
|
|
+
|
|
|
+ // URL decode the URI (convert %3A to :, etc.)
|
|
|
+ WINRT_LaunchOnExitURI.clear();
|
|
|
+ for (size_t i = 0; i < launchUri.length(); i++) {
|
|
|
+ if (launchUri[i] == L'%' && i + 2 < launchUri.length()) {
|
|
|
+ wchar_t hex[3] = { launchUri[i + 1], launchUri[i + 2], 0 };
|
|
|
+ WINRT_LaunchOnExitURI += (wchar_t)wcstol(hex, nullptr, 16);
|
|
|
+ i += 2;
|
|
|
+ } else {
|
|
|
+ WINRT_LaunchOnExitURI += launchUri[i];
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// Helper function to launch URI on exit if protocol activation included launchOnExit parameter
|
|
|
+static void WINRT_LaunchExitUriIfSet()
|
|
|
+{
|
|
|
+ if (!WINRT_LaunchOnExitURI.empty()) {
|
|
|
+ try {
|
|
|
+ // Launch the URI
|
|
|
+ auto uri = ref new Windows::Foundation::Uri(ref new Platform::String(WINRT_LaunchOnExitURI.c_str()));
|
|
|
+ Windows::System::Launcher::LaunchUriAsync(uri);
|
|
|
+ } catch (...) {
|
|
|
+ // Silently ignore errors during termination
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
ref class SDLApplicationSource sealed : Windows::ApplicationModel::Core::IFrameworkViewSource
|
|
|
{
|
|
|
public:
|
|
|
@@ -184,6 +237,12 @@ SDL_WinRTApp::SDL_WinRTApp() : m_windowClosed(false),
|
|
|
{
|
|
|
}
|
|
|
|
|
|
+SDL_WinRTApp::~SDL_WinRTApp()
|
|
|
+{
|
|
|
+ // Launch exit URI if set (handles protocol activation returning to caller)
|
|
|
+ WINRT_LaunchExitUriIfSet();
|
|
|
+}
|
|
|
+
|
|
|
void SDL_WinRTApp::Initialize(CoreApplicationView ^ applicationView)
|
|
|
{
|
|
|
applicationView->Activated +=
|
|
|
@@ -605,6 +664,7 @@ void SDL_WinRTApp::OnWindowClosed(CoreWindow ^ sender, CoreWindowEventArgs ^ arg
|
|
|
SDL_Log("%s\n", __FUNCTION__);
|
|
|
#endif
|
|
|
m_windowClosed = true;
|
|
|
+ WINRT_LaunchExitUriIfSet();
|
|
|
}
|
|
|
|
|
|
void SDL_WinRTApp::OnAppActivated(CoreApplicationView ^ applicationView, IActivatedEventArgs ^ args)
|
|
|
@@ -615,6 +675,8 @@ void SDL_WinRTApp::OnAppActivated(CoreApplicationView ^ applicationView, IActiva
|
|
|
if (protocolArgs && protocolArgs->Uri)
|
|
|
{
|
|
|
WINRT_ProtocolActivationURI = protocolArgs->Uri->AbsoluteUri;
|
|
|
+ // Extract and store launchOnExit URI before main URI gets cleared
|
|
|
+ WINRT_ExtractLaunchOnExitURI(WINRT_ProtocolActivationURI);
|
|
|
}
|
|
|
}
|
|
|
CoreWindow::GetForCurrentThread()->Activate();
|
|
|
@@ -622,6 +684,9 @@ void SDL_WinRTApp::OnAppActivated(CoreApplicationView ^ applicationView, IActiva
|
|
|
|
|
|
void SDL_WinRTApp::OnSuspending(Platform::Object ^ sender, SuspendingEventArgs ^ args)
|
|
|
{
|
|
|
+ // Launch exit URI if set before suspending
|
|
|
+ WINRT_LaunchExitUriIfSet();
|
|
|
+
|
|
|
// Save app state asynchronously after requesting a deferral. Holding a deferral
|
|
|
// indicates that the application is busy performing suspending operations. Be
|
|
|
// aware that a deferral may not be held indefinitely. After about five seconds,
|
|
|
@@ -675,6 +740,7 @@ void SDL_WinRTApp::OnResuming(Platform::Object ^ sender, Platform::Object ^ args
|
|
|
void SDL_WinRTApp::OnExiting(Platform::Object ^ sender, Platform::Object ^ args)
|
|
|
{
|
|
|
SDL_SendAppEvent(SDL_APP_TERMINATING);
|
|
|
+ WINRT_LaunchExitUriIfSet();
|
|
|
}
|
|
|
|
|
|
static void WINRT_LogPointerEvent(const char *header, Windows::UI::Core::PointerEventArgs ^ args, Windows::Foundation::Point transformedPoint)
|