From kde-commits Tue Jul 31 21:37:18 2018 From: David Edmundson Date: Tue, 31 Jul 2018 21:37:18 +0000 To: kde-commits Subject: [kwin/scripting2] /: scripting++ Message-Id: X-MARC-Message: https://marc.info/?l=kde-commits&m=153307305210826 Git commit c3f85429395610e1c6c636f82adfc0168b33524d by David Edmundson. Committed on 31/07/2018 at 20:22. Pushed by davidedmundson into branch 'scripting2'. scripting++ M +7 -7 autotests/integration/effects/scripted_effects_test.cpp M +1 -0 libkwineffects/kwineffects.cpp M +2 -0 libkwineffects/kwineffects.h M +79 -74 scripting/scriptedeffect.cpp M +14 -9 scripting/scriptedeffect.h https://commits.kde.org/kwin/c3f85429395610e1c6c636f82adfc0168b33524d diff --git a/autotests/integration/effects/scripted_effects_test.cpp b/auto= tests/integration/effects/scripted_effects_test.cpp index 0276ec965..903547c65 100644 --- a/autotests/integration/effects/scripted_effects_test.cpp +++ b/autotests/integration/effects/scripted_effects_test.cpp @@ -35,7 +35,7 @@ along with this program. If not, see . #include "workspace.h" = #include -#include +#include = #include #include @@ -75,6 +75,7 @@ class ScriptedEffectWithDebugSpy : public KWin::ScriptedE= ffect public: bool load(const QString &name); using AnimationEffect::state; + Q_INVOKABLE void sendTestResponse(const QString &out); signals: void testOutput(const QString &data); }; @@ -95,7 +96,6 @@ class SendTestResponseContext : public QObject Q_OBJECT public: SendTestResponseContext(ScriptedEffectWithDebugSpy *scriptedEffect); - Q_INVOKABLE void sendTestResponse(const QString &out); private: ScriptedEffectWithDebugSpy *m_scriptedEffect; }; @@ -103,20 +103,20 @@ private: >>>>>>> 87ad4e45f... port to QJSEngine = SendTestResponseContext::SendTestResponseContext(ScriptedEffectWithDebugSp= y *scriptedEffect): - QObject(nullptr), + QObject(scriptedEffect), m_scriptedEffect(scriptedEffect) { } = -void SendTestResponseContext::sendTestResponse(const QString &out) +void ScriptedEffectWithDebugSpy::sendTestResponse(const QString &out) { - emit m_scriptedEffect->testOutput(out); + emit testOutput(out); } = bool ScriptedEffectWithDebugSpy::load(const QString &name) { - auto selfContext =3D engine()->newQObject(new SendTestResponseContext(= this)); //JS ownership - + auto selfContext =3D engine()->newQObject(this); + QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership); const QString path =3D QFINDTESTDATA("./scripts/" + name + ".js"); engine()->globalObject().setProperty("sendTestResponse", selfContext.p= roperty("sendTestResponse")); if (!init(name, path)) { diff --git a/libkwineffects/kwineffects.cpp b/libkwineffects/kwineffects.cpp index 86e13ffb6..3454ddd34 100644 --- a/libkwineffects/kwineffects.cpp +++ b/libkwineffects/kwineffects.cpp @@ -743,6 +743,7 @@ EffectsHandler::EffectsHandler(CompositingType type) if (compositing_type =3D=3D NoCompositing) return; KWin::effects =3D this; + connect(this, QOverload::of(&EffectsHandler::desktopChanged)= , this, &EffectsHandler::desktopChangedCompat); } = EffectsHandler::~EffectsHandler() diff --git a/libkwineffects/kwineffects.h b/libkwineffects/kwineffects.h index 16bf5936a..c421173fa 100644 --- a/libkwineffects/kwineffects.h +++ b/libkwineffects/kwineffects.h @@ -1336,6 +1336,8 @@ Q_SIGNALS: * @deprecated */ void desktopChanged(int oldDesktop, int newDesktop); + ///@internal + void desktopChangedCompat(int oldDesktop, int newDesktop); /** * Signal emitted when a window moved to another desktop * NOTICE that this does NOT imply that the desktop has changed diff --git a/scripting/scriptedeffect.cpp b/scripting/scriptedeffect.cpp index e78f6315e..0e7967a1c 100644 --- a/scripting/scriptedeffect.cpp +++ b/scripting/scriptedeffect.cpp @@ -31,7 +31,7 @@ along with this program. If not, see . #include // Qt #include -#include +#include #include #include = @@ -59,55 +59,6 @@ QJSValue kwinEffectScriptPrint(QScriptContext *context, = QJSEngine *engine) return QJSValue(); } = -QJSValue kwinEffectScriptAnimationTime(QScriptContext *context, QJSEngine = *engine) -{ - if (context->argumentCount() !=3D 1) { - return QJSValue(); - } - if (!context->argument(0).isNumber()) { - return QJSValue(); - } - return Effect::animationTime(context->argument(0).toInteger()); -} - -QJSValue kwinEffectDisplayWidth(QScriptContext *context, QJSEngine *engine) -{ - Q_UNUSED(context) - Q_UNUSED(engine) - return screens()->displaySize().width(); -} - -QJSValue kwinEffectDisplayHeight(QScriptContext *context, QJSEngine *engin= e) -{ - Q_UNUSED(context) - Q_UNUSED(engine) - return screens()->displaySize().height(); -} - -QJSValue kwinScriptGlobalShortcut(QScriptContext *context, QJSEngine *engi= ne) -{ - return QJSValue(); -// return globalShortcut(context, engine); -} - -QJSValue kwinScriptScreenEdge(QScriptContext *context, QJSEngine *engine) -{ - return QJSValue(); -// return registerScreenEdge(context, engine); -} - -QJSValue kwinRegisterTouchScreenEdge(QScriptContext *context, QJSEngine *e= ngine) -{ - return QJSValue(); -// return registerTouchScreenEdge(context, engin= e); -} - -QJSValue kwinUnregisterTouchScreenEdge(QScriptContext *context, QJSEngine = *engine) -{ - return QJSValue(); -// return unregisterTouchScreenEdge(context, eng= ine); -} - struct AnimationSettings { enum { Type =3D 1<<0, Curve =3D 1<<1, Delay =3D 1<<2, Duration =3D 1<<= 3 }; AnimationEffect::Attribute type; @@ -514,14 +465,44 @@ bool ScriptedEffect::init(const QString &effectName, = const QString &pathToScript m_config->load(); } = -// QJSValue effectsObject =3D m_engine->newQObject(effects); -// m_engine->globalObject().setProperty(QStringLiteral("effects"), effe= ctsObject); + QJSValue effectsObject =3D m_engine->newQObject(effects); + QQmlEngine::setObjectOwnership(effects, QQmlEngine::CppOwnership); + m_engine->globalObject().setProperty(QStringLiteral("effects"), effect= sObject); + + //desktopChanged is overloaded, which is problematic + //old code exposed the signal also with parameters. QJSEngine does not= so we have to shim it + effectsObject.setProperty("desktopChanged(int,int)", effectsObject.pro= perty("desktopChangedCompat")); + effectsObject.setProperty("desktopChanged", effectsObject.property("de= sktopChangedCompat")); + + QJSValue selfWrapper =3D m_engine->newQObject(this); + QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership); + m_engine->globalObject().setProperty(QStringLiteral("Effect"), m_engin= e->newQMetaObject(&ScriptedEffect::staticMetaObject)); #ifndef KWIN_UNIT_TEST m_engine->globalObject().setProperty(QStringLiteral("KWin"), m_engine-= >newQMetaObject(&QtScriptWorkspaceWrapper::staticMetaObject)); #endif m_engine->globalObject().setProperty(QStringLiteral("QEasingCurve"), m= _engine->newQMetaObject(&QEasingCurve::staticMetaObject)); -// m_engine->globalObject().setProperty(QStringLiteral("effect"), m_eng= ine->newQObject(this, QJSEngine::QtOwnership, QJSEngine::ExcludeDeleteLater= ), QJSValue::Undeletable); + + m_engine->globalObject().setProperty("effect", selfWrapper); + + //expose functions at the root level for compatibility + engine()->globalObject().setProperty("displayWidth", selfWrapper.prope= rty("displayWidth")); + engine()->globalObject().setProperty("displayHeight", selfWrapper.prop= erty("displayHeight")); + engine()->globalObject().setProperty("animationTime", selfWrapper.prop= erty("animationTime")); + + engine()->globalObject().setProperty("registerShortcut", selfWrapper.p= roperty("registerShortcut")); + engine()->globalObject().setProperty("registerScreenEdge", selfWrapper= .property("registerScreenEdge")); + engine()->globalObject().setProperty("unregisterScreenEdge", selfWrapp= er.property("unregisterScreenEdge")); + engine()->globalObject().setProperty("registerTouchScreenEdge", selfWr= apper.property("registerTouchScreenEdge")); + engine()->globalObject().setProperty("unregisterTouchScreenEdge", self= Wrapper.property("unregisterTouchScreenEdge")); +//TODO +// fpx2 +// print + // animate + friends + //screen edge + //touchscreen function + + // MetaScripting::registration(m_engine); // qScriptRegisterMetaType(m_engine, effectWindowToSc= riptValue, effectWindowFromScriptValue); // qScriptRegisterMetaType(m_engine, fpx2ToScriptValue, fpx= 2FromScriptValue); @@ -530,17 +511,8 @@ bool ScriptedEffect::init(const QString &effectName, c= onst QString &pathToScript // QJSValue printFunc =3D m_engine->newFunction(kwinEffectScriptPrint); // printFunc.setData(m_engine->newQObject(this)); // m_engine->globalObject().setProperty(QStringLiteral("print"), printF= unc); -// // add our animationTime -// QJSValue animationTimeFunc =3D m_engine->newFunction(kwinEffectScrip= tAnimationTime); -// animationTimeFunc.setData(m_engine->newQObject(this)); -// m_engine->globalObject().setProperty(QStringLiteral("animationTime")= , animationTimeFunc); -// // add displayWidth and displayHeight -// QJSValue displayWidthFunc =3D m_engine->newFunction(kwinEffectDispla= yWidth); -// m_engine->globalObject().setProperty(QStringLiteral("displayWidth"),= displayWidthFunc); -// QJSValue displayHeightFunc =3D m_engine->newFunction(kwinEffectDispl= ayHeight); -// m_engine->globalObject().setProperty(QStringLiteral("displayHeight")= , displayHeightFunc); + // // add global Shortcut -// registerGlobalShortcutFunction(this, m_engine, kwinScriptGlobalShort= cut); // registerScreenEdgeFunction(this, m_engine, kwinScriptScreenEdge); // registerTouchScreenEdgeFunction(this, m_engine, kwinRegisterTouchScr= eenEdge); // unregisterTouchScreenEdgeFunction(this, m_engine, kwinUnregisterTouc= hScreenEdge); @@ -566,8 +538,9 @@ bool ScriptedEffect::init(const QString &effectName, co= nst QString &pathToScript = QJSValue ret =3D m_engine->evaluate(QString::fromUtf8(scriptFile.readA= ll())); = -// qDebug() <<" HERE! " << ret.toString(); if (ret.isError()) { + qDebug() <<" HERE! " << ret.property("lineNumber").toInt() << ret.= toString(); + // signalHandlerException(ret); return false; } @@ -575,6 +548,21 @@ bool ScriptedEffect::init(const QString &effectName, c= onst QString &pathToScript return true; } = +int ScriptedEffect::displayHeight() const +{ + return screens()->displaySize().height(); +} + +int ScriptedEffect::animationTime(int defaultTime) const +{ + return Effect::animationTime(defaultTime); +} + +int ScriptedEffect::displayWidth() const +{ + return screens()->displaySize().width(); +} + void ScriptedEffect::animationEnded(KWin::EffectWindow *w, Attribute a, ui= nt meta) { AnimationEffect::animationEnded(w, a, meta); @@ -640,15 +628,30 @@ void ScriptedEffect::reconfigure(ReconfigureFlags fla= gs) emit configChanged(); } = -void ScriptedEffect::registerShortcut(QAction *a, QJSValue callback) +bool ScriptedEffect::registerShortcut(const QString &objectName, const QSt= ring &text, const QString &keySequence, const QJSValue &callback) { + QAction* a =3D new QAction(this); + a->setObjectName(objectName); + a->setText(text); + const QKeySequence shortcut =3D QKeySequence(keySequence); + KGlobalAccel::self()->setShortcut(a, QList() << shortcut= ); m_shortcutCallbacks.insert(a, callback); - connect(a, SIGNAL(triggered(bool)), SLOT(globalShortcutTriggered())); -} + input()->registerShortcut(shortcut, a); = -void ScriptedEffect::globalShortcutTriggered() -{ -// callGlobalShortcutCallback(this, sender()); + connect(a, &QAction::triggered, this, [this, a, callback]() { + QJSValue c(callback); + + auto it =3D m_shortcutCallbacks.constFind(a); + if (it =3D=3D m_shortcutCallbacks.constEnd()) { + return; + } +// QJSValue value(it.value()); + //DAVE - WTF is this for? why would a JS script need to know the a= ction? it can just use a different callback? +// arguments << m_engine->newQObject(a); +// auto c =3D const_cast(callback); // see docs in QJSVal= ue::call it's safe + c.call(QJSValueList()); + }); + return true; } = bool ScriptedEffect::borderActivated(ElectricBorder edge) @@ -665,7 +668,7 @@ QVariant ScriptedEffect::readConfig(const QString &key,= const QVariant defaultVa return m_config->property(key); } = -bool ScriptedEffect::registerTouchScreenCallback(int edge, QJSValue callba= ck) +bool ScriptedEffect::registerTouchScreenCallback(int edge, const QJSValue = &callback) { if (m_touchScreenEdgeCallbacks.constFind(edge) !=3D m_touchScreenEdgeC= allbacks.constEnd()) { return false; @@ -677,9 +680,9 @@ bool ScriptedEffect::registerTouchScreenCallback(int ed= ge, QJSValue callback) invoke.call(); } ); - ScreenEdges::self()->reserveTouch(KWin::ElectricBorder(edge), action); + const auto ret =3D ScreenEdges::self()->reserveTouch(KWin::ElectricBor= der(edge), action); m_touchScreenEdgeCallbacks.insert(edge, action); - return true; + return ret; } = bool ScriptedEffect::unregisterTouchScreenCallback(int edge) @@ -689,8 +692,10 @@ bool ScriptedEffect::unregisterTouchScreenCallback(int= edge) return false; } delete it.value(); + + //DAVE m_touchScreenEdgeCallbacks.erase(it); - return true; + return ret; } = QJSEngine *ScriptedEffect::engine() const diff --git a/scripting/scriptedeffect.h b/scripting/scriptedeffect.h index 3fbdec51e..87fab9429 100644 --- a/scripting/scriptedeffect.h +++ b/scripting/scriptedeffect.h @@ -83,23 +83,28 @@ public: * @returns The config value if present **/ Q_SCRIPTABLE QVariant readConfig(const QString &key, const QVariant de= faultValue =3D QVariant()); + Q_SCRIPTABLE bool registerShortcut(const QString &objectName, const QS= tring &text, const QString &keySequence, const QJSValue &callback); + + Q_SCRIPTABLE int displayWidth() const; + Q_SCRIPTABLE int displayHeight() const; + Q_SCRIPTABLE int animationTime(int defaultTime) const; + + Q_SCRIPTABLE void registerScreenEdge(int edge, const QJSValue &callbac= k); + Q_SCRIPTABLE void unregisterScreenEdge(int edge); + Q_SCRIPTABLE void registerTouchScreenEdge(int edge, const QJSValue &ca= llback); + Q_SCRIPTABLE void unregisterTouchScreenEdge(int edge); + + void registerShortcut(QAction *a, QJSValue callback); - const QHash &shortcutCallbacks() const { - return m_shortcutCallbacks; - } QHash > &screenEdgeCallbacks() { return m_screenEdgeCallbacks; } - - bool registerTouchScreenCallback(int edge, QJSValue callback); - bool unregisterTouchScreenCallback(int edge); - public Q_SLOTS: quint64 animate(KWin::EffectWindow *w, Attribute a, int ms, KWin::FPx2= to, KWin::FPx2 from =3D KWin::FPx2(), uint metaData =3D 0, QEasingCurve::T= ype curve =3D QEasingCurve::Linear, int delay =3D 0); quint64 set(KWin::EffectWindow *w, Attribute a, int ms, KWin::FPx2 to,= KWin::FPx2 from =3D KWin::FPx2(), uint metaData =3D 0, QEasingCurve::Type = curve =3D QEasingCurve::Linear, int delay =3D 0); bool retarget(quint64 animationId, KWin::FPx2 newTarget, int newRemain= ingTime =3D -1); bool cancel(quint64 animationId) { return AnimationEffect::cancel(anim= ationId); } - virtual bool borderActivated(ElectricBorder border); + bool borderActivated(ElectricBorder border) override; = Q_SIGNALS: /** @@ -120,7 +125,7 @@ private: QJSEngine *m_engine; QString m_effectName; QString m_scriptFile; - QHash m_shortcutCallbacks; + QHash m_shortcutCallbacks; //remove QHash > m_screenEdgeCallbacks; KConfigLoader *m_config; int m_chainPosition;