From 995719cebd7cb2e875b2d64b54b9314363eab984 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Thu, 30 Mar 2017 10:45:21 +0200 Subject: winrt: Fix dnd with non mouse input device When using anything but the mouse, there is no release event sent. Instead one needs to subscribe to the ICorePointerRedirector. Task-number: QTBUG-58781 Change-Id: I664ba24bd89ea9f513f8f11b385e2f06ece42fd0 Reviewed-by: Oliver Wolff --- src/plugins/platforms/winrt/qwinrtscreen.cpp | 23 +++++++++++++++++++++++ src/plugins/platforms/winrt/qwinrtscreen.h | 2 ++ 2 files changed, 25 insertions(+) (limited to 'src/plugins/platforms/winrt') diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp index 150fc8a25e..edfcf038d7 100644 --- a/src/plugins/platforms/winrt/qwinrtscreen.cpp +++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp @@ -91,6 +91,7 @@ typedef ITypedEventHandler PointerHandler; typedef ITypedEventHandler SizeChangedHandler; typedef ITypedEventHandler VisibilityChangedHandler; typedef ITypedEventHandler DisplayInformationHandler; +typedef ITypedEventHandler RedirectHandler; #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) typedef ITypedEventHandler VisibleBoundsChangedHandler; #endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) @@ -454,6 +455,8 @@ typedef HRESULT (__stdcall ICoreWindow::*CoreWindowCallbackRemover)(EventRegistr uint qHash(CoreWindowCallbackRemover key) { void *ptr = *(void **)(&key); return qHash(ptr); } typedef HRESULT (__stdcall IDisplayInformation::*DisplayCallbackRemover)(EventRegistrationToken); uint qHash(DisplayCallbackRemover key) { void *ptr = *(void **)(&key); return qHash(ptr); } +typedef HRESULT (__stdcall ICorePointerRedirector::*RedirectorCallbackRemover)(EventRegistrationToken); +uint qHash(RedirectorCallbackRemover key) { void *ptr = *(void **)(&key); return qHash(ptr); } #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) typedef HRESULT (__stdcall IApplicationView2::*ApplicationView2CallbackRemover)(EventRegistrationToken); uint qHash(ApplicationView2CallbackRemover key) { void *ptr = *(void **)(&key); return qHash(ptr); } @@ -464,6 +467,7 @@ class QWinRTScreenPrivate public: QTouchDevice *touchDevice; ComPtr coreWindow; + ComPtr redirect; ComPtr canvas; ComPtr view; ComPtr displayInformation; @@ -482,6 +486,7 @@ public: QHash activeKeys; QHash windowTokens; QHash displayTokens; + QHash redirectTokens; #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) QHash view2Tokens; ComPtr view2; @@ -513,6 +518,10 @@ QWinRTScreen::QWinRTScreen() hr = window->get_CoreWindow(&d->coreWindow); Q_ASSERT_SUCCEEDED(hr); + + hr = d->coreWindow.As(&d->redirect); + Q_ASSERT_SUCCEEDED(hr); + hr = d->coreWindow->Activate(); Q_ASSERT_SUCCEEDED(hr); @@ -595,6 +604,10 @@ QWinRTScreen::~QWinRTScreen() hr = (d->displayInformation.Get()->*i.key())(i.value()); Q_ASSERT_SUCCEEDED(hr); } + for (QHash::const_iterator i = d->redirectTokens.begin(); i != d->redirectTokens.end(); ++i) { + hr = (d->redirect.Get()->*i.key())(i.value()); + Q_ASSERT_SUCCEEDED(hr); + } #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) for (QHash::const_iterator i = d->view2Tokens.begin(); i != d->view2Tokens.end(); ++i) { hr = (d->view2.Get()->*i.key())(i.value()); @@ -754,6 +767,9 @@ void QWinRTScreen::initialize() Q_ASSERT_SUCCEEDED(hr); onOrientationChanged(Q_NULLPTR, Q_NULLPTR); onVisibilityChanged(nullptr, nullptr); + + hr = d->redirect->add_PointerRoutedReleased(Callback(this, &QWinRTScreen::onRedirectReleased).Get(), &d->redirectTokens[&ICorePointerRedirector::remove_PointerRoutedReleased]); + Q_ASSERT_SUCCEEDED(hr); } void QWinRTScreen::setCursorRect(const QRectF &cursorRect) @@ -1378,6 +1394,13 @@ HRESULT QWinRTScreen::onDpiChanged(IDisplayInformation *, IInspectable *) return S_OK; } +HRESULT QWinRTScreen::onRedirectReleased(ICorePointerRedirector *, IPointerEventArgs *args) +{ + // When dragging ends with a non-mouse input device then onRedirectRelease is invoked. + // QTBUG-58781 + return onPointerUpdated(nullptr, args); +} + #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) HRESULT QWinRTScreen::onWindowSizeChanged(IApplicationView *, IInspectable *) #else diff --git a/src/plugins/platforms/winrt/qwinrtscreen.h b/src/plugins/platforms/winrt/qwinrtscreen.h index 7dcdb98ead..fd6499c2b9 100644 --- a/src/plugins/platforms/winrt/qwinrtscreen.h +++ b/src/plugins/platforms/winrt/qwinrtscreen.h @@ -52,6 +52,7 @@ namespace ABI { namespace Core { struct IAutomationProviderRequestedEventArgs; struct ICharacterReceivedEventArgs; + struct ICorePointerRedirector; struct ICoreWindow; struct ICoreWindowEventArgs; struct IKeyEventArgs; @@ -149,6 +150,7 @@ private: #else HRESULT onWindowSizeChanged(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IWindowSizeChangedEventArgs *); #endif + HRESULT onRedirectReleased(ABI::Windows::UI::Core::ICorePointerRedirector *, ABI::Windows::UI::Core::IPointerEventArgs *); QScopedPointer d_ptr; QRectF mCursorRect; -- cgit v1.2.3