WinRT: Gracefully exit an application
authorMaurice Kalinowski <maurice.kalinowski@theqtcompany.com>
Fri, 16 Jan 2015 10:29:54 +0000 (11:29 +0100)
committerJani Heikkinen <jani.heikkinen@theqtcompany.com>
Mon, 2 Feb 2015 10:26:47 +0000 (10:26 +0000)
While it is not recommended by Microsoft to manually exit an
application, currently applications just hang when exiting main().

Instead when QCoreApplication::exit() is called use the CoreApplication
to properly invoke native Exit() and let the application completely shut
down.

Add a warning to notify developer about this non-standard behavior, as
usually the system is supposed to take care of suspending and closing.

Certification still passes for Windows RT and Windows Phone.

Task-number: QTBUG-43862
Change-Id: Ia34443ea75daaaeca0bee2a0c9fcc568c0659262
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@theqtcompany.com>
src/corelib/kernel/qcoreapplication.cpp

index ca3d92bad11a7ebaef6a9b875efef688791908fa..6b0ebf8b8b18a95a7ddff9fcc3fab8a14b1d599d 100644 (file)
 #ifdef Q_OS_WIN
 # ifdef Q_OS_WINRT
 #  include "qeventdispatcher_winrt_p.h"
+#  include "qfunctions_winrt.h"
+#  include <wrl.h>
+#  include <Windows.ApplicationModel.core.h>
+   using namespace ABI::Windows::ApplicationModel::Core;
+   using namespace Microsoft::WRL;
 # else
 #  include "qeventdispatcher_win_p.h"
 # endif
@@ -1221,6 +1226,19 @@ void QCoreApplication::exit(int returnCode)
         QEventLoop *eventLoop = data->eventLoops.at(i);
         eventLoop->exit(returnCode);
     }
+#ifdef Q_OS_WINRT
+    qWarning("QCoreApplication::exit: It is not recommended to explicitly exit an application on Windows Store Apps");
+    ComPtr<ICoreApplication> app;
+    HRESULT hr = RoGetActivationFactory(Wrappers::HString::MakeReference(RuntimeClass_Windows_ApplicationModel_Core_CoreApplication).Get(),
+                                IID_PPV_ARGS(&app));
+    RETURN_VOID_IF_FAILED("Could not acquire ICoreApplication object");
+    ComPtr<ICoreApplicationExit> appExit;
+
+    hr = app.As(&appExit);
+    RETURN_VOID_IF_FAILED("Could not acquire ICoreApplicationExit object");
+    hr = appExit->Exit();
+    RETURN_VOID_IF_FAILED("Could not exit application");
+#endif // Q_OS_WINRT
 }
 
 /*****************************************************************************