diff options
author | Samuel Nevala <samuel.nevala@intopalo.com> | 2015-10-19 15:14:52 +0300 |
---|---|---|
committer | Samuel Nevala <samuel.nevala@intopalo.com> | 2015-10-22 08:58:23 +0000 |
commit | ceec35a6deb0e14cb2edadab8dbd18cfeff7320f (patch) | |
tree | 06274321564e92efaa0ac2f684db09545fbe92a0 /src | |
parent | 9388bbe4bdc366760c0ee5953d5f2157c51a8e68 (diff) |
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 <andrew.knight@intopalo.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/plugins/platforms/winrt/qwinrtintegration.cpp | 29 | ||||
-rw-r--r-- | src/plugins/platforms/winrt/qwinrtintegration.h | 1 | ||||
-rw-r--r-- | src/plugins/platforms/winrt/qwinrtscreen.cpp | 103 | ||||
-rw-r--r-- | src/plugins/platforms/winrt/qwinrtscreen.h | 4 |
4 files changed, 77 insertions, 60 deletions
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<Xaml::IWindowStatics> windowStatics; - hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_Xaml_Window).Get(), - IID_PPV_ARGS(&windowStatics)); - Q_ASSERT_SUCCEEDED(hr); - ComPtr<Xaml::IWindow> 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<Xaml::IWindowStatics> windowStatics; + hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_Xaml_Window).Get(), + IID_PPV_ARGS(&windowStatics)); + Q_ASSERT_SUCCEEDED(hr); + ComPtr<Xaml::IWindow> 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<KeyHandler>(this, &QWinRTScreen::onKeyDown).Get(), &d->windowTokens[&ICoreWindow::remove_KeyDown]); - Q_ASSERT_SUCCEEDED(hr); - hr = d->coreWindow->add_KeyUp(Callback<KeyHandler>(this, &QWinRTScreen::onKeyUp).Get(), &d->windowTokens[&ICoreWindow::remove_KeyUp]); - Q_ASSERT_SUCCEEDED(hr); - hr = d->coreWindow->add_CharacterReceived(Callback<CharacterReceivedHandler>(this, &QWinRTScreen::onCharacterReceived).Get(), &d->windowTokens[&ICoreWindow::remove_CharacterReceived]); - Q_ASSERT_SUCCEEDED(hr); - hr = d->coreWindow->add_PointerEntered(Callback<PointerHandler>(this, &QWinRTScreen::onPointerEntered).Get(), &d->windowTokens[&ICoreWindow::remove_PointerEntered]); - Q_ASSERT_SUCCEEDED(hr); - hr = d->coreWindow->add_PointerExited(Callback<PointerHandler>(this, &QWinRTScreen::onPointerExited).Get(), &d->windowTokens[&ICoreWindow::remove_PointerExited]); - Q_ASSERT_SUCCEEDED(hr); - hr = d->coreWindow->add_PointerMoved(Callback<PointerHandler>(this, &QWinRTScreen::onPointerUpdated).Get(), &d->windowTokens[&ICoreWindow::remove_PointerMoved]); - Q_ASSERT_SUCCEEDED(hr); - hr = d->coreWindow->add_PointerPressed(Callback<PointerHandler>(this, &QWinRTScreen::onPointerUpdated).Get(), &d->windowTokens[&ICoreWindow::remove_PointerPressed]); - Q_ASSERT_SUCCEEDED(hr); - hr = d->coreWindow->add_PointerReleased(Callback<PointerHandler>(this, &QWinRTScreen::onPointerUpdated).Get(), &d->windowTokens[&ICoreWindow::remove_PointerReleased]); - Q_ASSERT_SUCCEEDED(hr); - hr = d->coreWindow->add_PointerWheelChanged(Callback<PointerHandler>(this, &QWinRTScreen::onPointerUpdated).Get(), &d->windowTokens[&ICoreWindow::remove_PointerWheelChanged]); - Q_ASSERT_SUCCEEDED(hr); -#ifndef Q_OS_WINPHONE - hr = d->coreWindow->add_SizeChanged(Callback<SizeChangedHandler>(this, &QWinRTScreen::onSizeChanged).Get(), &d->windowTokens[&ICoreWindow::remove_SizeChanged]); - Q_ASSERT_SUCCEEDED(hr); -#endif - hr = d->coreWindow->add_Activated(Callback<ActivatedHandler>(this, &QWinRTScreen::onActivated).Get(), &d->windowTokens[&ICoreWindow::remove_Activated]); - Q_ASSERT_SUCCEEDED(hr); - hr = d->coreWindow->add_Closed(Callback<ClosedHandler>(this, &QWinRTScreen::onClosed).Get(), &d->windowTokens[&ICoreWindow::remove_Closed]); - Q_ASSERT_SUCCEEDED(hr); - hr = d->coreWindow->add_VisibilityChanged(Callback<VisibilityChangedHandler>(this, &QWinRTScreen::onVisibilityChanged).Get(), &d->windowTokens[&ICoreWindow::remove_VisibilityChanged]); - Q_ASSERT_SUCCEEDED(hr); - // Orientation handling ComPtr<IDisplayInformationStatics> 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<Qt::ScreenOrientation>(static_cast<int>(qtOrientationsFromNative(displayOrientation))); - hr = d->displayInformation->add_OrientationChanged(Callback<DisplayInformationHandler>(this, &QWinRTScreen::onOrientationChanged).Get(), &d->displayTokens[&IDisplayInformation::remove_OrientationChanged]); - Q_ASSERT_SUCCEEDED(hr); - - hr = d->displayInformation->add_DpiChanged(Callback<DisplayInformationHandler>(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<Xaml::IUIElement> 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<StatusBarHandler>(this, &QWinRTScreen::onStatusBarShowing).Get(), &d->statusBarTokens[&IStatusBar::remove_Showing]); - Q_ASSERT_SUCCEEDED(hr); - hr = d->statusBar->add_Hiding(Callback<StatusBarHandler>(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<KeyHandler>(this, &QWinRTScreen::onKeyDown).Get(), &d->windowTokens[&ICoreWindow::remove_KeyDown]); + Q_ASSERT_SUCCEEDED(hr); + hr = d->coreWindow->add_KeyUp(Callback<KeyHandler>(this, &QWinRTScreen::onKeyUp).Get(), &d->windowTokens[&ICoreWindow::remove_KeyUp]); + Q_ASSERT_SUCCEEDED(hr); + hr = d->coreWindow->add_CharacterReceived(Callback<CharacterReceivedHandler>(this, &QWinRTScreen::onCharacterReceived).Get(), &d->windowTokens[&ICoreWindow::remove_CharacterReceived]); + Q_ASSERT_SUCCEEDED(hr); + hr = d->coreWindow->add_PointerEntered(Callback<PointerHandler>(this, &QWinRTScreen::onPointerEntered).Get(), &d->windowTokens[&ICoreWindow::remove_PointerEntered]); + Q_ASSERT_SUCCEEDED(hr); + hr = d->coreWindow->add_PointerExited(Callback<PointerHandler>(this, &QWinRTScreen::onPointerExited).Get(), &d->windowTokens[&ICoreWindow::remove_PointerExited]); + Q_ASSERT_SUCCEEDED(hr); + hr = d->coreWindow->add_PointerMoved(Callback<PointerHandler>(this, &QWinRTScreen::onPointerUpdated).Get(), &d->windowTokens[&ICoreWindow::remove_PointerMoved]); + Q_ASSERT_SUCCEEDED(hr); + hr = d->coreWindow->add_PointerPressed(Callback<PointerHandler>(this, &QWinRTScreen::onPointerUpdated).Get(), &d->windowTokens[&ICoreWindow::remove_PointerPressed]); + Q_ASSERT_SUCCEEDED(hr); + hr = d->coreWindow->add_PointerReleased(Callback<PointerHandler>(this, &QWinRTScreen::onPointerUpdated).Get(), &d->windowTokens[&ICoreWindow::remove_PointerReleased]); + Q_ASSERT_SUCCEEDED(hr); + hr = d->coreWindow->add_PointerWheelChanged(Callback<PointerHandler>(this, &QWinRTScreen::onPointerUpdated).Get(), &d->windowTokens[&ICoreWindow::remove_PointerWheelChanged]); + Q_ASSERT_SUCCEEDED(hr); +#ifndef Q_OS_WINPHONE + hr = d->coreWindow->add_SizeChanged(Callback<SizeChangedHandler>(this, &QWinRTScreen::onSizeChanged).Get(), &d->windowTokens[&ICoreWindow::remove_SizeChanged]); + Q_ASSERT_SUCCEEDED(hr); +#else + hr = d->statusBar->add_Showing(Callback<StatusBarHandler>(this, &QWinRTScreen::onStatusBarShowing).Get(), &d->statusBarTokens[&IStatusBar::remove_Showing]); + Q_ASSERT_SUCCEEDED(hr); + hr = d->statusBar->add_Hiding(Callback<StatusBarHandler>(this, &QWinRTScreen::onStatusBarHiding).Get(), &d->statusBarTokens[&IStatusBar::remove_Hiding]); + Q_ASSERT_SUCCEEDED(hr); +#endif + hr = d->coreWindow->add_Activated(Callback<ActivatedHandler>(this, &QWinRTScreen::onActivated).Get(), &d->windowTokens[&ICoreWindow::remove_Activated]); + Q_ASSERT_SUCCEEDED(hr); + hr = d->coreWindow->add_Closed(Callback<ClosedHandler>(this, &QWinRTScreen::onClosed).Get(), &d->windowTokens[&ICoreWindow::remove_Closed]); + Q_ASSERT_SUCCEEDED(hr); + hr = d->coreWindow->add_VisibilityChanged(Callback<VisibilityChangedHandler>(this, &QWinRTScreen::onVisibilityChanged).Get(), &d->windowTokens[&ICoreWindow::remove_VisibilityChanged]); + Q_ASSERT_SUCCEEDED(hr); + hr = d->displayInformation->add_OrientationChanged(Callback<DisplayInformationHandler>(this, &QWinRTScreen::onOrientationChanged).Get(), &d->displayTokens[&IDisplayInformation::remove_OrientationChanged]); + Q_ASSERT_SUCCEEDED(hr); + hr = d->displayInformation->add_DpiChanged(Callback<DisplayInformationHandler>(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(); |