summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/winrt/qwinrtcursor.cpp
diff options
context:
space:
mode:
authorOliver Wolff <oliver.wolff@qt.io>2018-07-12 13:01:14 +0200
committerOliver Wolff <oliver.wolff@qt.io>2018-08-06 05:24:35 +0000
commite05dc08ba02b4a9d893190230c8dfd2554ec4413 (patch)
tree44e4ecde31d11f5a8568304a45861a59e6b2deb0 /src/plugins/platforms/winrt/qwinrtcursor.cpp
parent01e57909d4bce31483d023cf11dd2298391b38f3 (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/qwinrtcursor.cpp')
-rw-r--r--src/plugins/platforms/winrt/qwinrtcursor.cpp40
1 files changed, 40 insertions, 0 deletions
diff --git a/src/plugins/platforms/winrt/qwinrtcursor.cpp b/src/plugins/platforms/winrt/qwinrtcursor.cpp
index 3c918df935..6236ec1f2b 100644
--- a/src/plugins/platforms/winrt/qwinrtcursor.cpp
+++ b/src/plugins/platforms/winrt/qwinrtcursor.cpp
@@ -56,6 +56,11 @@ using namespace ABI::Windows::Foundation;
QT_BEGIN_NAMESPACE
+static inline bool qIsPointInRect(const Point &p, const Rect &r)
+{
+ return (p.X >= r.X && p.Y >= r.Y && p.X < r.X + r.Width && p.Y < r.Y + r.Height);
+}
+
class QWinRTCursorPrivate
{
public:
@@ -179,5 +184,40 @@ QPoint QWinRTCursor::pos() const
: position;
}
+void QWinRTCursor::setPos(const QPoint &pos)
+{
+ QWinRTScreen *screen = static_cast<QWinRTScreen *>(QGuiApplication::primaryScreen()->handle());
+ Q_ASSERT(screen);
+ ComPtr<ICoreWindow> coreWindow = screen->coreWindow();
+ Q_ASSERT(coreWindow);
+ const QPointF scaledPos = pos / screen->scaleFactor();
+ QWinRTScreen::MousePositionTransition t;
+ HRESULT hr = QEventDispatcherWinRT::runOnXamlThread([coreWindow, scaledPos, &t]() {
+ ComPtr<ICoreWindow2> coreWindow2;
+ HRESULT hr = coreWindow.As(&coreWindow2);
+ RETURN_HR_IF_FAILED("Failed to cast core window.");
+ Rect bounds;
+ hr = coreWindow->get_Bounds(&bounds);
+ RETURN_HR_IF_FAILED("Failed to obtain window bounds.");
+ Point mousePos;
+ hr = coreWindow->get_PointerPosition(&mousePos);
+ RETURN_HR_IF_FAILED("Failed to obtain mouse position.");
+ const Point p = {FLOAT(scaledPos.x() + bounds.X), FLOAT(scaledPos.y() + bounds.Y)};
+ const bool wasInWindow = qIsPointInRect(mousePos, bounds);
+ const bool willBeInWindow = qIsPointInRect(p, bounds);
+ if (wasInWindow && willBeInWindow)
+ t = QWinRTScreen::MousePositionTransition::StayedIn;
+ else if (wasInWindow && !willBeInWindow)
+ t = QWinRTScreen::MousePositionTransition::MovedOut;
+ else if (!wasInWindow && willBeInWindow)
+ t = QWinRTScreen::MousePositionTransition::MovedIn;
+ else
+ t = QWinRTScreen::MousePositionTransition::StayedOut;
+ return coreWindow2->put_PointerPosition(p);
+ });
+ RETURN_VOID_IF_FAILED("Failed to set cursor position");
+ screen->emulateMouseMove(scaledPos, t);
+}
+
QT_END_NAMESPACE