File indexing completed on 2024-05-19 05:31:44

0001 /*
0002     SPDX-FileCopyrightText: 2021 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #pragma once
0008 
0009 #include "core/output.h"
0010 #include "effect/effect.h"
0011 #include "effect/offscreenquickview.h"
0012 
0013 #include <QQmlComponent>
0014 
0015 namespace KWin
0016 {
0017 
0018 class QuickSceneEffect;
0019 class QuickSceneEffectPrivate;
0020 
0021 /**
0022  * The QuickSceneView represents a QtQuick scene view on a particular screen.
0023  *
0024  * The root QML object must be a QQuickItem or a subclass of QQuickItem, other
0025  * cases are unsupported.
0026  *
0027  * @see QuickSceneEffect, OffscreenQuickView
0028  */
0029 class KWIN_EXPORT QuickSceneView : public OffscreenQuickView
0030 {
0031     Q_OBJECT
0032     Q_PROPERTY(QuickSceneEffect *effect READ effect CONSTANT)
0033     Q_PROPERTY(Output *screen READ screen CONSTANT)
0034     Q_PROPERTY(QQuickItem *rootItem READ rootItem CONSTANT)
0035 
0036 public:
0037     explicit QuickSceneView(QuickSceneEffect *effect, Output *screen);
0038     ~QuickSceneView() override;
0039 
0040     QuickSceneEffect *effect() const;
0041     Output *screen() const;
0042 
0043     QQuickItem *rootItem() const;
0044     void setRootItem(QQuickItem *item);
0045 
0046     bool isDirty() const;
0047     void markDirty();
0048     void resetDirty();
0049 
0050     static QuickSceneView *findView(QQuickItem *item);
0051     static QuickSceneView *qmlAttachedProperties(QObject *object);
0052 
0053 public Q_SLOTS:
0054     void scheduleRepaint();
0055 
0056 private:
0057     QuickSceneEffect *m_effect;
0058     Output *m_screen;
0059     std::unique_ptr<QQuickItem> m_rootItem;
0060     bool m_dirty = false;
0061 };
0062 
0063 /**
0064  * The QuickSceneEffect class provides a convenient way to write fullscreen
0065  * QtQuick-based effects.
0066  *
0067  * QuickSceneView objects are managed internally.
0068  *
0069  * The QuickSceneEffect takes care of forwarding input events to QuickSceneView and
0070  * rendering. You can override relevant hooks from the Effect class to customize input
0071  * handling or rendering, although it's highly recommended that you avoid doing that.
0072  *
0073  * @see QuickSceneView
0074  */
0075 class KWIN_EXPORT QuickSceneEffect : public Effect
0076 {
0077     Q_OBJECT
0078     Q_PROPERTY(QuickSceneView *activeView READ activeView NOTIFY activeViewChanged)
0079     Q_PROPERTY(QQmlComponent *delegate READ delegate WRITE setDelegate NOTIFY delegateChanged)
0080 
0081 public:
0082     explicit QuickSceneEffect(QObject *parent = nullptr);
0083     ~QuickSceneEffect() override;
0084 
0085     /**
0086      * Returns @c true if the effect is running; otherwise returns @c false.
0087      */
0088     bool isRunning() const;
0089 
0090     /**
0091      * Starts or stops the effect depending on @a running.
0092      */
0093     void setRunning(bool running);
0094 
0095     QuickSceneView *activeView() const;
0096 
0097     /**
0098      * Returns the scene view on the specified screen
0099      */
0100     Q_INVOKABLE QuickSceneView *viewForScreen(Output *screen) const;
0101 
0102     /**
0103      * Returns the view at the specified @a pos in the global screen coordinates.
0104      */
0105     Q_INVOKABLE QuickSceneView *viewAt(const QPoint &pos) const;
0106 
0107     /**
0108      * Get a view at the given direction from the active view
0109      * Returns null if no other views exist in the given direction
0110      */
0111     Q_INVOKABLE KWin::QuickSceneView *getView(Qt::Edge edge);
0112 
0113     /**
0114      * Sets the given @a view as active. It will get a focusin event and all the other views will be set as inactive
0115      */
0116     Q_INVOKABLE void activateView(QuickSceneView *view);
0117 
0118     /**
0119      * The delegate provides a template defining the contents of each instantiated screen view.
0120      */
0121     QQmlComponent *delegate() const;
0122     void setDelegate(QQmlComponent *delegate);
0123 
0124     /**
0125      * Returns the source URL.
0126      */
0127     QUrl source() const;
0128 
0129     /**
0130      * Sets the source url to @a url. Note that the QML component will be loaded the next
0131      * time the effect is started.
0132      *
0133      * While the effect is running, the source url cannot be changed.
0134      *
0135      * In order to provide your custom initial properties, you need to override
0136      * the initialProperties() function.
0137      */
0138     void setSource(const QUrl &url);
0139 
0140     bool eventFilter(QObject *watched, QEvent *event) override;
0141 
0142     void prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime) override;
0143     void paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const QRegion &region, Output *screen) override;
0144     bool isActive() const override;
0145 
0146     void windowInputMouseEvent(QEvent *event) override;
0147     void grabbedKeyboardEvent(QKeyEvent *keyEvent) override;
0148 
0149     bool touchDown(qint32 id, const QPointF &pos, std::chrono::microseconds time) override;
0150     bool touchMotion(qint32 id, const QPointF &pos, std::chrono::microseconds time) override;
0151     bool touchUp(qint32 id, std::chrono::microseconds time) override;
0152 
0153     static bool supported();
0154 
0155     Q_INVOKABLE void checkItemDraggedOutOfScreen(QQuickItem *item);
0156     Q_INVOKABLE void checkItemDroppedOutOfScreen(const QPointF &globalPos, QQuickItem *item);
0157 
0158 Q_SIGNALS:
0159     void itemDraggedOutOfScreen(QQuickItem *item, QList<Output *> screens);
0160     void itemDroppedOutOfScreen(const QPointF &globalPos, QQuickItem *item, Output *screen);
0161     void activeViewChanged(KWin::QuickSceneView *view);
0162     void delegateChanged();
0163 
0164 protected:
0165     /**
0166      * Reimplement this function to provide your initial properties for the scene view
0167      * on the specified @a screen.
0168      *
0169      * @see QQmlComponent::createWithInitialProperties()
0170      */
0171     virtual QVariantMap initialProperties(Output *screen);
0172 
0173 private:
0174     void handleScreenAdded(Output *screen);
0175     void handleScreenRemoved(Output *screen);
0176 
0177     void addScreen(Output *screen);
0178     void startInternal();
0179     void stopInternal();
0180 
0181     std::unique_ptr<QuickSceneEffectPrivate> d;
0182     friend class QuickSceneEffectPrivate;
0183 };
0184 
0185 } // namespace KWin
0186 
0187 QML_DECLARE_TYPEINFO(KWin::QuickSceneView, QML_HAS_ATTACHED_PROPERTIES)