Add method unregisterScreenEdge to scripting

Test Plan: Used in a script. Works.

Reviewers: #kwin, graesslin

Reviewed By: #kwin, graesslin

Subscribers: graesslin, kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D2261
icc-effect-5.14.5
David Edmundson 2016-10-07 13:29:29 +01:00
parent b1e76ed8c4
commit b32cdc5653
5 changed files with 134 additions and 6 deletions

View File

@ -25,6 +25,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "workspace.h"
#include "scripting/scripting.h"
#include "effect_builtins.h"
#include "workspace.h"
#define private public
#include "screenedge.h"
#undef private
#include <KConfigGroup>
@ -44,6 +49,10 @@ private Q_SLOTS:
void testEdge_data();
void testEdge();
void testEdgeUnregister();
private:
void triggerConfigReload();
};
void ScreenEdgeTest::initTestCase()
@ -64,7 +73,7 @@ void ScreenEdgeTest::initTestCase()
plugins.writeEntry(name + QStringLiteral("Enabled"), false);
}
// disable electric border pushaback
// disable electric border pushback
config->group("Windows").writeEntry("ElectricBorderPushbackPixels", 0);
config->sync();
@ -73,6 +82,9 @@ void ScreenEdgeTest::initTestCase()
kwinApp()->start();
QVERIFY(workspaceCreatedSpy.wait());
QVERIFY(Scripting::self());
ScreenEdges::self()->setTimeThreshold(0);
ScreenEdges::self()->setReActivationThreshold(0);
}
void ScreenEdgeTest::init()
@ -87,11 +99,13 @@ void ScreenEdgeTest::init()
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));
const QStringList scripts = {QFINDTESTDATA("./scripts/screenedge.js"), QFINDTESTDATA("./scripts/screenedgeunregister.js")};
for (const QString &script: scripts) {
if (!script.isEmpty()) {
if (Scripting::self()->isScriptLoaded(script)) {
QVERIFY(Scripting::self()->unloadScript(script));
QTRY_VERIFY(!Scripting::self()->isScriptLoaded(script));
}
}
}
}
@ -109,6 +123,9 @@ void ScreenEdgeTest::testEdge_data()
QTest::newRow("BottomLeft") << KWin::ElectricBottomLeft << QPoint(0, 1023);
QTest::newRow("Left") << KWin::ElectricLeft << QPoint(0, 512);
QTest::newRow("TopLeft") << KWin::ElectricTopLeft << QPoint(0, 0);
//repeat a row to show previously unloading and re-registering works
QTest::newRow("Top") << KWin::ElectricTop << QPoint(512, 0);
}
void ScreenEdgeTest::testEdge()
@ -145,5 +162,56 @@ void ScreenEdgeTest::testEdge()
QVERIFY(workspace()->showingDesktop());
}
void ScreenEdgeTest::triggerConfigReload() {
workspace()->slotReconfigure();
}
void ScreenEdgeTest::testEdgeUnregister()
{
const QString scriptToLoad = QFINDTESTDATA("./scripts/screenedgeunregister.js");
QVERIFY(!scriptToLoad.isEmpty());
Scripting::self()->loadScript(scriptToLoad);
auto s = Scripting::self()->findScript(scriptToLoad);
auto configGroup = s->config();
configGroup.writeEntry("Edge", int(KWin::ElectricLeft));
configGroup.sync();
const QPoint triggerPos = QPoint(0, 512);
QSignalSpy runningChangedSpy(s, &AbstractScript::runningChanged);
s->run();
QVERIFY(runningChangedSpy.wait());
QSignalSpy showDesktopSpy(workspace(), &Workspace::showingDesktopChanged);
QVERIFY(showDesktopSpy.isValid());
//trigger the edge
KWin::Cursor::setPos(triggerPos);
QCOMPARE(showDesktopSpy.count(), 1);
//reset
KWin::Cursor::setPos(500,500);
workspace()->slotToggleShowDesktop();
showDesktopSpy.clear();
//trigger again, to show that retriggering works
KWin::Cursor::setPos(triggerPos);
QCOMPARE(showDesktopSpy.count(), 1);
//reset
KWin::Cursor::setPos(500,500);
workspace()->slotToggleShowDesktop();
showDesktopSpy.clear();
//make the script unregister the edge
configGroup.writeEntry("mode", "unregister");
triggerConfigReload();
KWin::Cursor::setPos(triggerPos);
QCOMPARE(showDesktopSpy.count(), 0); //not triggered
//force the script to unregister a non-registered edge to prove it doesn't explode
triggerConfigReload();
}
WAYLANDTEST_MAIN(ScreenEdgeTest)
#include "screenedge_test.moc"

