From dfd0664fd6702d35876a58c6afd8dc17bae98680 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Fri, 5 Feb 2016 15:39:04 +0100 Subject: [PATCH] [autotest] Add a test for a KWin internal QWindow The test creates a QRasterWindow which through KWin's internal QPA is considered an internal window. In the test methods we simulate various pointer events (enter/leave, press/release, wheel). --- autotests/wayland/CMakeLists.txt | 9 + autotests/wayland/internal_window.cpp | 226 ++++++++++++++++++++++++++ 2 files changed, 235 insertions(+) create mode 100644 autotests/wayland/internal_window.cpp diff --git a/autotests/wayland/CMakeLists.txt b/autotests/wayland/CMakeLists.txt index 6be8f71c4d..da7fccb581 100644 --- a/autotests/wayland/CMakeLists.txt +++ b/autotests/wayland/CMakeLists.txt @@ -62,3 +62,12 @@ add_executable(testDecorationInput ${testDecorationInput_SRCS}) target_link_libraries( testDecorationInput kwin Qt5::Test) add_test(kwin-testDecorationInput testDecorationInput) ecm_mark_as_test(testDecorationInput) + +######################################################## +# Internal Window test +######################################################## +set( testInternalWindow_SRCS internal_window.cpp kwin_wayland_test.cpp ) +add_executable(testInternalWindow ${testInternalWindow_SRCS}) +target_link_libraries( testInternalWindow kwin Qt5::Test) +add_test(kwin-testInternalWindow testInternalWindow) +ecm_mark_as_test(testInternalWindow) diff --git a/autotests/wayland/internal_window.cpp b/autotests/wayland/internal_window.cpp new file mode 100644 index 0000000000..7b56843233 --- /dev/null +++ b/autotests/wayland/internal_window.cpp @@ -0,0 +1,226 @@ +/******************************************************************** +KWin - the KDE window manager +This file is part of the KDE project. + +Copyright (C) 2016 Martin Gräßlin + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*********************************************************************/ +#include "kwin_wayland_test.h" +#include "abstract_backend.h" +#include "cursor.h" +#include "shell_client.h" +#include "screens.h" +#include "wayland_server.h" +#include "workspace.h" + +#include +#include + +#include + +namespace KWin +{ + +static const QString s_socketName = QStringLiteral("wayland_test_kwin_internal_window-0"); + +class InternalWindowTest : public QObject +{ + Q_OBJECT +private Q_SLOTS: + void initTestCase(); + void init(); + void testEnterLeave(); + void testPointerPressRelease(); + void testPointerAxis(); +}; + +class HelperWindow : public QRasterWindow +{ + Q_OBJECT +public: + HelperWindow(); + ~HelperWindow(); + +Q_SIGNALS: + void entered(); + void left(); + void mouseMoved(const QPoint &global); + void mousePressed(); + void mouseReleased(); + void wheel(); + +protected: + void paintEvent(QPaintEvent *event) override; + bool event(QEvent *event) override; + void mouseMoveEvent(QMouseEvent *event) override; + void mousePressEvent(QMouseEvent *event) override; + void mouseReleaseEvent(QMouseEvent *event) override; + void wheelEvent(QWheelEvent *event) override; +}; + +HelperWindow::HelperWindow() + : QRasterWindow(nullptr) +{ +} + +HelperWindow::~HelperWindow() = default; + +void HelperWindow::paintEvent(QPaintEvent *event) +{ + Q_UNUSED(event) + QPainter p(this); + p.fillRect(0, 0, width(), height(), Qt::red); +} + +bool HelperWindow::event(QEvent *event) +{ + if (event->type() == QEvent::Enter) { + emit entered(); + } + if (event->type() == QEvent::Leave) { + emit left(); + } + return QRasterWindow::event(event); +} + +void HelperWindow::mouseMoveEvent(QMouseEvent *event) +{ + emit mouseMoved(event->globalPos()); +} + +void HelperWindow::mousePressEvent(QMouseEvent *event) +{ + Q_UNUSED(event) + emit mousePressed(); +} + +void HelperWindow::mouseReleaseEvent(QMouseEvent *event) +{ + Q_UNUSED(event) + emit mouseReleased(); +} + +void HelperWindow::wheelEvent(QWheelEvent *event) +{ + Q_UNUSED(event) + emit wheel(); +} + +void InternalWindowTest::initTestCase() +{ + qRegisterMetaType(); + qRegisterMetaType(); + QSignalSpy workspaceCreatedSpy(kwinApp(), &Application::workspaceCreated); + QVERIFY(workspaceCreatedSpy.isValid()); + waylandServer()->backend()->setInitialWindowSize(QSize(1280, 1024)); + QMetaObject::invokeMethod(waylandServer()->backend(), "setOutputCount", Qt::DirectConnection, Q_ARG(int, 2)); + waylandServer()->init(s_socketName.toLocal8Bit()); + + kwinApp()->start(); + QVERIFY(workspaceCreatedSpy.wait()); + QCOMPARE(screens()->count(), 2); + QCOMPARE(screens()->geometry(0), QRect(0, 0, 1280, 1024)); + QCOMPARE(screens()->geometry(1), QRect(1280, 0, 1280, 1024)); + waylandServer()->initWorkspace(); +} + +void InternalWindowTest::init() +{ + Cursor::setPos(QPoint(1280, 512)); +} + +void InternalWindowTest::testEnterLeave() +{ + QSignalSpy clientAddedSpy(waylandServer(), &WaylandServer::shellClientAdded); + QVERIFY(clientAddedSpy.isValid()); + HelperWindow win; + win.setGeometry(0, 0, 100, 100); + win.show(); + + QVERIFY(clientAddedSpy.wait()); + QCOMPARE(clientAddedSpy.count(), 1); + QVERIFY(!workspace()->activeClient()); + ShellClient *c = clientAddedSpy.first().first().value(); + QVERIFY(c->isInternal()); + QCOMPARE(c->geometry(), QRect(0, 0, 100, 100)); + + QSignalSpy enterSpy(&win, &HelperWindow::entered); + QVERIFY(enterSpy.isValid()); + QSignalSpy leaveSpy(&win, &HelperWindow::left); + QVERIFY(leaveSpy.isValid()); + QSignalSpy moveSpy(&win, &HelperWindow::mouseMoved); + QVERIFY(moveSpy.isValid()); + + quint32 timestamp = 1; + waylandServer()->backend()->pointerMotion(QPoint(50, 50), timestamp++); + QTRY_COMPARE(enterSpy.count(), 1); + + waylandServer()->backend()->pointerMotion(QPoint(60, 50), timestamp++); + QTRY_COMPARE(moveSpy.count(), 1); + QCOMPARE(moveSpy.first().first().toPoint(), QPoint(60, 50)); + + waylandServer()->backend()->pointerMotion(QPoint(101, 50), timestamp++); + QTRY_COMPARE(leaveSpy.count(), 1); +} + +void InternalWindowTest::testPointerPressRelease() +{ + QSignalSpy clientAddedSpy(waylandServer(), &WaylandServer::shellClientAdded); + QVERIFY(clientAddedSpy.isValid()); + HelperWindow win; + win.setGeometry(0, 0, 100, 100); + win.show(); + QSignalSpy pressSpy(&win, &HelperWindow::mousePressed); + QVERIFY(pressSpy.isValid()); + QSignalSpy releaseSpy(&win, &HelperWindow::mouseReleased); + QVERIFY(releaseSpy.isValid()); + + QVERIFY(clientAddedSpy.wait()); + QCOMPARE(clientAddedSpy.count(), 1); + + quint32 timestamp = 1; + waylandServer()->backend()->pointerMotion(QPoint(50, 50), timestamp++); + + waylandServer()->backend()->pointerButtonPressed(BTN_LEFT, timestamp++); + QTRY_COMPARE(pressSpy.count(), 1); + waylandServer()->backend()->pointerButtonReleased(BTN_LEFT, timestamp++); + QTRY_COMPARE(releaseSpy.count(), 1); +} + +void InternalWindowTest::testPointerAxis() +{ + QSignalSpy clientAddedSpy(waylandServer(), &WaylandServer::shellClientAdded); + QVERIFY(clientAddedSpy.isValid()); + HelperWindow win; + win.setGeometry(0, 0, 100, 100); + win.show(); + QSignalSpy wheelSpy(&win, &HelperWindow::wheel); + QVERIFY(wheelSpy.isValid()); + QVERIFY(clientAddedSpy.wait()); + QCOMPARE(clientAddedSpy.count(), 1); + + quint32 timestamp = 1; + waylandServer()->backend()->pointerMotion(QPoint(50, 50), timestamp++); + + waylandServer()->backend()->pointerAxisVertical(5.0, timestamp++); + QTRY_COMPARE(wheelSpy.count(), 1); + waylandServer()->backend()->pointerAxisHorizontal(5.0, timestamp++); + QTRY_COMPARE(wheelSpy.count(), 2); +} + +} + +WAYLANTEST_MAIN(KWin::InternalWindowTest) +#include "internal_window.moc"