/* SPDX-FileCopyrightText: 2021 Vlad Zahorodnii SPDX-License-Identifier: GPL-2.0-or-later */ #pragma once #include "core/output.h" #include "effect/effect.h" #include "effect/offscreenquickview.h" #include namespace KWin { class QuickSceneEffect; class QuickSceneEffectPrivate; /** * The QuickSceneView represents a QtQuick scene view on a particular screen. * * The root QML object must be a QQuickItem or a subclass of QQuickItem, other * cases are unsupported. * * @see QuickSceneEffect, OffscreenQuickView */ class KWIN_EXPORT QuickSceneView : public OffscreenQuickView { Q_OBJECT Q_PROPERTY(QuickSceneEffect *effect READ effect CONSTANT) Q_PROPERTY(Output *screen READ screen CONSTANT) Q_PROPERTY(QQuickItem *rootItem READ rootItem CONSTANT) public: explicit QuickSceneView(QuickSceneEffect *effect, Output *screen); ~QuickSceneView() override; QuickSceneEffect *effect() const; Output *screen() const; QQuickItem *rootItem() const; void setRootItem(QQuickItem *item); bool isDirty() const; void markDirty(); void resetDirty(); static QuickSceneView *findView(QQuickItem *item); static QuickSceneView *qmlAttachedProperties(QObject *object); public Q_SLOTS: void scheduleRepaint(); private: QuickSceneEffect *m_effect; Output *m_screen; std::unique_ptr m_rootItem; bool m_dirty = false; }; /** * The QuickSceneEffect class provides a convenient way to write fullscreen * QtQuick-based effects. * * QuickSceneView objects are managed internally. * * The QuickSceneEffect takes care of forwarding input events to QuickSceneView and * rendering. You can override relevant hooks from the Effect class to customize input * handling or rendering, although it's highly recommended that you avoid doing that. * * @see QuickSceneView */ class KWIN_EXPORT QuickSceneEffect : public Effect { Q_OBJECT Q_PROPERTY(QuickSceneView *activeView READ activeView NOTIFY activeViewChanged) Q_PROPERTY(QQmlComponent *delegate READ delegate WRITE setDelegate NOTIFY delegateChanged) public: explicit QuickSceneEffect(QObject *parent = nullptr); ~QuickSceneEffect() override; /** * Returns @c true if the effect is running; otherwise returns @c false. */ bool isRunning() const; /** * Starts or stops the effect depending on @a running. */ void setRunning(bool running); QuickSceneView *activeView() const; /** * Returns the scene view on the specified screen */ Q_INVOKABLE QuickSceneView *viewForScreen(Output *screen) const; /** * Returns the view at the specified @a pos in the global screen coordinates. */ Q_INVOKABLE QuickSceneView *viewAt(const QPoint &pos) const; /** * Get a view at the given direction from the active view * Returns null if no other views exist in the given direction */ Q_INVOKABLE KWin::QuickSceneView *getView(Qt::Edge edge); /** * Sets the given @a view as active. It will get a focusin event and all the other views will be set as inactive */ Q_INVOKABLE void activateView(QuickSceneView *view); /** * The delegate provides a template defining the contents of each instantiated screen view. */ QQmlComponent *delegate() const; void setDelegate(QQmlComponent *delegate); /** * Returns the source URL. */ QUrl source() const; /** * Sets the source url to @a url. Note that the QML component will be loaded the next * time the effect is started. * * While the effect is running, the source url cannot be changed. * * In order to provide your custom initial properties, you need to override * the initialProperties() function. */ void setSource(const QUrl &url); bool eventFilter(QObject *watched, QEvent *event) override; void prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime) override; void paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const QRegion ®ion, Output *screen) override; bool isActive() const override; void windowInputMouseEvent(QEvent *event) override; void grabbedKeyboardEvent(QKeyEvent *keyEvent) override; bool touchDown(qint32 id, const QPointF &pos, std::chrono::microseconds time) override; bool touchMotion(qint32 id, const QPointF &pos, std::chrono::microseconds time) override; bool touchUp(qint32 id, std::chrono::microseconds time) override; static bool supported(); Q_INVOKABLE void checkItemDraggedOutOfScreen(QQuickItem *item); Q_INVOKABLE void checkItemDroppedOutOfScreen(const QPointF &globalPos, QQuickItem *item); Q_SIGNALS: void itemDraggedOutOfScreen(QQuickItem *item, QList screens); void itemDroppedOutOfScreen(const QPointF &globalPos, QQuickItem *item, Output *screen); void activeViewChanged(KWin::QuickSceneView *view); void delegateChanged(); protected: /** * Reimplement this function to provide your initial properties for the scene view * on the specified @a screen. * * @see QQmlComponent::createWithInitialProperties() */ virtual QVariantMap initialProperties(Output *screen); private: void handleScreenAdded(Output *screen); void handleScreenRemoved(Output *screen); void addScreen(Output *screen); void removeScreen(Output *screen); void startInternal(); void stopInternal(); std::unique_ptr d; friend class QuickSceneEffectPrivate; }; } // namespace KWin QML_DECLARE_TYPEINFO(KWin::QuickSceneView, QML_HAS_ATTACHED_PROPERTIES)