From abbe84bab499f8e421686663db9ddd2e139e0fa7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Mon, 12 Aug 2013 13:09:46 +0200 Subject: [PATCH] Port declarative scripting to QtQuick Getting all functionality from old solution into new one is not really possible. Main problems are that QtScript provided more functionality than the QJSEngine. For example it's no longer possible to just export functions to the engine. We need to have a Qt wrapper object. At the moment this wrapper object doesn't export all functions as the callbacks are tricky. A solution might be to create specific QML types encapsulating functionality which used to be exported on the functions. Nevertheless a basic QML script loads and works and the ported readConfig function works, too. --- CMakeLists.txt | 2 +- scripting/scripting.cpp | 55 ++++++++++++++++++++++------------------- scripting/scripting.h | 48 +++++++++++++++++++++++++++++------ 3 files changed, 72 insertions(+), 33 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 40523fd14a..0d90fdac47 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -221,7 +221,6 @@ set(kwin_OWN_LIBS ) set(kwin_QT_LIBS - ${Qt5Declarative_LIBRARIES} ${Qt5Quick_LIBRARIES} ${Qt5X11Extras_LIBRARIES} ) @@ -229,6 +228,7 @@ set(kwin_QT_LIBS set(kwin_KDE_LIBS ${KDE4Support_LIBRARIES} ${KDE4_KDEUI_LIBRARY} + ${KDECLARATIVE_LIBRARIES} KF5::KCrash KF5::plasma KF5::KWindowSystem diff --git a/scripting/scripting.cpp b/scripting/scripting.cpp index 3ab223ff15..a1bf81c58d 100644 --- a/scripting/scripting.cpp +++ b/scripting/scripting.cpp @@ -26,9 +26,7 @@ along with this program. If not, see . #include "workspace_wrapper.h" #include "scripting_model.h" #include "../client.h" -#if KWIN_QT5_PORTING #include "../thumbnailitem.h" -#endif #include "../options.h" #include "../workspace.h" // KDE @@ -46,13 +44,9 @@ along with this program. If not, see . #include #include #include -#include -#include -#include -#include -#include -#include #include +#include +#include #include #include @@ -266,7 +260,7 @@ bool KWin::AbstractScript::borderActivated(KWin::ElectricBorder edge) return true; } -void KWin::AbstractScript::installScriptFunctions(QScriptEngine* engine) +void KWin::Script::installScriptFunctions(QScriptEngine* engine) { // add our print QScriptValue printFunc = engine->newFunction(kwinScriptPrint); @@ -533,9 +527,8 @@ 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 QDeclarativeEngine(this)) - , m_component(new QDeclarativeComponent(m_engine, this)) - , m_scene(new QGraphicsScene(this)) + , m_engine(new QQmlEngine(this)) + , m_component(new QQmlComponent(m_engine, this)) { } @@ -548,29 +541,26 @@ void KWin::DeclarativeScript::run() if (running()) { return; } - // add read config -#warning DeclarativeScripts needs porting of KDeclarative -#if KWIN_QT5_PORTING KDeclarative kdeclarative; kdeclarative.setDeclarativeEngine(m_engine); kdeclarative.initialize(); kdeclarative.setupBindings(); - installScriptFunctions(kdeclarative.scriptEngine()); - qmlRegisterType("org.kde.kwin", 0, 1, "DesktopThumbnailItem"); - qmlRegisterType("org.kde.kwin", 0, 1, "ThumbnailItem"); -#endif + qmlRegisterType("org.kde.kwin", 2, 0, "DesktopThumbnailItem"); + qmlRegisterType("org.kde.kwin", 2, 0, "ThumbnailItem"); qmlRegisterType(); - qmlRegisterType("org.kde.kwin", 0, 1, "ClientModel"); - qmlRegisterType("org.kde.kwin", 0, 1, "ClientModelByScreen"); - qmlRegisterType("org.kde.kwin", 0, 1, "ClientModelByScreenAndDesktop"); - qmlRegisterType("org.kde.kwin", 0, 1, "ClientFilterModel"); + 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(); + 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()) { - connect(m_component, SIGNAL(statusChanged(QDeclarativeComponent::Status)), SLOT(createComponent())); + connect(m_component, &QQmlComponent::statusChanged, this, &DeclarativeScript::createComponent); } else { createComponent(); } @@ -581,11 +571,26 @@ void KWin::DeclarativeScript::createComponent() if (m_component->isError()) { kDebug(1212) << "Component failed to load: " << m_component->errors(); } else { - m_scene->addItem(qobject_cast(m_component->create())); + m_component->create(); } setRunning(true); } +KWin::JSEngineGlobalMethodsWrapper::JSEngineGlobalMethodsWrapper(KWin::DeclarativeScript *parent) + : QObject(parent) + , m_script(parent) +{ +} + +KWin::JSEngineGlobalMethodsWrapper::~JSEngineGlobalMethodsWrapper() +{ +} + +QVariant KWin::JSEngineGlobalMethodsWrapper::readConfig(const QString &key, QVariant defaultValue) +{ + return m_script->config().readEntry(key, defaultValue); +} + KWin::Scripting *KWin::Scripting::s_self = NULL; KWin::Scripting *KWin::Scripting::create(QObject *parent) diff --git a/scripting/scripting.h b/scripting/scripting.h index 43d819ce69..3a0f89a6ef 100644 --- a/scripting/scripting.h +++ b/scripting/scripting.h @@ -30,8 +30,8 @@ along with this program. If not, see . #include #include -class QDeclarativeComponent; -class QDeclarativeEngine; +class QQmlComponent; +class QQmlEngine; class QAction; class QDBusPendingCallWatcher; class QGraphicsScene; @@ -166,8 +166,6 @@ protected: return m_workspace; } - void installScriptFunctions(QScriptEngine *engine); - private: /** * @brief Parses the @p value to either a QMenu or QAction. @@ -246,6 +244,7 @@ private Q_SLOTS: void slotScriptLoadedFromFile(); private: + void installScriptFunctions(QScriptEngine *engine); /** * Read the script from file into a byte array. * If file cannot be read an empty byte array is returned. @@ -281,9 +280,44 @@ private Q_SLOTS: void createComponent(); private: - QDeclarativeEngine *m_engine; - QDeclarativeComponent *m_component; - QGraphicsScene *m_scene; + QQmlEngine *m_engine; + QQmlComponent *m_component; +}; + +class JSEngineGlobalMethodsWrapper : public QObject +{ + Q_OBJECT + Q_ENUMS(ClientAreaOption) +public: +//------------------------------------------------------------------ +//enums copy&pasted from kwinglobals.h for exporting + + enum ClientAreaOption { + ///< geometry where a window will be initially placed after being mapped + PlacementArea, + ///< window movement snapping area? ignore struts + MovementArea, + ///< geometry to which a window will be maximized + MaximizeArea, + ///< like MaximizeArea, but ignore struts - used e.g. for topmenu + MaximizeFullArea, + ///< area for fullscreen windows + FullScreenArea, + ///< whole workarea (all screens together) + WorkArea, + ///< whole area (all screens together), ignore struts + FullArea, + ///< one whole screen, ignore struts + ScreenArea + }; + explicit JSEngineGlobalMethodsWrapper(DeclarativeScript *parent); + virtual ~JSEngineGlobalMethodsWrapper(); + +public Q_SLOTS: + QVariant readConfig(const QString &key, QVariant defaultValue = QVariant()); + +private: + DeclarativeScript *m_script; }; /**