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);