From ceec35a6deb0e14cb2edadab8dbd18cfeff7320f Mon Sep 17 00:00:00 2001 From: Samuel Nevala Date: Mon, 19 Oct 2015 15:14:52 +0300 Subject: winrt: Connect callbacks after after integration class constructed. It was possible for Windows Runtime callback to run while integration class was constructed. That caused an assert when handling application state change. Fix this by connecting callbacks after integration class fully constructed. Change-Id: I029c2e1f932e8edc3665443cc17dbf11eaae1bf6 Task-Id: QTBUG-48109 Reviewed-by: Andrew Knight --- src/plugins/platforms/winrt/qwinrtintegration.cpp | 29 +++--- src/plugins/platforms/winrt/qwinrtintegration.h | 1 + src/plugins/platforms/winrt/qwinrtscreen.cpp | 103 +++++++++++++--------- src/plugins/platforms/winrt/qwinrtscreen.h | 4 +- 4 files changed, 77 insertions(+), 60 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/winrt/qwinrtintegration.cpp b/src/plugins/platforms/winrt/qwinrtintegration.cpp index 612f722481..fd50d4f579 100644 --- a/src/plugins/platforms/winrt/qwinrtintegration.cpp +++ b/src/plugins/platforms/winrt/qwinrtintegration.cpp @@ -133,25 +133,13 @@ QWinRTIntegration::QWinRTIntegration() : d_ptr(new QWinRTIntegrationPrivate) Q_ASSERT_SUCCEEDED(hr); #endif // Q_OS_WINPHONE - hr = QEventDispatcherWinRT::runOnXamlThread([this, d]() { - HRESULT hr; - ComPtr windowStatics; - hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_Xaml_Window).Get(), - IID_PPV_ARGS(&windowStatics)); - Q_ASSERT_SUCCEEDED(hr); - ComPtr window; - hr = windowStatics->get_Current(&window); - Q_ASSERT_SUCCEEDED(hr); - hr = window->Activate(); - Q_ASSERT_SUCCEEDED(hr); - - d->mainScreen = new QWinRTScreen(window.Get()); - d->inputContext.reset(new QWinRTInputContext(d->mainScreen)); - screenAdded(d->mainScreen); + QEventDispatcherWinRT::runOnXamlThread([d]() { + d->mainScreen = new QWinRTScreen; return S_OK; }); - Q_ASSERT_SUCCEEDED(hr); + d->inputContext.reset(new QWinRTInputContext(d->mainScreen)); + screenAdded(d->mainScreen); d->platformServices = new QWinRTServices; } @@ -184,6 +172,15 @@ QAbstractEventDispatcher *QWinRTIntegration::createEventDispatcher() const return new QWinRTEventDispatcher; } +void QWinRTIntegration::initialize() +{ + Q_D(const QWinRTIntegration); + QEventDispatcherWinRT::runOnXamlThread([d]() { + d->mainScreen->initialize(); + return S_OK; + }); +} + bool QWinRTIntegration::hasCapability(QPlatformIntegration::Capability cap) const { switch (cap) { diff --git a/src/plugins/platforms/winrt/qwinrtintegration.h b/src/plugins/platforms/winrt/qwinrtintegration.h index 600e79442a..3a151e1ed8 100644 --- a/src/plugins/platforms/winrt/qwinrtintegration.h +++ b/src/plugins/platforms/winrt/qwinrtintegration.h @@ -88,6 +88,7 @@ public: QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const Q_DECL_OVERRIDE; QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const Q_DECL_OVERRIDE; QAbstractEventDispatcher *createEventDispatcher() const Q_DECL_OVERRIDE; + void initialize() Q_DECL_OVERRIDE; QPlatformFontDatabase *fontDatabase() const Q_DECL_OVERRIDE; QPlatformInputContext *inputContext() const Q_DECL_OVERRIDE; QPlatformServices *services() const Q_DECL_OVERRIDE; diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp index 563753cfcb..0fe3262398 100644 --- a/src/plugins/platforms/winrt/qwinrtscreen.cpp +++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp @@ -447,7 +447,7 @@ public: }; // To be called from the XAML thread -QWinRTScreen::QWinRTScreen(Xaml::IWindow *xamlWindow) +QWinRTScreen::QWinRTScreen() : d_ptr(new QWinRTScreenPrivate) { Q_D(QWinRTScreen); @@ -455,7 +455,17 @@ QWinRTScreen::QWinRTScreen(Xaml::IWindow *xamlWindow) d->touchDevice = Q_NULLPTR; HRESULT hr; - hr = xamlWindow->get_CoreWindow(&d->coreWindow); + ComPtr windowStatics; + hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_Xaml_Window).Get(), + IID_PPV_ARGS(&windowStatics)); + Q_ASSERT_SUCCEEDED(hr); + ComPtr window; + hr = windowStatics->get_Current(&window); + Q_ASSERT_SUCCEEDED(hr); + hr = window->Activate(); + Q_ASSERT_SUCCEEDED(hr); + + hr = window->get_CoreWindow(&d->coreWindow); Q_ASSERT_SUCCEEDED(hr); hr = d->coreWindow->Activate(); Q_ASSERT_SUCCEEDED(hr); @@ -465,35 +475,6 @@ QWinRTScreen::QWinRTScreen(Xaml::IWindow *xamlWindow) Q_ASSERT_SUCCEEDED(hr); d->logicalSize = QSizeF(rect.Width, rect.Height); - hr = d->coreWindow->add_KeyDown(Callback(this, &QWinRTScreen::onKeyDown).Get(), &d->windowTokens[&ICoreWindow::remove_KeyDown]); - Q_ASSERT_SUCCEEDED(hr); - hr = d->coreWindow->add_KeyUp(Callback(this, &QWinRTScreen::onKeyUp).Get(), &d->windowTokens[&ICoreWindow::remove_KeyUp]); - Q_ASSERT_SUCCEEDED(hr); - hr = d->coreWindow->add_CharacterReceived(Callback(this, &QWinRTScreen::onCharacterReceived).Get(), &d->windowTokens[&ICoreWindow::remove_CharacterReceived]); - Q_ASSERT_SUCCEEDED(hr); - hr = d->coreWindow->add_PointerEntered(Callback(this, &QWinRTScreen::onPointerEntered).Get(), &d->windowTokens[&ICoreWindow::remove_PointerEntered]); - Q_ASSERT_SUCCEEDED(hr); - hr = d->coreWindow->add_PointerExited(Callback(this, &QWinRTScreen::onPointerExited).Get(), &d->windowTokens[&ICoreWindow::remove_PointerExited]); - Q_ASSERT_SUCCEEDED(hr); - hr = d->coreWindow->add_PointerMoved(Callback(this, &QWinRTScreen::onPointerUpdated).Get(), &d->windowTokens[&ICoreWindow::remove_PointerMoved]); - Q_ASSERT_SUCCEEDED(hr); - hr = d->coreWindow->add_PointerPressed(Callback(this, &QWinRTScreen::onPointerUpdated).Get(), &d->windowTokens[&ICoreWindow::remove_PointerPressed]); - Q_ASSERT_SUCCEEDED(hr); - hr = d->coreWindow->add_PointerReleased(Callback(this, &QWinRTScreen::onPointerUpdated).Get(), &d->windowTokens[&ICoreWindow::remove_PointerReleased]); - Q_ASSERT_SUCCEEDED(hr); - hr = d->coreWindow->add_PointerWheelChanged(Callback(this, &QWinRTScreen::onPointerUpdated).Get(), &d->windowTokens[&ICoreWindow::remove_PointerWheelChanged]); - Q_ASSERT_SUCCEEDED(hr); -#ifndef Q_OS_WINPHONE - hr = d->coreWindow->add_SizeChanged(Callback(this, &QWinRTScreen::onSizeChanged).Get(), &d->windowTokens[&ICoreWindow::remove_SizeChanged]); - Q_ASSERT_SUCCEEDED(hr); -#endif - hr = d->coreWindow->add_Activated(Callback(this, &QWinRTScreen::onActivated).Get(), &d->windowTokens[&ICoreWindow::remove_Activated]); - Q_ASSERT_SUCCEEDED(hr); - hr = d->coreWindow->add_Closed(Callback(this, &QWinRTScreen::onClosed).Get(), &d->windowTokens[&ICoreWindow::remove_Closed]); - Q_ASSERT_SUCCEEDED(hr); - hr = d->coreWindow->add_VisibilityChanged(Callback(this, &QWinRTScreen::onVisibilityChanged).Get(), &d->windowTokens[&ICoreWindow::remove_VisibilityChanged]); - Q_ASSERT_SUCCEEDED(hr); - // Orientation handling ComPtr displayInformationStatics; hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Graphics_Display_DisplayInformation).Get(), @@ -509,12 +490,6 @@ QWinRTScreen::QWinRTScreen(Xaml::IWindow *xamlWindow) Q_ASSERT_SUCCEEDED(hr); d->nativeOrientation = static_cast(static_cast(qtOrientationsFromNative(displayOrientation))); - hr = d->displayInformation->add_OrientationChanged(Callback(this, &QWinRTScreen::onOrientationChanged).Get(), &d->displayTokens[&IDisplayInformation::remove_OrientationChanged]); - Q_ASSERT_SUCCEEDED(hr); - - hr = d->displayInformation->add_DpiChanged(Callback(this, &QWinRTScreen::onDpiChanged).Get(), &d->displayTokens[&IDisplayInformation::remove_DpiChanged]); - Q_ASSERT_SUCCEEDED(hr); - // Set initial orientation & pixel density onDpiChanged(Q_NULLPTR, Q_NULLPTR); d->orientation = d->nativeOrientation; @@ -542,7 +517,7 @@ QWinRTScreen::QWinRTScreen(Xaml::IWindow *xamlWindow) ComPtr uiElement; hr = canvas.As(&uiElement); Q_ASSERT_SUCCEEDED(hr); - hr = xamlWindow->put_Content(uiElement.Get()); + hr = window->put_Content(uiElement.Get()); Q_ASSERT_SUCCEEDED(hr); hr = canvas.As(&d->canvas); Q_ASSERT_SUCCEEDED(hr); @@ -556,10 +531,6 @@ QWinRTScreen::QWinRTScreen(Xaml::IWindow *xamlWindow) Q_ASSERT_SUCCEEDED(hr); hr = statusBarStatics->GetForCurrentView(&d->statusBar); Q_ASSERT_SUCCEEDED(hr); - hr = d->statusBar->add_Showing(Callback(this, &QWinRTScreen::onStatusBarShowing).Get(), &d->statusBarTokens[&IStatusBar::remove_Showing]); - Q_ASSERT_SUCCEEDED(hr); - hr = d->statusBar->add_Hiding(Callback(this, &QWinRTScreen::onStatusBarHiding).Get(), &d->statusBarTokens[&IStatusBar::remove_Hiding]); - Q_ASSERT_SUCCEEDED(hr); #endif // Q_OS_WINPHONE } @@ -726,6 +697,50 @@ void QWinRTScreen::setStatusBarVisibility(bool visible, QWindow *window) } #endif //Q_OS_WINPHONE +void QWinRTScreen::initialize() +{ + Q_D(QWinRTScreen); + HRESULT hr; + hr = d->coreWindow->add_KeyDown(Callback(this, &QWinRTScreen::onKeyDown).Get(), &d->windowTokens[&ICoreWindow::remove_KeyDown]); + Q_ASSERT_SUCCEEDED(hr); + hr = d->coreWindow->add_KeyUp(Callback(this, &QWinRTScreen::onKeyUp).Get(), &d->windowTokens[&ICoreWindow::remove_KeyUp]); + Q_ASSERT_SUCCEEDED(hr); + hr = d->coreWindow->add_CharacterReceived(Callback(this, &QWinRTScreen::onCharacterReceived).Get(), &d->windowTokens[&ICoreWindow::remove_CharacterReceived]); + Q_ASSERT_SUCCEEDED(hr); + hr = d->coreWindow->add_PointerEntered(Callback(this, &QWinRTScreen::onPointerEntered).Get(), &d->windowTokens[&ICoreWindow::remove_PointerEntered]); + Q_ASSERT_SUCCEEDED(hr); + hr = d->coreWindow->add_PointerExited(Callback(this, &QWinRTScreen::onPointerExited).Get(), &d->windowTokens[&ICoreWindow::remove_PointerExited]); + Q_ASSERT_SUCCEEDED(hr); + hr = d->coreWindow->add_PointerMoved(Callback(this, &QWinRTScreen::onPointerUpdated).Get(), &d->windowTokens[&ICoreWindow::remove_PointerMoved]); + Q_ASSERT_SUCCEEDED(hr); + hr = d->coreWindow->add_PointerPressed(Callback(this, &QWinRTScreen::onPointerUpdated).Get(), &d->windowTokens[&ICoreWindow::remove_PointerPressed]); + Q_ASSERT_SUCCEEDED(hr); + hr = d->coreWindow->add_PointerReleased(Callback(this, &QWinRTScreen::onPointerUpdated).Get(), &d->windowTokens[&ICoreWindow::remove_PointerReleased]); + Q_ASSERT_SUCCEEDED(hr); + hr = d->coreWindow->add_PointerWheelChanged(Callback(this, &QWinRTScreen::onPointerUpdated).Get(), &d->windowTokens[&ICoreWindow::remove_PointerWheelChanged]); + Q_ASSERT_SUCCEEDED(hr); +#ifndef Q_OS_WINPHONE + hr = d->coreWindow->add_SizeChanged(Callback(this, &QWinRTScreen::onSizeChanged).Get(), &d->windowTokens[&ICoreWindow::remove_SizeChanged]); + Q_ASSERT_SUCCEEDED(hr); +#else + hr = d->statusBar->add_Showing(Callback(this, &QWinRTScreen::onStatusBarShowing).Get(), &d->statusBarTokens[&IStatusBar::remove_Showing]); + Q_ASSERT_SUCCEEDED(hr); + hr = d->statusBar->add_Hiding(Callback(this, &QWinRTScreen::onStatusBarHiding).Get(), &d->statusBarTokens[&IStatusBar::remove_Hiding]); + Q_ASSERT_SUCCEEDED(hr); +#endif + hr = d->coreWindow->add_Activated(Callback(this, &QWinRTScreen::onActivated).Get(), &d->windowTokens[&ICoreWindow::remove_Activated]); + Q_ASSERT_SUCCEEDED(hr); + hr = d->coreWindow->add_Closed(Callback(this, &QWinRTScreen::onClosed).Get(), &d->windowTokens[&ICoreWindow::remove_Closed]); + Q_ASSERT_SUCCEEDED(hr); + hr = d->coreWindow->add_VisibilityChanged(Callback(this, &QWinRTScreen::onVisibilityChanged).Get(), &d->windowTokens[&ICoreWindow::remove_VisibilityChanged]); + Q_ASSERT_SUCCEEDED(hr); + hr = d->displayInformation->add_OrientationChanged(Callback(this, &QWinRTScreen::onOrientationChanged).Get(), &d->displayTokens[&IDisplayInformation::remove_OrientationChanged]); + Q_ASSERT_SUCCEEDED(hr); + hr = d->displayInformation->add_DpiChanged(Callback(this, &QWinRTScreen::onDpiChanged).Get(), &d->displayTokens[&IDisplayInformation::remove_DpiChanged]); + Q_ASSERT_SUCCEEDED(hr); + onVisibilityChanged(nullptr, nullptr); +} + QWindow *QWinRTScreen::topWindow() const { Q_D(const QWinRTScreen); @@ -1089,8 +1104,10 @@ HRESULT QWinRTScreen::onClosed(ICoreWindow *, ICoreWindowEventArgs *) HRESULT QWinRTScreen::onVisibilityChanged(ICoreWindow *, IVisibilityChangedEventArgs *args) { + Q_D(QWinRTScreen); boolean visible; - args->get_Visible(&visible); + HRESULT hr = args ? args->get_Visible(&visible) : d->coreWindow->get_Visible(&visible); + RETURN_OK_IF_FAILED("Failed to get visbile."); QWindowSystemInterface::handleApplicationStateChanged(visible ? Qt::ApplicationActive : Qt::ApplicationHidden); if (visible) handleExpose(); diff --git a/src/plugins/platforms/winrt/qwinrtscreen.h b/src/plugins/platforms/winrt/qwinrtscreen.h index 3297617740..0043b2cfa3 100644 --- a/src/plugins/platforms/winrt/qwinrtscreen.h +++ b/src/plugins/platforms/winrt/qwinrtscreen.h @@ -83,7 +83,7 @@ class QWinRTScreenPrivate; class QWinRTScreen : public QPlatformScreen { public: - explicit QWinRTScreen(ABI::Windows::UI::Xaml::IWindow *xamlWindow); + explicit QWinRTScreen(); ~QWinRTScreen(); QRect geometry() const Q_DECL_OVERRIDE; #ifdef Q_OS_WINPHONE @@ -115,6 +115,8 @@ public: void setStatusBarVisibility(bool visible, QWindow *window); #endif + void initialize(); + private: void handleExpose(); -- cgit v1.2.3