From 6ab7119d890e740af8f21b78a460e3ecd44b6cea Mon Sep 17 00:00:00 2001 From: Kai Uwe Broulik Date: Tue, 15 Feb 2022 11:03:18 +0100 Subject: [PATCH] Introduce SharedQmlEngine class Allows to drop the direct dependency on KDeclarative only used for `QmlObjectSharedEngine` outside of `KCModuleQML` Signed-off-by: Eike Hein --- src/libkwineffects/CMakeLists.txt | 3 +- src/libkwineffects/kwinoffscreenquickview.cpp | 51 ++++++++++++------- src/libkwineffects/kwinquickeffect.cpp | 9 ++-- src/libkwineffects/sharedqmlengine.cpp | 35 +++++++++++++ src/libkwineffects/sharedqmlengine.h | 27 ++++++++++ 5 files changed, 103 insertions(+), 22 deletions(-) create mode 100644 src/libkwineffects/sharedqmlengine.cpp create mode 100644 src/libkwineffects/sharedqmlengine.h diff --git a/src/libkwineffects/CMakeLists.txt b/src/libkwineffects/CMakeLists.txt index b61df8d09e..53965c8461 100644 --- a/src/libkwineffects/CMakeLists.txt +++ b/src/libkwineffects/CMakeLists.txt @@ -43,6 +43,7 @@ set(kwin_EFFECTSLIB_SRCS kwinoffscreenquickview.cpp kwinquickeffect.cpp logging.cpp + sharedqmlengine.cpp ) add_library(kwineffects SHARED ${kwin_EFFECTSLIB_SRCS}) @@ -55,7 +56,7 @@ target_link_libraries(kwineffects XCB::XCB PRIVATE Qt::Quick - KF5::Declarative + KF5::I18n kwinglutils ) set_target_properties(kwineffects PROPERTIES diff --git a/src/libkwineffects/kwinoffscreenquickview.cpp b/src/libkwineffects/kwinoffscreenquickview.cpp index 733927e47a..0fb32305f5 100644 --- a/src/libkwineffects/kwinoffscreenquickview.cpp +++ b/src/libkwineffects/kwinoffscreenquickview.cpp @@ -11,12 +11,14 @@ #include "kwinglutils.h" #include "logging_p.h" +#include "sharedqmlengine.h" #include #include #include #include #include +#include #include #include #include @@ -26,8 +28,6 @@ #include #include -#include - namespace KWin { @@ -87,7 +87,15 @@ public: class Q_DECL_HIDDEN OffscreenQuickScene::Private { public: - KDeclarative::QmlObjectSharedEngine *qmlObject = nullptr; + Private() + : qmlEngine(SharedQmlEngine::engine()) + { + + } + + SharedQmlEngine::Ptr qmlEngine; + QScopedPointer qmlComponent; + QScopedPointer quickItem; }; OffscreenQuickView::OffscreenQuickView(QObject *parent) @@ -541,44 +549,53 @@ OffscreenQuickScene::OffscreenQuickScene(QObject *parent) : OffscreenQuickView(parent) , d(new OffscreenQuickScene::Private) { - d->qmlObject = new KDeclarative::QmlObjectSharedEngine(this); } OffscreenQuickScene::OffscreenQuickScene(QObject *parent, QWindow *renderWindow) : OffscreenQuickView(parent, renderWindow) , d(new OffscreenQuickScene::Private) { - d->qmlObject = new KDeclarative::QmlObjectSharedEngine(this); } OffscreenQuickScene::OffscreenQuickScene(QObject *parent, QWindow *renderWindow, ExportMode exportMode) : OffscreenQuickView(parent, renderWindow, exportMode) , d(new OffscreenQuickScene::Private) { - d->qmlObject = new KDeclarative::QmlObjectSharedEngine(this); } OffscreenQuickScene::OffscreenQuickScene(QObject *parent, OffscreenQuickView::ExportMode exportMode) : OffscreenQuickView(parent, exportMode) , d(new OffscreenQuickScene::Private) { - d->qmlObject = new KDeclarative::QmlObjectSharedEngine(this); } -OffscreenQuickScene::~OffscreenQuickScene() -{ - delete d->qmlObject; -} +OffscreenQuickScene::~OffscreenQuickScene() = default; void OffscreenQuickScene::setSource(const QUrl &source) { - d->qmlObject->setSource(source); + if (!d->qmlComponent) { + d->qmlComponent.reset(new QQmlComponent(d->qmlEngine.data())); + } - QQuickItem *item = rootItem(); - if (!item) { - qCDebug(LIBKWINEFFECTS) << "Could not load effect quick view" << source; + d->qmlComponent->loadUrl(source); + if (d->qmlComponent->isError()) { + qCWarning(LIBKWINEFFECTS).nospace() << "Failed to load effect quick view " << source << ": " << d->qmlComponent->errors(); + d->qmlComponent.reset(); return; } + + d->quickItem.reset(); + + QScopedPointer qmlObject(d->qmlComponent->create()); + QQuickItem *item = qobject_cast(qmlObject.data()); + if (!item) { + qCWarning(LIBKWINEFFECTS) << "Root object of effect quick view" << source << "is not a QQuickItem"; + return; + } + + qmlObject.take(); + d->quickItem.reset(item); + item->setParentItem(contentItem()); auto updateSize = [item, this]() { item->setSize(contentItem()->size()); }; @@ -589,12 +606,12 @@ void OffscreenQuickScene::setSource(const QUrl &source) QQmlContext *OffscreenQuickScene::rootContext() const { - return d->qmlObject->rootContext(); + return d->qmlEngine->rootContext(); } QQuickItem *OffscreenQuickScene::rootItem() const { - return qobject_cast(d->qmlObject->rootObject()); + return d->quickItem.data(); } } // namespace KWin diff --git a/src/libkwineffects/kwinquickeffect.cpp b/src/libkwineffects/kwinquickeffect.cpp index 0026dfc630..4b1c579b39 100644 --- a/src/libkwineffects/kwinquickeffect.cpp +++ b/src/libkwineffects/kwinquickeffect.cpp @@ -6,9 +6,10 @@ #include "kwinquickeffect.h" -#include +#include "sharedqmlengine.h" #include +#include #include namespace KWin @@ -19,7 +20,7 @@ class QuickSceneEffectPrivate public: static QuickSceneEffectPrivate *get(QuickSceneEffect *effect) { return effect->d.data(); } - QScopedPointer qmlEngine; + SharedQmlEngine::Ptr qmlEngine; QScopedPointer qmlComponent; QUrl source; QHash views; @@ -254,11 +255,11 @@ void QuickSceneEffect::startInternal() } if (!d->qmlEngine) { - d->qmlEngine.reset(new KDeclarative::QmlObjectSharedEngine(this)); + d->qmlEngine = SharedQmlEngine::engine(); } if (!d->qmlComponent) { - d->qmlComponent.reset(new QQmlComponent(d->qmlEngine->engine())); + d->qmlComponent.reset(new QQmlComponent(d->qmlEngine.data())); d->qmlComponent->loadUrl(d->source); if (d->qmlComponent->isError()) { qWarning().nospace() << "Failed to load " << d->source << ": " << d->qmlComponent->errors(); diff --git a/src/libkwineffects/sharedqmlengine.cpp b/src/libkwineffects/sharedqmlengine.cpp new file mode 100644 index 0000000000..73643b4c25 --- /dev/null +++ b/src/libkwineffects/sharedqmlengine.cpp @@ -0,0 +1,35 @@ +/* + SPDX-FileCopyrightText: 2022 MBition GmbH + SPDX-FileContributor: Kai Uwe Broulik + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +#include "sharedqmlengine.h" + +#include +#include + +#include + +namespace KWin +{ + +QWeakPointer SharedQmlEngine::s_engine; + +SharedQmlEngine::Ptr SharedQmlEngine::engine() +{ + if (!s_engine) { + Ptr ptr(new QQmlEngine()); + + auto *i18nContext = new KLocalizedContext(ptr.data()); + ptr->rootContext()->setContextObject(i18nContext); + + s_engine = ptr; + return ptr; + } + + return s_engine.toStrongRef(); +} + +} // namespace KWin diff --git a/src/libkwineffects/sharedqmlengine.h b/src/libkwineffects/sharedqmlengine.h new file mode 100644 index 0000000000..6f4d1eb99e --- /dev/null +++ b/src/libkwineffects/sharedqmlengine.h @@ -0,0 +1,27 @@ +/* + SPDX-FileCopyrightText: 2022 MBition GmbH + SPDX-FileContributor: Kai Uwe Broulik + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +#pragma once + +#include + +class QQmlEngine; + +namespace KWin +{ + +class SharedQmlEngine +{ +public: + using Ptr = QSharedPointer; + static Ptr engine(); + +private: + static QWeakPointer s_engine; +}; + +} // namespace KWin