From 921e27257cf13d7e3acf5ac6ee3c7dc18417d955 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Thu, 4 Aug 2016 10:39:23 +0200 Subject: [PATCH] [wayland] Ensure that pointer enter event carries the correct coordinates So far KWin's pointer surface enter handling was: 1. update fouced surface 2. update the global position On client side this resulted in: 1. Enter with incorrect coordinates 2. move event to correct coordinate With QtWayland this results in the case of multiple surfaces in one application that Qt doesn't properly process the enter event and the Window never getting pointer focus and not reacting on any pointer input events. The root problem is that the KWayland server API is not ideal for supporting this situation. There is an API call for setting the global position (which causes a pointer motion for the focused surface) and an API call to update the focused surface. But a combination for both is (still) missing. This change addresses the problem by first unsetting the entered surface, then updating the global position and afterwards setting the new surface. Thus the position is correct. While this needs to be made better in KWayland, this is an urgency bug fix to get the behavior correct and thus first working around the API deficit and not first extending in KWayland. Reviewed-By: bshah --- autotests/wayland/pointer_input.cpp | 8 +++----- pointer_input.cpp | 3 +++ 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/autotests/wayland/pointer_input.cpp b/autotests/wayland/pointer_input.cpp index bd2ede8ce5..b8bd60c4ab 100644 --- a/autotests/wayland/pointer_input.cpp +++ b/autotests/wayland/pointer_input.cpp @@ -232,6 +232,7 @@ void PointerInputTest::testWarpingUpdatesFocus() Cursor::setPos(QPoint(25, 25)); QVERIFY(enteredSpy.wait()); QCOMPARE(enteredSpy.count(), 1); + QCOMPARE(enteredSpy.first().at(1).toPointF(), QPointF(25, 25)); // window should have focus QCOMPARE(pointer->enteredSurface(), surface); // also on the server @@ -274,15 +275,12 @@ void PointerInputTest::testWarpingGeneratesPointerMotion() // enter kwinApp()->platform()->pointerMotion(QPointF(25, 25), 1); QVERIFY(enteredSpy.wait()); - // we get a move event together with the enter, that's actually wrong but also shouldn't harm - QVERIFY(movedSpy.wait()); - QCOMPARE(movedSpy.count(), 1); - QCOMPARE(movedSpy.first().first().toPointF(), QPointF(25, 25)); + QCOMPARE(enteredSpy.first().at(1).toPointF(), QPointF(25, 25)); // now warp Cursor::setPos(QPoint(26, 26)); QVERIFY(movedSpy.wait()); - QCOMPARE(movedSpy.count(), 2); + QCOMPARE(movedSpy.count(), 1); QCOMPARE(movedSpy.last().first().toPointF(), QPointF(26, 26)); } diff --git a/pointer_input.cpp b/pointer_input.cpp index 7a8bfac172..ee33624130 100644 --- a/pointer_input.cpp +++ b/pointer_input.cpp @@ -281,6 +281,9 @@ void PointerInputRedirection::update() } if (t && t->surface()) { m_window = QPointer(t); + // TODO: add convenient API to update global pos together with updating focused surface + seat->setFocusedPointerSurface(nullptr); + seat->setPointerPos(m_pos.toPoint()); seat->setFocusedPointerSurface(t->surface(), t->inputTransformation()); m_windowGeometryConnection = connect(t, &Toplevel::geometryChanged, this, [this] {