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:
1 parent
c9889fb013
commit
639c7a1e52
2 files changed
+67
No files matched your search
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in new issue
Block a user