diff --git a/autotests/wayland/lockscreen.cpp b/autotests/wayland/lockscreen.cpp index 831503d94e..fa722f22e9 100644 --- a/autotests/wayland/lockscreen.cpp +++ b/autotests/wayland/lockscreen.cpp @@ -38,6 +38,7 @@ along with this program. If not, see . #include #include #include +#include //screenlocker #include @@ -68,6 +69,7 @@ private Q_SLOTS: void testAxisShortcut_data(); void testAxisShortcut(); void testKeyboardShortcut(); + void testTouch(); private: void unlock(); @@ -725,6 +727,44 @@ void LockScreenTest::testKeyboardShortcut() KEYRELEASE(KEY_LEFTALT); } +void LockScreenTest::testTouch() +{ + using namespace KWayland::Client; + auto touch = m_seat->createTouch(m_seat); + QVERIFY(touch); + QVERIFY(touch->isValid()); + AbstractClient *c = showWindow(); + QVERIFY(c); + QSignalSpy sequenceStartedSpy(touch, &Touch::sequenceStarted); + QVERIFY(sequenceStartedSpy.isValid()); + QSignalSpy cancelSpy(touch, &Touch::sequenceCanceled); + QVERIFY(cancelSpy.isValid()); + QSignalSpy pointRemovedSpy(touch, &Touch::pointRemoved); + QVERIFY(pointRemovedSpy.isValid()); + + quint32 timestamp = 1; + waylandServer()->backend()->touchDown(1, QPointF(25, 25), timestamp++); + QVERIFY(sequenceStartedSpy.wait()); + QCOMPARE(sequenceStartedSpy.count(), 1); + + LOCK + QVERIFY(cancelSpy.wait()); + + waylandServer()->backend()->touchUp(1, timestamp++); + QVERIFY(!pointRemovedSpy.wait(100)); + waylandServer()->backend()->touchDown(1, QPointF(25, 25), timestamp++); + waylandServer()->backend()->touchMotion(1, QPointF(26, 26), timestamp++); + waylandServer()->backend()->touchUp(1, timestamp++); + + UNLOCK + waylandServer()->backend()->touchDown(1, QPointF(25, 25), timestamp++); + QVERIFY(sequenceStartedSpy.wait()); + QCOMPARE(sequenceStartedSpy.count(), 2); + waylandServer()->backend()->touchUp(1, timestamp++); + QVERIFY(pointRemovedSpy.wait()); + QCOMPARE(pointRemovedSpy.count(), 1); +} + } WAYLANTEST_MAIN(KWin::LockScreenTest) diff --git a/input.cpp b/input.cpp index c501261e8c..31672192e5 100644 --- a/input.cpp +++ b/input.cpp @@ -403,6 +403,49 @@ public: } return true; } + bool touchDown(quint32 id, const QPointF &pos, quint32 time) { + if (!waylandServer()->isScreenLocked()) { + return false; + } + auto seat = waylandServer()->seat(); + seat->setTimestamp(time); + if (!seat->isTouchSequence()) { + input()->updateTouchWindow(pos); + } + if (touchSurfaceAllowed()) { + input()->insertTouchId(id, seat->touchDown(pos)); + } + return true; + } + bool touchMotion(quint32 id, const QPointF &pos, quint32 time) { + if (!waylandServer()->isScreenLocked()) { + return false; + } + auto seat = waylandServer()->seat(); + seat->setTimestamp(time); + if (touchSurfaceAllowed()) { + const qint32 kwaylandId = input()->touchId(id); + if (kwaylandId != -1) { + seat->touchMove(kwaylandId, pos); + } + } + return true; + } + bool touchUp(quint32 id, quint32 time) { + if (!waylandServer()->isScreenLocked()) { + return false; + } + auto seat = waylandServer()->seat(); + seat->setTimestamp(time); + if (touchSurfaceAllowed()) { + const qint32 kwaylandId = input()->touchId(id); + if (kwaylandId != -1) { + seat->touchUp(kwaylandId); + input()->removeTouchId(id); + } + } + return true; + } private: bool surfaceAllowed(KWayland::Server::SurfaceInterface *(KWayland::Server::SeatInterface::*method)() const) const { if (KWayland::Server::SurfaceInterface *s = (waylandServer()->seat()->*method)()) { @@ -419,6 +462,9 @@ private: bool keyboardSurfaceAllowed() const { return surfaceAllowed(&KWayland::Server::SeatInterface::focusedKeyboardSurface); } + bool touchSurfaceAllowed() const { + return surfaceAllowed(&KWayland::Server::SeatInterface::focusedTouchSurface); + } }; class EffectsFilter : public InputEventFilter { @@ -872,6 +918,13 @@ void InputRedirection::setupWorkspace() connect(ScreenLocker::KSldApp::self(), &ScreenLocker::KSldApp::lockStateChanged, this, &InputRedirection::updatePointerWindow); connect(ScreenLocker::KSldApp::self(), &ScreenLocker::KSldApp::lockStateChanged, this, &InputRedirection::updateKeyboardWindow); + connect(ScreenLocker::KSldApp::self(), &ScreenLocker::KSldApp::lockStateChanged, this, + [this] { + cancelTouch(); + // position doesn't matter + updateTouchWindow(QPointF()); + } + ); } setupInputFilters(); } diff --git a/input.h b/input.h index 5820228d6f..10cbb8fea8 100644 --- a/input.h +++ b/input.h @@ -156,6 +156,7 @@ public: void removeTouchId(quint32 internalId); void updateKeyboardWindow(); + void updateTouchWindow(const QPointF &pos); public Q_SLOTS: void updatePointerWindow(); @@ -209,7 +210,6 @@ private: void registerShortcutForGlobalAccelTimestamp(QAction *action); void updateFocusedPointerPosition(); void updateFocusedTouchPosition(); - void updateTouchWindow(const QPointF &pos); void updatePointerDecoration(Toplevel *t); void updatePointerInternalWindow(); void pointerInternalWindowVisibilityChanged(bool visible);