Sdl2 Add support for launchOnExit URI for WinRT

Implements extraction and launching of a 'launchOnExit' URI parameter from protocol activation in SDL_WinRTApp. The URI is stored and launched on app exit, suspension, or window close, enabling return-to-caller scenarios for protocol-activated apps.
This commit is contained in:
danprice142 authored and Sam Lantinga committed 2025-10-25 08:13:45 -07:00
1 parent c9889fb013
commit 639c7a1e52
2 files changed
+67

No files matched your search

+66
View File
@@ -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)
+1
View File
@@ -26,6 +26,7 @@ ref class SDL_WinRTApp sealed : public Windows::ApplicationModel::Core::IFramewo
{
public:
SDL_WinRTApp();
virtual ~SDL_WinRTApp();
// IFrameworkView Methods.
virtual void Initialize(Windows::ApplicationModel::Core::CoreApplicationView ^ applicationView);