Global Shortcut support for KWin scripts and scripted Effects

A global method "registerShortcut" is exported to the scripts which
can be used to register a callback to be called when the global
shortcut is triggered.

The shared code between Scripts and Effects is moved into template
functions defined in a new file scriptingutils.h.

REVIEW: 104400
icc-effect-5.14.5
Martin Gräßlin 2012-03-25 09:59:01 +02:00
parent 7c117276b5
commit 42dfdb63b0
5 changed files with 128 additions and 0 deletions

View File

@ -20,6 +20,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "scriptedeffect.h"
#include "meta.h"
#include "scriptingutils.h"
// KDE
#include <KDE/KConfigGroup>
#include <KDE/KDebug>
@ -77,6 +78,11 @@ QScriptValue kwinEffectDisplayHeight(QScriptContext *context, QScriptEngine *eng
return Effect::displayHeight();
}
QScriptValue kwinScriptGlobalShortcut(QScriptContext *context, QScriptEngine *engine)
{
return globalShortcut<KWin::ScriptedEffect*>(context, engine);
}
QScriptValue effectWindowToScriptValue(QScriptEngine *eng, const KEffectWindowRef &window)
{
return eng->newQObject(window, QScriptEngine::QtOwnership,
@ -168,6 +174,8 @@ bool ScriptedEffect::init(const QString &effectName, const QString &pathToScript
m_engine->globalObject().setProperty("displayWidth", displayWidthFunc);
QScriptValue displayHeightFunc = m_engine->newFunction(kwinEffectDisplayHeight);
m_engine->globalObject().setProperty("displayHeight", displayHeightFunc);
// add global Shortcut
registerGlobalShortcutFunction(this, m_engine, kwinScriptGlobalShortcut);
QScriptValue ret = m_engine->evaluate(scriptFile.readAll());
@ -238,6 +246,17 @@ void ScriptedEffect::reconfigure(ReconfigureFlags flags)
emit configChanged();
}
void ScriptedEffect::registerShortcut(QAction *a, QScriptValue callback)
{
m_shortcutCallbacks.insert(a, callback);
connect(a, SIGNAL(triggered(bool)), SLOT(globalShortcutTriggered()));
}
void ScriptedEffect::globalShortcutTriggered()
{
callGlobalShortcutCallback<KWin::ScriptedEffect*>(this, sender());
}
QVariant ScriptedEffect::readConfig(const QString &key, const QVariant defaultValue)
{
KConfigGroup cg = effects->effectConfig(m_effectName);

View File

@ -117,6 +117,10 @@ public:
* @returns The config value if present
**/
Q_SCRIPTABLE QVariant readConfig(const QString &key, const QVariant defaultValue = QVariant());
void registerShortcut(QAction *a, QScriptValue callback);
const QHash<QAction*, QScriptValue> &shortcutCallbacks() const {
return m_shortcutCallbacks;
}
public Q_SLOTS:
void animate(KWin::EffectWindow *w, Attribute a, int ms, KWin::FPx2 to, KWin::FPx2 from = KWin::FPx2(), KWin::AnimationData *data = NULL, QEasingCurve curve = QEasingCurve(), int delay = 0);
@ -129,12 +133,14 @@ Q_SIGNALS:
private Q_SLOTS:
void signalHandlerException(const QScriptValue &value);
void globalShortcutTriggered();
private:
ScriptedEffect();
bool init(const QString &effectName, const QString &pathToScript);
QScriptEngine *m_engine;
QString m_effectName;
QString m_scriptFile;
QHash<QAction*, QScriptValue> m_shortcutCallbacks;
};
}

View File

@ -22,6 +22,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "scripting.h"
// own
#include "meta.h"
#include "scriptingutils.h"
#include "workspace_wrapper.h"
#include "../client.h"
#include "../thumbnailitem.h"
@ -80,6 +81,11 @@ QScriptValue kwinScriptReadConfig(QScriptContext *context, QScriptEngine *engine
return engine->newVariant(script->config().readEntry(key, defaultValue));
}
QScriptValue kwinScriptGlobalShortcut(QScriptContext *context, QScriptEngine *engine)
{
return KWin::globalShortcut<KWin::AbstractScript*>(context, engine);
}
KWin::AbstractScript::AbstractScript(int id, QString scriptName, QString pluginName, QObject *parent)
: QObject(parent)
, m_scriptId(id)
@ -113,6 +119,17 @@ void KWin::AbstractScript::printMessage(const QString &message)
emit print(message);
}
void KWin::AbstractScript::registerShortcut(QAction *a, QScriptValue callback)
{
m_shortcutCallbacks.insert(a, callback);
connect(a, SIGNAL(triggered(bool)), SLOT(globalShortcutTriggered()));
}
void KWin::AbstractScript::globalShortcutTriggered()
{
callGlobalShortcutCallback<KWin::AbstractScript*>(this, sender());
}
void KWin::AbstractScript::installScriptFunctions(QScriptEngine* engine)
{
// add our print
@ -123,6 +140,8 @@ void KWin::AbstractScript::installScriptFunctions(QScriptEngine* engine)
QScriptValue configFunc = engine->newFunction(kwinScriptReadConfig);
configFunc.setData(engine->newQObject(this));
engine->globalObject().setProperty("readConfig", configFunc);
// add global Shortcut
registerGlobalShortcutFunction(this, engine, kwinScriptGlobalShortcut);
}
KWin::Script::Script(int id, QString scriptName, QString pluginName, QObject* parent)

