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.
This commit is contained in:
parent
a17d99ee02
commit
0c0fb99919
2 changed files with 57 additions and 11 deletions
|
@ -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…
Reference in a new issue