winphone: Properly close the application

When shutting down an application on Windows Phone the SceneGraph tries
to create an offscreen surface to render into. If there is no offscreen
surface available, it creates a new native window and tries to hide it.
As the native event loop is about to shut down, creation fails and
exceptions are raised. Instead we create a vanilla
QPlatformOffscreenSurface. The SceneGraph recognizes it as such and can
handle a proper cleanup on its own.

Furthermore removing the suspend/resume handler in the destructor of
QWinRTIntegration fails for Windows Phone as the application object
itself does not accept this anymore. Hence skip this part for this
platform.

Task-number: QTBUG-49310
Change-Id: I02acdd5a635ef0b9d6ef8199376537b8f0f1a8fb
Reviewed-by: Oliver Wolff <oliver.wolff@theqtcompany.com>
bb10
Maurice Kalinowski 2016-01-08 12:50:32 +01:00
parent c4ecab7127
commit becbffe291
3 changed files with 22 additions and 0 deletions

View File

@ -46,6 +46,7 @@
#define EGL_EGLEXT_PROTOTYPES
#include <EGL/eglext.h>
#include <QOffscreenSurface>
#include <QOpenGLContext>
#include <QtPlatformSupport/private/qeglconvenience_p.h>
@ -147,6 +148,9 @@ bool QWinRTEGLContext::makeCurrent(QPlatformSurface *windowSurface)
Q_D(QWinRTEGLContext);
Q_ASSERT(windowSurface->surface()->supportsOpenGL());
if (windowSurface->surface()->surfaceClass() == QSurface::Offscreen)
return false;
QWinRTWindow *window = static_cast<QWinRTWindow *>(windowSurface);
if (window->eglSurface() == EGL_NO_SURFACE)
window->createEglSurface(g->eglDisplay, d->eglConfig);

View File

@ -49,6 +49,8 @@
#include <QtGui/QOpenGLContext>
#include <qfunctions_winrt.h>
#include <qpa/qplatformoffscreensurface.h>
#include <functional>
#include <wrl.h>
#include <windows.ui.xaml.h>
@ -180,10 +182,15 @@ QWinRTIntegration::~QWinRTIntegration()
Q_ASSERT_SUCCEEDED(hr);
}
#endif
// Do not execute this on Windows Phone as the application is already
// shutting down and trying to unregister suspending/resume handler will
// cause exceptions and assert in debug mode
#ifndef Q_OS_WINPHONE
for (QHash<CoreApplicationCallbackRemover, EventRegistrationToken>::const_iterator i = d->applicationTokens.begin(); i != d->applicationTokens.end(); ++i) {
hr = (d->application.Get()->*i.key())(i.value());
Q_ASSERT_SUCCEEDED(hr);
}
#endif
destroyScreen(d->mainScreen);
Windows::Foundation::Uninitialize();
}
@ -349,4 +356,14 @@ HRESULT QWinRTIntegration::onResume(IInspectable *, IInspectable *)
return S_OK;
}
QPlatformOffscreenSurface *QWinRTIntegration::createPlatformOffscreenSurface(QOffscreenSurface *surface) const
{
// This is only used for shutdown of applications.
// In case we do not return an empty surface the scenegraph will try
// to create a new native window during application exit causing crashes
// or assertions.
return new QPlatformOffscreenSurface(surface);
}
QT_END_NAMESPACE

View File

@ -98,6 +98,7 @@ public:
QStringList themeNames() const Q_DECL_OVERRIDE;
QPlatformTheme *createPlatformTheme(const QString &name) const Q_DECL_OVERRIDE;
QPlatformOffscreenSurface *createPlatformOffscreenSurface(QOffscreenSurface *surface) const Q_DECL_OVERRIDE;
private:
#ifdef Q_OS_WINPHONE
HRESULT onBackButtonPressed(IInspectable *, ABI::Windows::Phone::UI::Input::IBackPressedEventArgs *args);