From 0f9ca217d0f479756e50459473cad7371f29047c Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Fri, 8 Apr 2016 10:44:12 +0200 Subject: winrt: support additional activation modes Besides launching a WinRT application it can also be activated, for instance via an uri protocol, as a share target or file open event. In those cases we need to resume the main thread, which only happened for regular launches so far. In addition we create and post an activation event, which can be caught from the user application. However this requires a QCoreApplication object to be created from the main thread, hence try to query the eventdispatcher with a timeout. Task-number: QTBUG-49276 Change-Id: I4ceca59dd3b062d9a5e49d1ad80334360aafbd6f Reviewed-by: Oliver Wolff --- src/winmain/qtmain_winrt.cpp | 47 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 38 insertions(+), 9 deletions(-) (limited to 'src/winmain') diff --git a/src/winmain/qtmain_winrt.cpp b/src/winmain/qtmain_winrt.cpp index 9e5f206ea5..81ca07e447 100644 --- a/src/winmain/qtmain_winrt.cpp +++ b/src/winmain/qtmain_winrt.cpp @@ -187,12 +187,43 @@ public: } private: + HRESULT activatedLaunch(IInspectable *activateArgs) { + QCoreApplication *app = QCoreApplication::instance(); + + // Check whether the app already runs + if (!app) { +#if _MSC_VER >= 1900 + // I*EventArgs have no launch arguments, hence we + // need to prepend the application binary manually + wchar_t fn[513]; + DWORD res = GetModuleFileName(0, fn, 512); + + if (SUCCEEDED(res)) + args.prepend(QString::fromWCharArray(fn, res).toUtf8().data()); +#endif _MSC_VER >= 1900 + + ResumeThread(mainThread); + + // We give main() a max of 100ms to create an application object. + // No eventhandling needs to happen at that point, all we want is + // append our activation event + int iterations = 0; + while (true) { + app = QCoreApplication::instance(); + if (app || iterations++ > 10) + break; + Sleep(10); + } + } + + if (app) + QCoreApplication::postEvent(app, new QActivationEvent(activateArgs)); + return S_OK; + } + HRESULT __stdcall OnActivated(IActivatedEventArgs *args) Q_DECL_OVERRIDE { - QAbstractEventDispatcher *dispatcher = QCoreApplication::eventDispatcher(); - if (dispatcher) - QCoreApplication::postEvent(dispatcher, new QActivationEvent(args)); - return S_OK; + return activatedLaunch(args); } HRESULT __stdcall OnLaunched(ILaunchActivatedEventArgs *launchArgs) Q_DECL_OVERRIDE @@ -290,8 +321,7 @@ private: HRESULT __stdcall OnFileActivated(IFileActivatedEventArgs *args) Q_DECL_OVERRIDE { - Q_UNUSED(args); - return S_OK; + return activatedLaunch(args); } HRESULT __stdcall OnSearchActivated(ISearchActivatedEventArgs *args) Q_DECL_OVERRIDE @@ -302,8 +332,7 @@ private: HRESULT __stdcall OnShareTargetActivated(IShareTargetActivatedEventArgs *args) Q_DECL_OVERRIDE { - Q_UNUSED(args); - return S_OK; + return activatedLaunch(args); } HRESULT __stdcall OnFileOpenPickerActivated(IFileOpenPickerActivatedEventArgs *args) Q_DECL_OVERRIDE @@ -334,7 +363,7 @@ private: ComPtr core; QByteArray commandLine; QVarLengthArray args; - HANDLE mainThread; + HANDLE mainThread{0}; HANDLE pidFile; }; -- cgit v1.2.3