View File

@ -0,0 +1,12 @@
function init() {
var edge = readConfig("Edge", 1);
if (readConfig("mode", "") == "unregister") {
unregisterScreenEdge(edge);
} else {
registerScreenEdge(edge, function() { workspace.slotToggleShowDesktop(); });
}
}
options.configChanged.connect(init);
init();

View File

@ -57,6 +57,14 @@
<read></read>
<detaileddescription>Registers the callback for the screen edge. When the mouse gets pushed against the given edge the callback will be invoked.</detaileddescription>
</memberdef>
<memberdef kind="function">
<type>Q_SCRIPTABLE bool</type>
<definition>bool KWin::Scripting::unregisterScreenEdge</definition>
<argsstring>(ElectricBorder border)</argsstring>
<name>unregisterScreenEdge</name>
<read></read>
<detaileddescription>Unregisters the callback for the screen edge. This will disconnect all callbacks from this script to that edge.</detaileddescription>
</memberdef>
<memberdef kind="function">
<type>Q_SCRIPTABLE bool</type>
<definition>bool KWin::Scripting::registerShortcut</definition>

View File

@ -154,6 +154,12 @@ QScriptValue kwinRegisterScreenEdge(QScriptContext *context, QScriptEngine *engi
return KWin::registerScreenEdge<KWin::AbstractScript*>(context, engine);
}
QScriptValue kwinUnregisterScreenEdge(QScriptContext *context, QScriptEngine *engine)
{
return KWin::unregisterScreenEdge<KWin::AbstractScript*>(context, engine);
}
QScriptValue kwinRegisterUserActionsMenu(QScriptContext *context, QScriptEngine *engine)
{
return KWin::registerUserActionsMenu<KWin::AbstractScript*>(context, engine);
@ -277,6 +283,8 @@ void KWin::Script::installScriptFunctions(QScriptEngine* engine)
registerGlobalShortcutFunction(this, engine, kwinScriptGlobalShortcut);
// add screen edge
registerScreenEdgeFunction(this, engine, kwinRegisterScreenEdge);
unregisterScreenEdgeFunction(this, engine, kwinUnregisterScreenEdge);
// add user actions menu register function
regesterUserActionsMenuFunction(this, engine, kwinRegisterUserActionsMenu);
// add assertions

View File

@ -170,6 +170,31 @@ QScriptValue registerScreenEdge(QScriptContext *context, QScriptEngine *engine)
return engine->newVariant(true);
}
template<class T>
QScriptValue unregisterScreenEdge(QScriptContext *context, QScriptEngine *engine)
{
T script = qobject_cast<T>(context->callee().data().toQObject());
if (!script) {
return engine->undefinedValue();
}
if (!validateParameters(context, 1, 1)) {
return engine->undefinedValue();
}
if (!validateArgumentType<int>(context)) {
return engine->undefinedValue();
}
const int edge = context->argument(0).toVariant().toInt();
QHash<int, QList<QScriptValue> >::iterator it = script->screenEdgeCallbacks().find(edge);
if (it == script->screenEdgeCallbacks().end()) {
//not previously registered
return engine->newVariant(false);
}
ScreenEdges::self()->unreserve(static_cast<KWin::ElectricBorder>(edge), script);
script->screenEdgeCallbacks().erase(it);
return engine->newVariant(true);
}
template<class T>
QScriptValue registerUserActionsMenu(QScriptContext *context, QScriptEngine *engine)
{
@ -271,6 +296,13 @@ inline void registerScreenEdgeFunction(QObject *parent, QScriptEngine *engine, Q
engine->globalObject().setProperty(QStringLiteral("registerScreenEdge"), shortcutFunc);
}
inline void unregisterScreenEdgeFunction(QObject *parent, QScriptEngine *engine, QScriptEngine::FunctionSignature function)
{
QScriptValue shortcutFunc = engine->newFunction(function);
shortcutFunc.setData(engine->newQObject(parent));
engine->globalObject().setProperty(QStringLiteral("unregisterScreenEdge"), shortcutFunc);
}
inline void regesterUserActionsMenuFunction(QObject *parent, QScriptEngine *engine, QScriptEngine::FunctionSignature function)
{
QScriptValue shortcutFunc = engine->newFunction(function);