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>
This commit is contained in:
parent
9388bbe4bd
commit
ceec35a6de
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user