diff --git a/scripting/scriptedeffect.cpp b/scripting/scriptedeffect.cpp index 0aa9a8b968..193ed958dc 100644 --- a/scripting/scriptedeffect.cpp +++ b/scripting/scriptedeffect.cpp @@ -492,7 +492,7 @@ bool ScriptedEffect::init(const QString &effectName, const QString &pathToScript m_engine->globalObject().setProperty(QStringLiteral("effects"), effectsObject, QScriptValue::Undeletable); m_engine->globalObject().setProperty(QStringLiteral("Effect"), m_engine->newQMetaObject(&ScriptedEffect::staticMetaObject)); #ifndef KWIN_UNIT_TEST - m_engine->globalObject().setProperty(QStringLiteral("KWin"), m_engine->newQMetaObject(&WorkspaceWrapper::staticMetaObject)); + 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_engine->newQObject(this, QScriptEngine::QtOwnership, QScriptEngine::ExcludeDeleteLater), QScriptValue::Undeletable); diff --git a/scripting/scripting.cpp b/scripting/scripting.cpp index 3e3ab5691e..a1817868be 100644 --- a/scripting/scripting.cpp +++ b/scripting/scripting.cpp @@ -46,6 +46,7 @@ along with this program. If not, see . #include #include #include +#include #include #include #include @@ -293,7 +294,7 @@ void KWin::Script::installScriptFunctions(QScriptEngine* engine) QScriptValue assertNotNullFunc = engine->newFunction(kwinAssertNotNull); engine->globalObject().setProperty(QStringLiteral("assertNotNull"), assertNotNullFunc); // global properties - engine->globalObject().setProperty(QStringLiteral("KWin"), engine->newQMetaObject(&WorkspaceWrapper::staticMetaObject)); + engine->globalObject().setProperty(QStringLiteral("KWin"), engine->newQMetaObject(&QtScriptWorkspaceWrapper::staticMetaObject)); QScriptValue workspace = engine->newQObject(Scripting::self()->workspaceWrapper(), QScriptEngine::QtOwnership, QScriptEngine::ExcludeSuperClassContents | QScriptEngine::ExcludeDeleteLater); engine->globalObject().setProperty(QStringLiteral("workspace"), workspace, QScriptValue::Undeletable); @@ -527,7 +528,7 @@ void KWin::ScriptUnloaderAgent::scriptUnload(qint64 id) KWin::DeclarativeScript::DeclarativeScript(int id, QString scriptName, QString pluginName, QObject* parent) : AbstractScript(id, scriptName, pluginName, parent) - , m_context(new QQmlContext(Scripting::self()->qmlEngine(), this)) + , m_context(new QQmlContext(Scripting::self()->declarativeScriptSharedContext(), this)) , m_component(new QQmlComponent(Scripting::self()->qmlEngine(), this)) { m_context->setContextProperty(QStringLiteral("KWin"), new JSEngineGlobalMethodsWrapper(this)); @@ -622,7 +623,8 @@ KWin::Scripting::Scripting(QObject *parent) : QObject(parent) , m_scriptsLock(new QMutex(QMutex::Recursive)) , m_qmlEngine(new QQmlEngine(this)) - , m_workspaceWrapper(new WorkspaceWrapper(this)) + , m_declarativeScriptSharedContext(new QQmlContext(m_qmlEngine, this)) + , m_workspaceWrapper(new QtScriptWorkspaceWrapper(this)) { init(); QDBusConnection::sessionBus().registerObject(QStringLiteral("/Scripting"), this, QDBusConnection::ExportScriptableContents | QDBusConnection::ExportScriptableInvokables); @@ -647,6 +649,11 @@ void KWin::Scripting::init() m_qmlEngine->rootContext()->setContextProperty(QStringLiteral("workspace"), m_workspaceWrapper); m_qmlEngine->rootContext()->setContextProperty(QStringLiteral("options"), options); + + m_declarativeScriptSharedContext->setContextProperty(QStringLiteral("workspace"), new DeclarativeScriptWorkspaceWrapper(this)); + // QQmlListProperty interfaces only work via properties, rebind them as functions here + QQmlExpression expr(m_declarativeScriptSharedContext, nullptr, "workspace.clientList = function() { return workspace.clients }"); + expr.evaluate(); } void KWin::Scripting::start() diff --git a/scripting/scripting.h b/scripting/scripting.h index d2682e22e0..02627e90ad 100644 --- a/scripting/scripting.h +++ b/scripting/scripting.h @@ -51,7 +51,7 @@ namespace KWin class AbstractClient; class Client; class ScriptUnloaderAgent; -class WorkspaceWrapper; +class QtScriptWorkspaceWrapper; class KWIN_EXPORT AbstractScript : public QObject { @@ -362,7 +362,9 @@ public: QQmlEngine *qmlEngine() const; QQmlEngine *qmlEngine(); - WorkspaceWrapper *workspaceWrapper() const; + QQmlContext *declarativeScriptSharedContext() const; + QQmlContext *declarativeScriptSharedContext(); + QtScriptWorkspaceWrapper *workspaceWrapper() const; AbstractScript *findScript(const QString &pluginName) const; @@ -381,7 +383,8 @@ private: LoadScriptList queryScriptsToLoad(); static Scripting *s_self; QQmlEngine *m_qmlEngine; - WorkspaceWrapper *m_workspaceWrapper; + QQmlContext *m_declarativeScriptSharedContext; + QtScriptWorkspaceWrapper *m_workspaceWrapper; }; inline @@ -397,7 +400,19 @@ QQmlEngine *Scripting::qmlEngine() } inline -WorkspaceWrapper *Scripting::workspaceWrapper() const +QQmlContext *Scripting::declarativeScriptSharedContext() const +{ + return m_declarativeScriptSharedContext; +} + +inline +QQmlContext *Scripting::declarativeScriptSharedContext() +{ + return m_declarativeScriptSharedContext; +} + +inline +QtScriptWorkspaceWrapper *Scripting::workspaceWrapper() const { return m_workspaceWrapper; } diff --git a/scripting/workspace_wrapper.cpp b/scripting/workspace_wrapper.cpp index 05aecb6eb6..d10054d576 100644 --- a/scripting/workspace_wrapper.cpp +++ b/scripting/workspace_wrapper.cpp @@ -90,12 +90,12 @@ void WorkspaceWrapper::setNumberOfDesktops(int count) VirtualDesktopManager::self()->setCount(count); } -#define GETTER( rettype, getterName ) \ -rettype WorkspaceWrapper::getterName( ) const { \ +#define GETTER( klass, rettype, getterName ) \ +rettype klass::getterName( ) const { \ return Workspace::self()->getterName(); \ } -GETTER(KWin::AbstractClient*, activeClient) -GETTER(QList< KWin::Client* >, clientList) +GETTER(WorkspaceWrapper, KWin::AbstractClient*, activeClient) +GETTER(QtScriptWorkspaceWrapper, QList< KWin::Client* >, clientList) #undef GETTER @@ -324,4 +324,26 @@ QSize WorkspaceWrapper::virtualScreenSize() const return screens()->size(); } +QtScriptWorkspaceWrapper::QtScriptWorkspaceWrapper(QObject* parent) + : WorkspaceWrapper(parent) {} + + +QQmlListProperty DeclarativeScriptWorkspaceWrapper::clients() +{ + return QQmlListProperty(this, 0, &DeclarativeScriptWorkspaceWrapper::countClientList, &DeclarativeScriptWorkspaceWrapper::atClientList); +} + +int DeclarativeScriptWorkspaceWrapper::countClientList(QQmlListProperty *clients) +{ + return Workspace::self()->clientList().size(); +} + +KWin::Client *DeclarativeScriptWorkspaceWrapper::atClientList(QQmlListProperty *clients, int index) +{ + return Workspace::self()->clientList().at(index); +} + +DeclarativeScriptWorkspaceWrapper::DeclarativeScriptWorkspaceWrapper(QObject* parent) + : WorkspaceWrapper(parent) {} + } // KWin diff --git a/scripting/workspace_wrapper.h b/scripting/workspace_wrapper.h index 5a6c2cbf71..d21989a788 100644 --- a/scripting/workspace_wrapper.h +++ b/scripting/workspace_wrapper.h @@ -26,6 +26,7 @@ along with this program. If not, see . #include #include #include +#include #include namespace KWin @@ -198,7 +199,10 @@ public: ElectricNone }; +protected: explicit WorkspaceWrapper(QObject* parent = nullptr); + +public: #define GETTERSETTERDEF( rettype, getter, setter ) \ rettype getter() const; \ void setter( rettype val ); @@ -222,10 +226,6 @@ void setter( rettype val ); QSize virtualScreenSize() const; QRect virtualScreenGeometry() const; - /** - * List of Clients currently managed by KWin. - **/ - Q_INVOKABLE QList< KWin::Client* > clientList() const; /** * Returns the geometry a Client can use with the specified option. * This method should be preferred over other methods providing screen sizes as the @@ -349,6 +349,31 @@ private Q_SLOTS: void setupClientConnections(KWin::Client* client); }; +class QtScriptWorkspaceWrapper : public WorkspaceWrapper +{ + Q_OBJECT +public: + /** + * List of Clients currently managed by KWin. + **/ + Q_INVOKABLE QList< KWin::Client* > clientList() const; + + explicit QtScriptWorkspaceWrapper(QObject* parent = nullptr); +}; + +class DeclarativeScriptWorkspaceWrapper : public WorkspaceWrapper +{ + Q_OBJECT + + Q_PROPERTY(QQmlListProperty clients READ clients) +public: + QQmlListProperty clients(); + static int countClientList(QQmlListProperty *clients); + static KWin::Client *atClientList(QQmlListProperty *clients, int index); + + explicit DeclarativeScriptWorkspaceWrapper(QObject* parent = nullptr); +}; + } #endif