diff --git a/autotests/integration/quick_tiling_test.cpp b/autotests/integration/quick_tiling_test.cpp --- a/autotests/integration/quick_tiling_test.cpp +++ b/autotests/integration/quick_tiling_test.cpp @@ -28,8 +28,11 @@ #include "shell_client.h" #include "scripting/scripting.h" +#include + #include #include +#include #include #include #include @@ -70,6 +73,8 @@ void testQuickTilingPointerMove(); void testQuickTilingPointerMoveXdgShell_data(); void testQuickTilingPointerMoveXdgShell(); + void testQuickTilingTouchMoveXdgShell_data(); + void testQuickTilingTouchMoveXdgShell(); void testX11QuickTiling_data(); void testX11QuickTiling(); void testX11QuickTilingAfterVertMaximize_data(); @@ -115,7 +120,7 @@ void QuickTilingTest::init() { - QVERIFY(Test::setupWaylandConnection()); + QVERIFY(Test::setupWaylandConnection(Test::AdditionalWaylandInterface::Decoration)); m_connection = Test::waylandConnection(); m_compositor = Test::waylandCompositor(); m_shell = Test::waylandShell(); @@ -496,6 +501,69 @@ QCOMPARE(false, configureRequestedSpy.last().first().toSize().isEmpty()); } +void QuickTilingTest::testQuickTilingTouchMoveXdgShell_data() +{ + QTest::addColumn("targetPos"); + QTest::addColumn("expectedMode"); + + QTest::newRow("topRight") << QPoint(2559, 24) << QuickTileMode(QuickTileFlag::Top | QuickTileFlag::Right); + QTest::newRow("right") << QPoint(2559, 512) << QuickTileMode(QuickTileFlag::Right); + QTest::newRow("bottomRight") << QPoint(2559, 1023) << QuickTileMode(QuickTileFlag::Bottom | QuickTileFlag::Right); + QTest::newRow("bottomLeft") << QPoint(0, 1023) << QuickTileMode(QuickTileFlag::Bottom | QuickTileFlag::Left); + QTest::newRow("Left") << QPoint(0, 512) << QuickTileMode(QuickTileFlag::Left); + QTest::newRow("topLeft") << QPoint(0, 24) << QuickTileMode(QuickTileFlag::Top | QuickTileFlag::Left); +} + +void QuickTilingTest::testQuickTilingTouchMoveXdgShell() +{ + // test verifies that touch on decoration also allows quick tiling + // see BUG: 390113 + using namespace KWayland::Client; + + QScopedPointer surface(Test::createSurface()); + QVERIFY(!surface.isNull()); + QScopedPointer deco(Test::waylandServerSideDecoration()->create(surface.data())); + + QScopedPointer shellSurface(Test::createXdgShellV6Surface(surface.data())); + QVERIFY(!shellSurface.isNull()); + QSignalSpy configureRequestedSpy(shellSurface.data(), &XdgShellSurface::configureRequested); + QVERIFY(configureRequestedSpy.isValid()); + // let's render + auto c = Test::renderAndWaitForShown(surface.data(), QSize(1000, 50), Qt::blue); + + QVERIFY(c); + QVERIFY(c->isDecorated()); + const auto decoration = c->decoration(); + QCOMPARE(workspace()->activeClient(), c); + QCOMPARE(c->geometry(), QRect(-decoration->borderLeft(), 0, + 1000 + decoration->borderLeft() + decoration->borderRight(), + 50 + decoration->borderTop() + decoration->borderBottom())); + QCOMPARE(c->quickTileMode(), QuickTileMode(QuickTileFlag::None)); + QCOMPARE(c->maximizeMode(), MaximizeRestore); + QVERIFY(configureRequestedSpy.wait()); + QTRY_COMPARE(configureRequestedSpy.count(), 2); + + QSignalSpy quickTileChangedSpy(c, &AbstractClient::quickTileModeChanged); + QVERIFY(quickTileChangedSpy.isValid()); + + quint32 timestamp = 1; + kwinApp()->platform()->touchDown(0, QPointF(c->geometry().center().x(), c->geometry().y() + decoration->borderTop() / 2), timestamp++); + QVERIFY(configureRequestedSpy.wait()); + QCOMPARE(c, workspace()->getMovingClient()); + QCOMPARE(configureRequestedSpy.count(), 3); + + QFETCH(QPoint, targetPos); + kwinApp()->platform()->touchMotion(0, targetPos, timestamp++); + kwinApp()->platform()->touchUp(0, timestamp++); + QVERIFY(!workspace()->getMovingClient()); + + QCOMPARE(quickTileChangedSpy.count(), 1); + QTEST(c->quickTileMode(), "expectedMode"); + QVERIFY(configureRequestedSpy.wait()); + QCOMPARE(configureRequestedSpy.count(), 5); + QCOMPARE(false, configureRequestedSpy.last().first().toSize().isEmpty()); +} + struct XcbConnectionDeleter { static inline void cleanup(xcb_connection_t *pointer) diff --git a/input.cpp b/input.cpp --- a/input.cpp +++ b/input.cpp @@ -1100,9 +1100,13 @@ } m_lastGlobalTouchPos = pos; m_lastLocalTouchPos = pos - decoration->client()->pos(); - QHoverEvent e(QEvent::HoverMove, m_lastLocalTouchPos, m_lastLocalTouchPos); - QCoreApplication::instance()->sendEvent(decoration->decoration(), &e); - decoration->client()->processDecorationMove(m_lastLocalTouchPos.toPoint(), pos.toPoint()); + if (auto c = workspace()->getMovingClient()) { + c->updateMoveResize(pos); + } else { + QHoverEvent e(QEvent::HoverMove, m_lastLocalTouchPos, m_lastLocalTouchPos); + QCoreApplication::instance()->sendEvent(decoration->decoration(), &e); + decoration->client()->processDecorationMove(m_lastLocalTouchPos.toPoint(), pos.toPoint()); + } return true; } bool touchUp(quint32 id, quint32 time) override { @@ -1119,10 +1123,14 @@ return true; } // send mouse up - QMouseEvent e(QEvent::MouseButtonRelease, m_lastLocalTouchPos, m_lastGlobalTouchPos, Qt::LeftButton, Qt::MouseButtons(), input()->keyboardModifiers()); - e.setAccepted(false); - QCoreApplication::sendEvent(decoration->decoration(), &e); - decoration->client()->processDecorationButtonRelease(&e); + if (auto c = workspace()->getMovingClient()) { + c->endMoveResize(); + } else { + QMouseEvent e(QEvent::MouseButtonRelease, m_lastLocalTouchPos, m_lastGlobalTouchPos, Qt::LeftButton, Qt::MouseButtons(), input()->keyboardModifiers()); + e.setAccepted(false); + QCoreApplication::sendEvent(decoration->decoration(), &e); + decoration->client()->processDecorationButtonRelease(&e); + } m_lastGlobalTouchPos = QPointF(); m_lastLocalTouchPos = QPointF();