File indexing completed on 2024-05-19 16:34:36

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