diff --git a/autotests/integration/CMakeLists.txt b/autotests/integration/CMakeLists.txt index 7d53e05f25..cb7b9eb4c1 100644 --- a/autotests/integration/CMakeLists.txt +++ b/autotests/integration/CMakeLists.txt @@ -47,3 +47,5 @@ if (XCB_ICCCM_FOUND) integrationTest(NAME testPlasmaWindow SRCS plasmawindow_test.cpp LIBS XCB::ICCCM) integrationTest(NAME testScreenEdgeClientShow SRCS screenedge_client_show_test.cpp LIBS XCB::ICCCM) endif() + +add_subdirectory(scripting) diff --git a/autotests/integration/scripting/CMakeLists.txt b/autotests/integration/scripting/CMakeLists.txt new file mode 100644 index 0000000000..854f7ae9f9 --- /dev/null +++ b/autotests/integration/scripting/CMakeLists.txt @@ -0,0 +1 @@ +integrationTest(NAME testScriptingScreenEdge SRCS screenedge_test.cpp) diff --git a/autotests/integration/scripting/screenedge_test.cpp b/autotests/integration/scripting/screenedge_test.cpp new file mode 100644 index 0000000000..32a8be40a2 --- /dev/null +++ b/autotests/integration/scripting/screenedge_test.cpp @@ -0,0 +1,146 @@ +/******************************************************************** +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 "cursor.h" +#include "effectloader.h" +#include "platform.h" +#include "wayland_server.h" +#include "workspace.h" +#include "scripting/scripting.h" +#include "effect_builtins.h" + +#include + +Q_DECLARE_METATYPE(KWin::ElectricBorder) + +using namespace KWin; + +static const QString s_socketName = QStringLiteral("wayland_test_kwin_scripting_screenedge-0"); + +class ScreenEdgeTest : public QObject +{ + Q_OBJECT +private Q_SLOTS: + void initTestCase(); + void init(); + void cleanup(); + + void testEdge_data(); + void testEdge(); +}; + +void ScreenEdgeTest::initTestCase() +{ + QSignalSpy workspaceCreatedSpy(kwinApp(), &Application::workspaceCreated); + QVERIFY(workspaceCreatedSpy.isValid()); + kwinApp()->platform()->setInitialWindowSize(QSize(1280, 1024)); + QVERIFY(waylandServer()->init(s_socketName.toLocal8Bit())); + + // empty config to have defaults + auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig); + + // disable all effects to prevent them grabbing edges + KConfigGroup plugins(config, QStringLiteral("Plugins")); + ScriptedEffectLoader loader; + const auto builtinNames = BuiltInEffects::availableEffectNames() << loader.listOfKnownEffects(); + for (QString name : builtinNames) { + plugins.writeEntry(name + QStringLiteral("Enabled"), false); + } + + // disable electric border pushaback + config->group("Windows").writeEntry("ElectricBorderPushbackPixels", 0); + + config->sync(); + kwinApp()->setConfig(config); + + kwinApp()->start(); + QVERIFY(workspaceCreatedSpy.wait()); + QVERIFY(Scripting::self()); +} + +void ScreenEdgeTest::init() +{ + KWin::Cursor::setPos(640, 512); + if (workspace()->showingDesktop()) { + workspace()->slotToggleShowDesktop(); + } + QVERIFY(!workspace()->showingDesktop()); +} + +void ScreenEdgeTest::cleanup() +{ + // try to unload the script + const QString scriptToLoad = QFINDTESTDATA("./scripts/screenedge.js"); + if (!scriptToLoad.isEmpty()) { + if (Scripting::self()->isScriptLoaded(scriptToLoad)) { + QVERIFY(Scripting::self()->unloadScript(scriptToLoad)); + QTRY_VERIFY(!Scripting::self()->isScriptLoaded(scriptToLoad)); + } + } +} + +void ScreenEdgeTest::testEdge_data() +{ + QTest::addColumn("edge"); + QTest::addColumn("triggerPos"); + + QTest::newRow("Top") << KWin::ElectricTop << QPoint(512, 0); + QTest::newRow("TopRight") << KWin::ElectricTopRight << QPoint(1279, 0); + QTest::newRow("Right") << KWin::ElectricRight << QPoint(1279, 512); + QTest::newRow("BottomRight") << KWin::ElectricBottomRight << QPoint(1279, 1023); + QTest::newRow("Bottom") << KWin::ElectricBottom << QPoint(512, 1023); + QTest::newRow("BottomLeft") << KWin::ElectricBottomLeft << QPoint(0, 1023); + QTest::newRow("Left") << KWin::ElectricLeft << QPoint(0, 512); + QTest::newRow("TopLeft") << KWin::ElectricTopLeft << QPoint(0, 0); +} + +void ScreenEdgeTest::testEdge() +{ + const QString scriptToLoad = QFINDTESTDATA("./scripts/screenedge.js"); + QVERIFY(!scriptToLoad.isEmpty()); + + // mock the config + auto config = kwinApp()->config(); + QFETCH(KWin::ElectricBorder, edge); + config->group(QLatin1String("Script-") + scriptToLoad).writeEntry("Edge", int(edge)); + config->sync(); + + QVERIFY(!Scripting::self()->isScriptLoaded(scriptToLoad)); + const int id = Scripting::self()->loadScript(scriptToLoad); + QVERIFY(id != -1); + QVERIFY(Scripting::self()->isScriptLoaded(scriptToLoad)); + // TODO: a way to run the script without having to call the global start + Scripting::self()->start(); + // give it some time to start - a callback would be nice + QTest::qWait(100); + + // triggering the edge will result in show desktop being triggered + QSignalSpy showDesktopSpy(workspace(), &Workspace::showingDesktopChanged); + QVERIFY(showDesktopSpy.isValid()); + + // trigger the edge + QFETCH(QPoint, triggerPos); + KWin::Cursor::setPos(triggerPos); + QCOMPARE(showDesktopSpy.count(), 1); + QVERIFY(workspace()->showingDesktop()); +} + +WAYLANDTEST_MAIN(ScreenEdgeTest) +#include "screenedge_test.moc" diff --git a/autotests/integration/scripting/scripts/screenedge.js b/autotests/integration/scripting/scripts/screenedge.js new file mode 100644 index 0000000000..4d02e83b35 --- /dev/null +++ b/autotests/integration/scripting/scripts/screenedge.js @@ -0,0 +1 @@ +registerScreenEdge(readConfig("Edge", 1), function() { workspace.slotToggleShowDesktop(); }); diff --git a/scripting/scripting.h b/scripting/scripting.h index fdc3ebe795..48a3b7132b 100644 --- a/scripting/scripting.h +++ b/scripting/scripting.h @@ -321,7 +321,7 @@ private: /** * The heart of KWin::Scripting. Infinite power lies beyond */ -class Scripting : public QObject +class KWIN_EXPORT Scripting : public QObject { Q_OBJECT Q_CLASSINFO("D-Bus Interface", "org.kde.kwin.Scripting")