From 79c274b942992d08078a6055f8c0eac93f90c98a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Thu, 11 Feb 2016 14:20:06 +0100 Subject: [PATCH] [autotest] Add test case for update pointer focus after screen change The test removes the second screen while the cursor is on it. This should warp the pointer to the center of first screen and trigger a focus enter event. As can be seen by the expect failures currently it's bound to libinput and also doesn't process the event as if it were a pointer event. --- autotests/wayland/pointer_input.cpp | 58 +++++++++++++++++++++++++++-- 1 file changed, 54 insertions(+), 4 deletions(-) diff --git a/autotests/wayland/pointer_input.cpp b/autotests/wayland/pointer_input.cpp index 1afe4bc87c..9516d7974f 100644 --- a/autotests/wayland/pointer_input.cpp +++ b/autotests/wayland/pointer_input.cpp @@ -55,9 +55,10 @@ private Q_SLOTS: void cleanup(); void testWarpingUpdatesFocus(); void testWarpingGeneratesPointerMotion(); + void testUpdateFocusAfterScreenChange(); private: - void render(KWayland::Client::Surface *surface); + void render(KWayland::Client::Surface *surface, const QSize &size = QSize(100, 50)); KWayland::Client::ConnectionThread *m_connection = nullptr; KWayland::Client::Compositor *m_compositor = nullptr; KWayland::Client::Seat *m_seat = nullptr; @@ -167,12 +168,12 @@ void PointerInputTest::cleanup() } } -void PointerInputTest::render(KWayland::Client::Surface *surface) +void PointerInputTest::render(KWayland::Client::Surface *surface, const QSize &size) { - QImage img(QSize(100, 50), QImage::Format_ARGB32); + QImage img(size, QImage::Format_ARGB32); img.fill(Qt::blue); surface->attachBuffer(m_shm->createBuffer(img)); - surface->damage(QRect(0, 0, 100, 50)); + surface->damage(QRect(QPoint(0, 0), size)); surface->commit(KWayland::Client::Surface::CommitFlag::None); m_connection->flush(); } @@ -264,6 +265,55 @@ void PointerInputTest::testWarpingGeneratesPointerMotion() QCOMPARE(movedSpy.last().first().toPointF(), QPointF(26, 26)); } +void PointerInputTest::testUpdateFocusAfterScreenChange() +{ + // this test verifies that a pointer enter event is generated when the cursor changes to another + // screen due to removal of screen + using namespace KWayland::Client; + // ensure cursor is on second screen + Cursor::setPos(1500, 300); + + // create pointer and signal spy for enter and motion + auto pointer = m_seat->createPointer(m_seat); + QVERIFY(pointer); + QVERIFY(pointer->isValid()); + QSignalSpy enteredSpy(pointer, &Pointer::entered); + QVERIFY(enteredSpy.isValid()); + + // create a window + QSignalSpy clientAddedSpy(waylandServer(), &WaylandServer::shellClientAdded); + QVERIFY(clientAddedSpy.isValid()); + Surface *surface = m_compositor->createSurface(m_compositor); + QVERIFY(surface); + ShellSurface *shellSurface = m_shell->createSurface(surface, surface); + QVERIFY(shellSurface); + render(surface, QSize(1280, 1024)); + QVERIFY(clientAddedSpy.wait()); + AbstractClient *window = workspace()->activeClient(); + QVERIFY(window); + QVERIFY(!window->geometry().contains(Cursor::pos())); + + QSignalSpy screensChangedSpy(screens(), &Screens::changed); + QVERIFY(screensChangedSpy.isValid()); + // now let's remove the screen containing the cursor + QMetaObject::invokeMethod(waylandServer()->backend(), "setOutputCount", Qt::DirectConnection, Q_ARG(int, 1)); + QMetaObject::invokeMethod(waylandServer()->backend(), "sizeChanged", Qt::QueuedConnection); + QVERIFY(screensChangedSpy.wait()); + QCOMPARE(screens()->count(), 1); + + // this should have warped the cursor + QEXPECT_FAIL("", "Doesn't work yet, requires libinput", Continue); + QCOMPARE(Cursor::pos(), QPoint(639, 511)); + QEXPECT_FAIL("", "Doesn't work yet, requires libinput", Continue); + QVERIFY(window->geometry().contains(Cursor::pos())); + + // and we should get an enter event + QEXPECT_FAIL("", "Not yet passed through", Continue); + QVERIFY(enteredSpy.wait()); + QEXPECT_FAIL("", "Not yet passed through", Continue); + QCOMPARE(enteredSpy.count(), 1); +} + } WAYLANDTEST_MAIN(KWin::PointerInputTest)