View File

@ -23,8 +23,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define KWIN_SCRIPTING_H
#include <QtCore/QFile>
#include <QtCore/QHash>
#include <QtCore/QStringList>
class QAction;
class QDeclarativeView;
class QScriptEngine;
class QScriptValue;
@ -48,13 +50,20 @@ public:
}
void printMessage(const QString &message);
void registerShortcut(QAction *a, QScriptValue callback);
KConfigGroup config() const;
const QHash<QAction*, QScriptValue> &shortcutCallbacks() const {
return m_shortcutCallbacks;
}
public Q_SLOTS:
Q_SCRIPTABLE void stop();
Q_SCRIPTABLE virtual void run() = 0;
private Q_SLOTS:
void globalShortcutTriggered();
Q_SIGNALS:
Q_SCRIPTABLE void print(const QString &text);
@ -84,6 +93,7 @@ private:
QString m_pluginName;
bool m_running;
WorkspaceWrapper *m_workspace;
QHash<QAction*, QScriptValue> m_shortcutCallbacks;
};
class Script : public AbstractScript

View File

@ -0,0 +1,74 @@
/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2012 Martin Gräßlin <mgraesslin@kde.org>
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 <http://www.gnu.org/licenses/>.
*********************************************************************/
#ifndef KWIN_SCRIPTINGUTILS_H
#define KWIN_SCRIPTINGUTILS_H
#include <KDE/KAction>
#include <KDE/KActionCollection>
#include <KDE/KDebug>
#include <QtScript/QScriptEngine>
namespace KWin
{
template<class T>
QScriptValue globalShortcut(QScriptContext *context, QScriptEngine *engine)
{
T script = qobject_cast<T>(context->callee().data().toQObject());
if (!script) {
return engine->undefinedValue();
}
if (context->argumentCount() != 4) {
kDebug(1212) << "Incorrect number of arguments! Expected: title, text, keySequence, callback";
return engine->undefinedValue();
}
KActionCollection* actionCollection = new KActionCollection(script);
KAction* a = (KAction*)actionCollection->addAction(context->argument(0).toString());
a->setText(context->argument(1).toString());
a->setGlobalShortcut(KShortcut(context->argument(2).toString()));
script->registerShortcut(a, context->argument(3));
return engine->newVariant(true);
};
template<class T>
void callGlobalShortcutCallback(T script, QObject *sender)
{
QAction *a = qobject_cast<QAction*>(sender);
if (!a) {
return;
}
QHash<QAction*, QScriptValue>::const_iterator it = script->shortcutCallbacks().find(a);
if (it == script->shortcutCallbacks().end()) {
return;
}
QScriptValue value(it.value());
value.call();
};
inline void registerGlobalShortcutFunction(QObject *parent, QScriptEngine *engine, QScriptEngine::FunctionSignature function)
{
QScriptValue shortcutFunc = engine->newFunction(function);
shortcutFunc.setData(engine->newQObject(parent));
engine->globalObject().setProperty("registerShortcut", shortcutFunc);
};
} // namespace KWin
#endif // KWIN_SCRIPTINGUTILS_H