diff --git a/autotests/wayland/move_resize_window_test.cpp b/autotests/wayland/move_resize_window_test.cpp
index 3f1b27456f..2d9946f622 100644
--- a/autotests/wayland/move_resize_window_test.cpp
+++ b/autotests/wayland/move_resize_window_test.cpp
@@ -36,6 +36,8 @@ along with this program. If not, see .
#include
#include
+#include
+
Q_DECLARE_METATYPE(KWin::AbstractClient::QuickTileMode)
Q_DECLARE_METATYPE(KWin::MaximizeMode)
@@ -58,6 +60,8 @@ private Q_SLOTS:
void testPackAgainstClient();
void testGrowShrink_data();
void testGrowShrink();
+ void testPointerMoveEnd_data();
+ void testPointerMoveEnd();
private:
KWayland::Client::ConnectionThread *m_connection = nullptr;
@@ -448,6 +452,82 @@ void MoveResizeWindowTest::testGrowShrink()
QTEST(c->geometry(), "expectedGeometry");
}
+void MoveResizeWindowTest::testPointerMoveEnd_data()
+{
+ QTest::addColumn("additionalButton");
+
+ QTest::newRow("BTN_RIGHT") << BTN_RIGHT;
+ QTest::newRow("BTN_MIDDLE") << BTN_MIDDLE;
+ QTest::newRow("BTN_SIDE") << BTN_SIDE;
+ QTest::newRow("BTN_EXTRA") << BTN_EXTRA;
+ QTest::newRow("BTN_FORWARD") << BTN_FORWARD;
+ QTest::newRow("BTN_BACK") << BTN_BACK;
+ QTest::newRow("BTN_TASK") << BTN_TASK;
+ for (int i=BTN_TASK + 1; i < BTN_JOYSTICK; i++) {
+ QTest::newRow(QByteArray::number(i, 16).constData()) << i;
+ }
+}
+
+void MoveResizeWindowTest::testPointerMoveEnd()
+{
+ // this test verifies that moving a window through pointer only ends if all buttons are released
+ using namespace KWayland::Client;
+
+ QSignalSpy clientAddedSpy(waylandServer(), &WaylandServer::shellClientAdded);
+ QVERIFY(clientAddedSpy.isValid());
+
+ QScopedPointer surface(m_compositor->createSurface());
+ QVERIFY(!surface.isNull());
+
+ QScopedPointer shellSurface(m_shell->createSurface(surface.data()));
+ QVERIFY(!shellSurface.isNull());
+ QSignalSpy sizeChangeSpy(shellSurface.data(), &ShellSurface::sizeChanged);
+ QVERIFY(sizeChangeSpy.isValid());
+ // let's render
+ QImage img(QSize(100, 50), QImage::Format_ARGB32);
+ img.fill(Qt::blue);
+ surface->attachBuffer(m_shm->createBuffer(img));
+ surface->damage(QRect(0, 0, 100, 50));
+ surface->commit(Surface::CommitFlag::None);
+
+ m_connection->flush();
+ QVERIFY(clientAddedSpy.wait());
+ AbstractClient *c = workspace()->activeClient();
+ QVERIFY(c);
+ QVERIFY(!c->isMove());
+
+ // let's trigger the left button
+ quint32 timestamp = 1;
+ waylandServer()->backend()->pointerButtonPressed(BTN_LEFT, timestamp++);
+ QVERIFY(!c->isMove());
+ workspace()->slotWindowMove();
+ QVERIFY(c->isMove());
+
+ // let's press another button
+ QFETCH(int, additionalButton);
+ waylandServer()->backend()->pointerButtonPressed(additionalButton, timestamp++);
+ QVERIFY(c->isMove());
+
+ // release the left button, should still have the window moving
+ waylandServer()->backend()->pointerButtonReleased(BTN_LEFT, timestamp++);
+ QEXPECT_FAIL("BTN_SIDE", "Not yet mapped", Continue);
+ QEXPECT_FAIL("BTN_EXTRA", "Not yet mapped", Continue);
+ QEXPECT_FAIL("BTN_TASK", "Not yet mapped", Continue);
+ QEXPECT_FAIL("118", "Not yet mapped", Continue);
+ QEXPECT_FAIL("119", "Not yet mapped", Continue);
+ QEXPECT_FAIL("11a", "Not yet mapped", Continue);
+ QEXPECT_FAIL("11b", "Not yet mapped", Continue);
+ QEXPECT_FAIL("11c", "Not yet mapped", Continue);
+ QEXPECT_FAIL("11d", "Not yet mapped", Continue);
+ QEXPECT_FAIL("11e", "Not yet mapped", Continue);
+ QEXPECT_FAIL("11f", "Not yet mapped", Continue);
+ QVERIFY(c->isMove());
+
+ // but releasing the other button should now end moving
+ waylandServer()->backend()->pointerButtonReleased(additionalButton, timestamp++);
+ QVERIFY(!c->isMove());
+}
+
}
WAYLANDTEST_MAIN(KWin::MoveResizeWindowTest)