diff --git a/include/SDL_system.h b/include/SDL_system.h index 7d11a5bf50..fb0135a84a 100644 --- a/include/SDL_system.h +++ b/include/SDL_system.h @@ -572,6 +572,22 @@ extern DECLSPEC const char * SDLCALL SDL_WinRTGetFSPathUTF8(SDL_WinRT_Path pathT */ extern DECLSPEC SDL_WinRT_DeviceFamily SDLCALL SDL_WinRTGetDeviceFamily(); +/** + * Get the protocol activation URI if the app was launched via protocol activation. + * + * When a UWP/WinRT app is launched via a custom URI scheme (e.g., myapp://action?param=value), + * this function retrieves the full activation URI string. + * + * The URI is only available once per activation - after the first successful call, + * subsequent calls will return NULL. This ensures the URI is processed only once. + * + * \returns the protocol activation URI as a UTF-8 string that must be freed with SDL_free(), + * or NULL if the app was not activated via protocol or the URI was already retrieved. + * + * \since This function is available since SDL 2.33.0. + */ +extern DECLSPEC char * SDLCALL SDL_WinRTGetProtocolActivationURI(void); + #endif /* __WINRT__ */ /** diff --git a/src/core/winrt/SDL_winrtapp_direct3d.cpp b/src/core/winrt/SDL_winrtapp_direct3d.cpp index 04c655dda9..cd9118f2e4 100644 --- a/src/core/winrt/SDL_winrtapp_direct3d.cpp +++ b/src/core/winrt/SDL_winrtapp_direct3d.cpp @@ -43,6 +43,7 @@ extern "C" { #include "SDL_hints.h" #include "SDL_main.h" #include "SDL_stdinc.h" +#include "SDL_system.h" #include "SDL_render.h" #include "../../video/SDL_sysvideo.h" #include "../../events/SDL_events_c.h" @@ -80,6 +81,9 @@ extern "C" void D3D11_Trim(SDL_Renderer *); // SDL_CreateWindow(). SDL_WinRTApp ^ SDL_WinRTGlobalApp = nullptr; +// Protocol activation URI storage +static Platform::String^ WINRT_ProtocolActivationURI = nullptr; + ref class SDLApplicationSource sealed : Windows::ApplicationModel::Core::IFrameworkViewSource { public: @@ -107,6 +111,22 @@ int SDL_WinRTInitNonXAMLApp(int (*mainFunction)(int, char **)) return 0; } +extern "C" char* SDL_WinRTGetProtocolActivationURI(void) +{ + if (WINRT_ProtocolActivationURI == nullptr) + return nullptr; + Platform::String^ uriStr = WINRT_ProtocolActivationURI; + const wchar_t* uriWide = uriStr->Data(); + int uriLen = WideCharToMultiByte(CP_UTF8, 0, uriWide, -1, nullptr, 0, nullptr, nullptr); + char* uriUtf8 = (char*)SDL_malloc(uriLen); + if (uriUtf8) + WideCharToMultiByte(CP_UTF8, 0, uriWide, -1, uriUtf8, uriLen, nullptr, nullptr); + + // Clear after first successful read (only return it once) + WINRT_ProtocolActivationURI = nullptr; + return uriUtf8; +} + static void WINRT_ProcessWindowSizeChange() // TODO: Pass an SDL_Window-identifying thing into WINRT_ProcessWindowSizeChange() { CoreWindow ^ coreWindow = CoreWindow::GetForCurrentThread(); @@ -589,6 +609,14 @@ void SDL_WinRTApp::OnWindowClosed(CoreWindow ^ sender, CoreWindowEventArgs ^ arg void SDL_WinRTApp::OnAppActivated(CoreApplicationView ^ applicationView, IActivatedEventArgs ^ args) { + if (args->Kind == Windows::ApplicationModel::Activation::ActivationKind::Protocol) + { + auto protocolArgs = dynamic_cast(args); + if (protocolArgs && protocolArgs->Uri) + { + WINRT_ProtocolActivationURI = protocolArgs->Uri->AbsoluteUri; + } + } CoreWindow::GetForCurrentThread()->Activate(); }