From 84b0578a717375f094d0d1f2d29a3dac5bb922e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Fl=C3=B6ser?= Date: Thu, 20 Jul 2017 20:49:42 +0200 Subject: [PATCH] [autotests] Add test cases for switchWindow A new test class for KWinBindings added which is intended to group the testing of the various slots set up in kwinbindings.cpp. As the scripts also delegate to the slots this is also tested. --- autotests/integration/CMakeLists.txt | 1 + autotests/integration/kwinbindings_test.cpp | 191 ++++++++++++++++++++ 2 files changed, 192 insertions(+) create mode 100644 autotests/integration/kwinbindings_test.cpp diff --git a/autotests/integration/CMakeLists.txt b/autotests/integration/CMakeLists.txt index cd61ed6921..3908e31757 100644 --- a/autotests/integration/CMakeLists.txt +++ b/autotests/integration/CMakeLists.txt @@ -46,6 +46,7 @@ integrationTest(NAME testKeyboardLayout SRCS keyboard_layout_test.cpp) integrationTest(NAME testKeymapCreationFailure SRCS keymap_creation_failure_test.cpp) integrationTest(NAME testShowingDesktop SRCS showing_desktop_test.cpp) integrationTest(NAME testDontCrashUseractionsMenu SRCS dont_crash_useractions_menu.cpp) +integrationTest(NAME testKWinBindings SRCS kwinbindings_test.cpp) if (XCB_ICCCM_FOUND) integrationTest(NAME testMoveResize SRCS move_resize_window_test.cpp LIBS XCB::ICCCM) diff --git a/autotests/integration/kwinbindings_test.cpp b/autotests/integration/kwinbindings_test.cpp new file mode 100644 index 0000000000..a867eac995 --- /dev/null +++ b/autotests/integration/kwinbindings_test.cpp @@ -0,0 +1,191 @@ +/******************************************************************** +KWin - the KDE window manager +This file is part of the KDE project. + +Copyright (C) 2017 Martin Flöser + +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 "cursor.h" +#include "input.h" +#include "platform.h" +#include "screens.h" +#include "shell_client.h" +#include "scripting/scripting.h" +#include "useractions.h" +#include "wayland_server.h" +#include "workspace.h" + +#include +#include + +#include +#include +#include + +using namespace KWin; +using namespace KWayland::Client; + +static const QString s_socketName = QStringLiteral("wayland_test_kwin_kwinbindings-0"); + +class KWinBindingsTest : public QObject +{ + Q_OBJECT +private Q_SLOTS: + void initTestCase(); + void init(); + void cleanup(); + + void testSwitchWindow(); + void testSwitchWindowScript(); +}; + + +void KWinBindingsTest::initTestCase() +{ + qRegisterMetaType(); + qRegisterMetaType(); + QSignalSpy workspaceCreatedSpy(kwinApp(), &Application::workspaceCreated); + QVERIFY(workspaceCreatedSpy.isValid()); + kwinApp()->platform()->setInitialWindowSize(QSize(1280, 1024)); + QVERIFY(waylandServer()->init(s_socketName.toLocal8Bit())); + + kwinApp()->setConfig(KSharedConfig::openConfig(QString(), KConfig::SimpleConfig)); + + kwinApp()->start(); + QVERIFY(workspaceCreatedSpy.wait()); + waylandServer()->initWorkspace(); +} + +void KWinBindingsTest::init() +{ + QVERIFY(Test::setupWaylandConnection()); + screens()->setCurrent(0); + KWin::Cursor::setPos(QPoint(640, 512)); +} + +void KWinBindingsTest::cleanup() +{ + Test::destroyWaylandConnection(); +} + +void KWinBindingsTest::testSwitchWindow() +{ + // first create windows + QScopedPointer surface1(Test::createSurface()); + QScopedPointer shellSurface1(Test::createShellSurface(surface1.data())); + auto c1 = Test::renderAndWaitForShown(surface1.data(), QSize(100, 50), Qt::blue); + QScopedPointer surface2(Test::createSurface()); + QScopedPointer shellSurface2(Test::createShellSurface(surface2.data())); + auto c2 = Test::renderAndWaitForShown(surface2.data(), QSize(100, 50), Qt::blue); + QScopedPointer surface3(Test::createSurface()); + QScopedPointer shellSurface3(Test::createShellSurface(surface3.data())); + auto c3 = Test::renderAndWaitForShown(surface3.data(), QSize(100, 50), Qt::blue); + QScopedPointer surface4(Test::createSurface()); + QScopedPointer shellSurface4(Test::createShellSurface(surface4.data())); + auto c4 = Test::renderAndWaitForShown(surface4.data(), QSize(100, 50), Qt::blue); + + QVERIFY(c4->isActive()); + QVERIFY(c4 != c3); + QVERIFY(c3 != c2); + QVERIFY(c2 != c1); + + // let's position all windows + c1->move(0, 0); + c2->move(200, 0); + c3->move(200, 200); + c4->move(0, 200); + + // now let's trigger the shortcuts + + // invoke global shortcut through dbus + auto invokeShortcut = [] (const QString &shortcut) { + auto msg = QDBusMessage::createMethodCall( + QStringLiteral("org.kde.kglobalaccel"), + QStringLiteral("/component/kwin"), + QStringLiteral("org.kde.kglobalaccel.Component"), + QStringLiteral("invokeShortcut")); + msg.setArguments(QList{shortcut}); + QDBusConnection::sessionBus().asyncCall(msg); + }; + invokeShortcut(QStringLiteral("Switch Window Up")); + QTRY_COMPARE(workspace()->activeClient(), c1); + invokeShortcut(QStringLiteral("Switch Window Right")); + QTRY_COMPARE(workspace()->activeClient(), c2); + invokeShortcut(QStringLiteral("Switch Window Down")); + QTRY_COMPARE(workspace()->activeClient(), c3); + invokeShortcut(QStringLiteral("Switch Window Left")); + QTRY_COMPARE(workspace()->activeClient(), c4); +} + +void KWinBindingsTest::testSwitchWindowScript() +{ + QVERIFY(Scripting::self()); + + // first create windows + QScopedPointer surface1(Test::createSurface()); + QScopedPointer shellSurface1(Test::createShellSurface(surface1.data())); + auto c1 = Test::renderAndWaitForShown(surface1.data(), QSize(100, 50), Qt::blue); + QScopedPointer surface2(Test::createSurface()); + QScopedPointer shellSurface2(Test::createShellSurface(surface2.data())); + auto c2 = Test::renderAndWaitForShown(surface2.data(), QSize(100, 50), Qt::blue); + QScopedPointer surface3(Test::createSurface()); + QScopedPointer shellSurface3(Test::createShellSurface(surface3.data())); + auto c3 = Test::renderAndWaitForShown(surface3.data(), QSize(100, 50), Qt::blue); + QScopedPointer surface4(Test::createSurface()); + QScopedPointer shellSurface4(Test::createShellSurface(surface4.data())); + auto c4 = Test::renderAndWaitForShown(surface4.data(), QSize(100, 50), Qt::blue); + + QVERIFY(c4->isActive()); + QVERIFY(c4 != c3); + QVERIFY(c3 != c2); + QVERIFY(c2 != c1); + + // let's position all windows + c1->move(0, 0); + c2->move(200, 0); + c3->move(200, 200); + c4->move(0, 200); + + auto runScript = [] (const QString &slot) { + QTemporaryFile tmpFile; + QVERIFY(tmpFile.open()); + QTextStream out(&tmpFile); + out << "workspace." << slot << "()"; + out.flush(); + + const int id = Scripting::self()->loadScript(tmpFile.fileName()); + QVERIFY(id != -1); + QVERIFY(Scripting::self()->isScriptLoaded(tmpFile.fileName())); + auto s = Scripting::self()->findScript(tmpFile.fileName()); + QVERIFY(s); + QSignalSpy runningChangedSpy(s, &AbstractScript::runningChanged); + QVERIFY(runningChangedSpy.isValid()); + s->run(); + QVERIFY(runningChangedSpy.wait()); + }; + + runScript(QStringLiteral("slotSwitchWindowUp")); + QTRY_COMPARE(workspace()->activeClient(), c1); + runScript(QStringLiteral("slotSwitchWindowRight")); + QTRY_COMPARE(workspace()->activeClient(), c2); + runScript(QStringLiteral("slotSwitchWindowDown")); + QTRY_COMPARE(workspace()->activeClient(), c3); + runScript(QStringLiteral("slotSwitchWindowLeft")); + QTRY_COMPARE(workspace()->activeClient(), c4); +} + +WAYLANDTEST_MAIN(KWinBindingsTest) +#include "kwinbindings_test.moc"