From adf485c26129b680340da626007cd4c35423bd3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Mon, 3 Mar 2014 13:23:55 +0100 Subject: [PATCH] [kwin] Share QQmlEngine between all declarative KWin Scripts Instead of having each declarative script create it's own qml engine there is one hold by the Scripting singleton. The engine's root context gets populated in Scripting and each script just gets a new child context. Thus also the WorkspaceWrapper instance is shared between the declarative scripts. --- scripting/scripting.cpp | 46 +++++++++++++++++++++++------------------ scripting/scripting.h | 33 +++++++++++++++++++++++------ 2 files changed, 53 insertions(+), 26 deletions(-) diff --git a/scripting/scripting.cpp b/scripting/scripting.cpp index 72d5cab3e7..76150980fe 100644 --- a/scripting/scripting.cpp +++ b/scripting/scripting.cpp @@ -216,7 +216,6 @@ KWin::AbstractScript::AbstractScript(int id, QString scriptName, QString pluginN , m_scriptId(id) , m_pluginName(pluginName) , m_running(false) - , m_workspace(new WorkspaceWrapper(this)) { m_scriptFile.setFileName(scriptName); if (m_pluginName.isNull()) { @@ -295,7 +294,7 @@ void KWin::Script::installScriptFunctions(QScriptEngine* engine) engine->globalObject().setProperty(QStringLiteral("assertNotNull"), assertNotNullFunc); // global properties engine->globalObject().setProperty(QStringLiteral("KWin"), engine->newQMetaObject(&WorkspaceWrapper::staticMetaObject)); - QScriptValue workspace = engine->newQObject(AbstractScript::workspace(), QScriptEngine::QtOwnership, + QScriptValue workspace = engine->newQObject(Scripting::self()->workspaceWrapper(), QScriptEngine::QtOwnership, QScriptEngine::ExcludeSuperClassContents | QScriptEngine::ExcludeDeleteLater); engine->globalObject().setProperty(QStringLiteral("workspace"), workspace, QScriptValue::Undeletable); // install meta functions @@ -528,9 +527,10 @@ void KWin::ScriptUnloaderAgent::scriptUnload(qint64 id) KWin::DeclarativeScript::DeclarativeScript(int id, QString scriptName, QString pluginName, QObject* parent) : AbstractScript(id, scriptName, pluginName, parent) - , m_engine(new QQmlEngine(this)) - , m_component(new QQmlComponent(m_engine, this)) + , m_context(new QQmlContext(Scripting::self()->qmlEngine(), this)) + , m_component(new QQmlComponent(Scripting::self()->qmlEngine(), this)) { + m_context->setContextProperty(QStringLiteral("KWin"), new JSEngineGlobalMethodsWrapper(this)); } KWin::DeclarativeScript::~DeclarativeScript() @@ -542,21 +542,6 @@ void KWin::DeclarativeScript::run() if (running()) { return; } - qmlRegisterType("org.kde.kwin", 2, 0, "DesktopThumbnailItem"); - qmlRegisterType("org.kde.kwin", 2, 0, "ThumbnailItem"); - qmlRegisterType("org.kde.kwin", 2, 0, "DBusCall"); - qmlRegisterType("org.kde.kwin", 2, 0, "ScreenEdgeItem"); - qmlRegisterType(); - qmlRegisterType("org.kde.kwin", 2, 0, "ClientModel"); - qmlRegisterType("org.kde.kwin", 2, 0, "ClientModelByScreen"); - qmlRegisterType("org.kde.kwin", 2, 0, "ClientModelByScreenAndDesktop"); - qmlRegisterType("org.kde.kwin", 2, 0, "ClientFilterModel"); - qmlRegisterType(); - qmlRegisterType(); - - m_engine->rootContext()->setContextProperty(QStringLiteral("workspace"), AbstractScript::workspace()); - m_engine->rootContext()->setContextProperty(QStringLiteral("options"), options); - m_engine->rootContext()->setContextProperty(QStringLiteral("KWin"), new JSEngineGlobalMethodsWrapper(this)); m_component->loadUrl(QUrl::fromLocalFile(scriptFile().fileName())); if (m_component->isLoading()) { @@ -571,7 +556,7 @@ void KWin::DeclarativeScript::createComponent() if (m_component->isError()) { qDebug() << "Component failed to load: " << m_component->errors(); } else { - m_component->create(); + m_component->create(m_context); } setRunning(true); } @@ -612,13 +597,34 @@ KWin::Scripting *KWin::Scripting::create(QObject *parent) KWin::Scripting::Scripting(QObject *parent) : QObject(parent) , m_scriptsLock(new QMutex(QMutex::Recursive)) + , m_qmlEngine(new QQmlEngine(this)) + , m_workspaceWrapper(new WorkspaceWrapper(this)) { + init(); QDBusConnection::sessionBus().registerObject(QStringLiteral("/Scripting"), this, QDBusConnection::ExportScriptableContents | QDBusConnection::ExportScriptableInvokables); QDBusConnection::sessionBus().registerService(QStringLiteral("org.kde.kwin.Scripting")); connect(Workspace::self(), SIGNAL(configChanged()), SLOT(start())); connect(Workspace::self(), SIGNAL(workspaceInitialized()), SLOT(start())); } +void KWin::Scripting::init() +{ + qmlRegisterType("org.kde.kwin", 2, 0, "DesktopThumbnailItem"); + qmlRegisterType("org.kde.kwin", 2, 0, "ThumbnailItem"); + qmlRegisterType("org.kde.kwin", 2, 0, "DBusCall"); + qmlRegisterType("org.kde.kwin", 2, 0, "ScreenEdgeItem"); + qmlRegisterType(); + qmlRegisterType("org.kde.kwin", 2, 0, "ClientModel"); + qmlRegisterType("org.kde.kwin", 2, 0, "ClientModelByScreen"); + qmlRegisterType("org.kde.kwin", 2, 0, "ClientModelByScreenAndDesktop"); + qmlRegisterType("org.kde.kwin", 2, 0, "ClientFilterModel"); + qmlRegisterType(); + qmlRegisterType(); + + m_qmlEngine->rootContext()->setContextProperty(QStringLiteral("workspace"), m_workspaceWrapper); + m_qmlEngine->rootContext()->setContextProperty(QStringLiteral("options"), options); +} + void KWin::Scripting::start() { #if 0 diff --git a/scripting/scripting.h b/scripting/scripting.h index 2ac96ee472..ac495db545 100644 --- a/scripting/scripting.h +++ b/scripting/scripting.h @@ -31,6 +31,7 @@ along with this program. If not, see . #include class QQmlComponent; +class QQmlContext; class QQmlEngine; class QAction; class QDBusPendingCallWatcher; @@ -163,10 +164,6 @@ protected: return m_scriptId; } - WorkspaceWrapper *workspace() { - return m_workspace; - } - private: /** * @brief Parses the @p value to either a QMenu or QAction. @@ -204,7 +201,6 @@ private: QFile m_scriptFile; QString m_pluginName; bool m_running; - WorkspaceWrapper *m_workspace; QHash m_shortcutCallbacks; QHash > m_screenEdgeCallbacks; QHash m_callbacks; @@ -281,7 +277,7 @@ private Q_SLOTS: void createComponent(); private: - QQmlEngine *m_engine; + QQmlContext *m_context; QQmlComponent *m_component; }; @@ -357,6 +353,10 @@ public: **/ QList actionsForUserActionMenu(Client *c, QMenu *parent); + QQmlEngine *qmlEngine() const; + QQmlEngine *qmlEngine(); + WorkspaceWrapper *workspaceWrapper() const; + static Scripting *self(); static Scripting *create(QObject *parent); @@ -368,10 +368,31 @@ private Q_SLOTS: void slotScriptsQueried(); private: + void init(); LoadScriptList queryScriptsToLoad(); static Scripting *s_self; + QQmlEngine *m_qmlEngine; + WorkspaceWrapper *m_workspaceWrapper; }; +inline +QQmlEngine *Scripting::qmlEngine() const +{ + return m_qmlEngine; +} + +inline +QQmlEngine *Scripting::qmlEngine() +{ + return m_qmlEngine; +} + +inline +WorkspaceWrapper *Scripting::workspaceWrapper() const +{ + return m_workspaceWrapper; +} + inline Scripting *Scripting::self() {