diff options
author | Oliver Wolff <oliver.wolff@qt.io> | 2018-07-12 13:01:14 +0200 |
---|---|---|
committer | Oliver Wolff <oliver.wolff@qt.io> | 2018-08-06 05:24:35 +0000 |
commit | e05dc08ba02b4a9d893190230c8dfd2554ec4413 (patch) | |
tree | 44e4ecde31d11f5a8568304a45861a59e6b2deb0 /src/plugins/platforms/winrt/qwinrtscreen.cpp | |
parent | 01e57909d4bce31483d023cf11dd2298391b38f3 (diff) |
winrt: Implement QPlatformCursor::setPos
Additionally to setting the cursor position we have to make sure that
enter and leave events are triggered. As WinRT at the moment only supports
maximized/fullscreen native top level widgets, an enter or leave event has
to be triggered, every time the cursor enters or leaves the core window.
Same as is done on Windows desktop an enter event is immediately followed
by a move event even for emulated mouse events.
Change-Id: I4b9a7b07f8e24b7887619f96979a064d933788aa
Reviewed-by: Maurice Kalinowski <maurice.kalinowski@qt.io>
Diffstat (limited to 'src/plugins/platforms/winrt/qwinrtscreen.cpp')
-rw-r--r-- | src/plugins/platforms/winrt/qwinrtscreen.cpp | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp index 7d6659f5e2..0c03c2865b 100644 --- a/src/plugins/platforms/winrt/qwinrtscreen.cpp +++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp @@ -491,6 +491,7 @@ public: QAtomicPointer<QWinRTWindow> keyboardGrabWindow; QWindow *currentPressWindow = nullptr; QWindow *currentTargetWindow = nullptr; + bool firstMouseMove = true; }; // To be called from the XAML thread @@ -850,6 +851,7 @@ void QWinRTScreen::addWindow(QWindow *window) } handleExpose(); + d->firstMouseMove = true; QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents); #if QT_CONFIG(draganddrop) @@ -1091,6 +1093,7 @@ HRESULT QWinRTScreen::onPointerEntered(ICoreWindow *, IPointerEventArgs *args) d->currentTargetWindow = d->mouseGrabWindow.load()->window(); QWindowSystemInterface::handleEnterEvent(d->currentTargetWindow, pos, pos); + d->firstMouseMove = false; } return S_OK; } @@ -1315,6 +1318,62 @@ HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *, IPointerEventArgs *args) return S_OK; } +void QWinRTScreen::emulateMouseMove(const QPointF &point, MousePositionTransition transition) +{ + Q_D(QWinRTScreen); + if (transition == MousePositionTransition::StayedOut) + return; + qt_winrt_lastPointerPoint = nullptr; + const QPointF pos(point.x() * d->scaleFactor, point.y() * d->scaleFactor); + QPointF localPos = pos; + + const QPoint posPoint = pos.toPoint(); + QWindow *windowUnderPointer = windowAt(QHighDpiScaling::mapPositionFromNative(posPoint, this)); + d->currentTargetWindow = windowUnderPointer; + + if (d->mouseGrabWindow) + d->currentTargetWindow = d->mouseGrabWindow.load()->window(); + + if (d->currentTargetWindow) { + const QPointF globalPosDelta = pos - posPoint; + localPos = d->currentTargetWindow->mapFromGlobal(posPoint) + globalPosDelta; + } + + // In case of a mouse grab we have to store the target of a press event + // to be able to send one additional release event to this target when the mouse + // button is released. This is a similar approach to AutoMouseCapture in the + // windows qpa backend. Otherwise the release might not be propagated and the original + // press event receiver considers a button to still be pressed, as in Qt Quick Controls 1 + // menus. + if (d->currentPressWindow && d->mouseGrabWindow) { + const QPointF globalPosDelta = pos - posPoint; + const QPointF localPressPos = d->currentPressWindow->mapFromGlobal(posPoint) + globalPosDelta; + + QWindowSystemInterface::handleMouseEvent(d->currentPressWindow, localPressPos, pos, + Qt::NoButton, Qt::NoModifier); + d->currentPressWindow = nullptr; + } + // If the mouse button is released outside of a window, targetWindow is 0, but the event + // has to be delivered to the window, that initially received the mouse press. Do not reset + // d->currentTargetWindow though, as it is used (and reset) in onPointerExited. + if (d->currentPressWindow && !d->currentTargetWindow) { + d->currentTargetWindow = d->currentPressWindow; + d->currentPressWindow = nullptr; + } + + if (transition == MousePositionTransition::MovedOut) { + QWindowSystemInterface::handleLeaveEvent(d->currentTargetWindow); + return; + } + + if (transition == MousePositionTransition::MovedIn || d->firstMouseMove) { + QWindowSystemInterface::handleEnterEvent(d->currentTargetWindow, localPos, pos); + d->firstMouseMove = false; + } + QWindowSystemInterface::handleMouseEvent(d->currentTargetWindow, localPos, pos, Qt::NoButton, + Qt::NoModifier); +} + HRESULT QWinRTScreen::onActivated(ICoreWindow *, IWindowActivatedEventArgs *args) { Q_D(QWinRTScreen); |