kwineffects: Add SceneView attached property

SceneView attached property is a more script friendly way to pass the
information about a screen view from C++ to QML code.
master
Vlad Zahorodnii 2 years ago
parent a17d99ee02
commit 0c0fb99919

@ -18,22 +18,41 @@
namespace KWin
{
static QHash<QQuickWindow *, QuickSceneView *> s_views;
class QuickSceneViewIncubator : public QQmlIncubator
{
public:
QuickSceneViewIncubator(const std::function<void(QuickSceneViewIncubator *)> &statusChangedCallback)
QuickSceneViewIncubator(QuickSceneEffect *effect, EffectScreen *screen, const std::function<void(QuickSceneViewIncubator *)> &statusChangedCallback)
: QQmlIncubator(QQmlIncubator::Asynchronous)
, m_effect(effect)
, m_screen(screen)
, m_statusChangedCallback(statusChangedCallback)
{
}
std::unique_ptr<QuickSceneView> result()
{
return std::move(m_view);
}
void setInitialState(QObject *object) override
{
m_view = std::make_unique<QuickSceneView>(m_effect, m_screen);
m_view->setAutomaticRepaint(false);
m_view->setRootItem(qobject_cast<QQuickItem *>(object));
}
void statusChanged(QQmlIncubator::Status status) override
{
m_statusChangedCallback(this);
}
private:
QuickSceneEffect *m_effect;
EffectScreen *m_screen;
std::function<void(QuickSceneViewIncubator *)> m_statusChangedCallback;
std::unique_ptr<QuickSceneView> m_view;
};
class QuickSceneEffectPrivate
@ -74,10 +93,13 @@ QuickSceneView::QuickSceneView(QuickSceneEffect *effect, EffectScreen *screen)
connect(screen, &EffectScreen::geometryChanged, this, [this, screen]() {
setGeometry(screen->geometry());
});
s_views.insert(window(), this);
}
QuickSceneView::~QuickSceneView()
{
s_views.remove(window());
}
QQuickItem *QuickSceneView::rootItem() const
@ -130,6 +152,23 @@ void QuickSceneView::scheduleRepaint()
effects->addRepaint(geometry());
}
QuickSceneView *QuickSceneView::findView(QQuickItem *item)
{
return s_views.value(item->window());
}
QuickSceneView *QuickSceneView::qmlAttachedProperties(QObject *object)
{
QQuickItem *item = qobject_cast<QQuickItem *>(object);
if (item) {
if (QuickSceneView *view = findView(item)) {
return view;
}
}
qCWarning(LIBKWINEFFECTS) << "Could not find SceneView for" << object;
return nullptr;
}
QuickSceneEffect::QuickSceneEffect(QObject *parent)
: Effect(parent)
, d(new QuickSceneEffectPrivate)
@ -366,21 +405,19 @@ void QuickSceneEffect::addScreen(EffectScreen *screen)
properties["width"] = screen->geometry().width();
properties["height"] = screen->geometry().height();
auto incubator = new QuickSceneViewIncubator([this, screen](QuickSceneViewIncubator *incubator) {
auto incubator = new QuickSceneViewIncubator(this, screen, [this, screen](QuickSceneViewIncubator *incubator) {
if (incubator->isReady()) {
auto view = new QuickSceneView(this, screen);
view->setRootItem(qobject_cast<QQuickItem *>(incubator->object()));
auto view = incubator->result();
if (view->contentItem()) {
view->contentItem()->setFocus(false);
}
view->setAutomaticRepaint(false);
connect(view, &QuickSceneView::repaintNeeded, this, [view]() {
effects->addRepaint(view->geometry());
connect(view.get(), &QuickSceneView::repaintNeeded, this, [screen]() {
effects->addRepaint(screen->geometry());
});
connect(view, &QuickSceneView::renderRequested, view, &QuickSceneView::scheduleRepaint);
connect(view, &QuickSceneView::sceneChanged, view, &QuickSceneView::scheduleRepaint);
connect(view.get(), &QuickSceneView::renderRequested, view.get(), &QuickSceneView::scheduleRepaint);
connect(view.get(), &QuickSceneView::sceneChanged, view.get(), &QuickSceneView::scheduleRepaint);
view->scheduleRepaint();
d->views[screen].reset(view);
d->views[screen] = std::move(view);
} else if (incubator->isError()) {
qCWarning(LIBKWINEFFECTS) << "Could not create a view for QML file" << d->qmlComponent->url();
qCWarning(LIBKWINEFFECTS) << incubator->errors();

@ -9,6 +9,8 @@
#include "kwineffects.h"
#include "kwinoffscreenquickview.h"
#include <QQmlEngine>
namespace KWin
{
@ -26,6 +28,8 @@ class QuickSceneEffectPrivate;
class KWINEFFECTS_EXPORT QuickSceneView : public OffscreenQuickView
{
Q_OBJECT
Q_PROPERTY(QuickSceneEffect *effect READ effect CONSTANT)
Q_PROPERTY(EffectScreen *screen READ screen CONSTANT)
public:
explicit QuickSceneView(QuickSceneEffect *effect, EffectScreen *screen);
@ -41,6 +45,9 @@ public:
void markDirty();
void resetDirty();
static QuickSceneView *findView(QQuickItem *item);
static QuickSceneView *qmlAttachedProperties(QObject *object);
public Q_SLOTS:
void scheduleRepaint();
@ -96,7 +103,7 @@ public:
/**
* Get a view at the given direction from the active view
* Returns null if no other views exist in the given direction
* Returns null if no other views exist in the given direction
*/
Q_INVOKABLE KWin::QuickSceneView *getView(Qt::Edge edge);
@ -166,3 +173,5 @@ private:
};
} // namespace KWin
QML_DECLARE_TYPEINFO(KWin::QuickSceneView, QML_HAS_ATTACHED_PROPERTIES)

Loading…
Cancel
Save