File indexing completed on 2024-04-28 05:30:30

0001 /*
0002     KWin - the KDE window manager
0003     This file is part of the KDE project.
0004 
0005     SPDX-FileCopyrightText: 2011 Martin Gräßlin <mgraesslin@kde.org>
0006     SPDX-FileCopyrightText: 2020 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
0007 
0008     SPDX-License-Identifier: GPL-2.0-or-later
0009 */
0010 #pragma once
0011 
0012 #include "kwin_export.h"
0013 
0014 #include <QImage>
0015 #include <QObject>
0016 #include <QRectF>
0017 
0018 #include <xcb/xcb.h>
0019 
0020 namespace KDecoration2
0021 {
0022 class Decoration;
0023 class DecorationShadow;
0024 }
0025 
0026 namespace KWin
0027 {
0028 
0029 class ShadowInterface;
0030 class Window;
0031 
0032 /**
0033  * @short Class representing a Window's Shadow to be rendered by the Compositor.
0034  *
0035  * This class holds all information about the Shadow to be rendered together with the
0036  * window during the Compositing stage. The Shadow consists of several pixmaps and offsets.
0037  * For a complete description please refer to https://community.kde.org/KWin/Shadow
0038  *
0039  * To create a Shadow instance use the static factory method createShadow which will
0040  * create an instance for the currently used Compositing Backend. It will read the X11 Property
0041  * and create the Shadow and all required data (such as WindowQuads). If there is no Shadow
0042  * defined for the Window the factory method returns @c NULL.
0043  *
0044  * @author Martin Gräßlin <mgraesslin@kde.org>
0045  * @todo React on Window size changes.
0046  */
0047 class KWIN_EXPORT Shadow : public QObject
0048 {
0049     Q_OBJECT
0050 public:
0051     explicit Shadow(Window *window);
0052     ~Shadow() override;
0053 
0054     /**
0055      * This method updates the Shadow when the property has been changed.
0056      * It is the responsibility of the owner of the Shadow to call this method
0057      * whenever the owner receives a PropertyNotify event.
0058      * This method will invoke a re-read of the Property. In case the Property has
0059      * been withdrawn the method returns @c false. In that case the owner should
0060      * delete the Shadow.
0061      * @returns @c true when the shadow has been updated, @c false if the property is not set anymore.
0062      */
0063     bool updateShadow();
0064 
0065     /**
0066      * Factory Method to create the shadow from the property.
0067      * This method takes care of creating an instance of the
0068      * Shadow class for the current Compositing Backend.
0069      *
0070      * If there is no shadow defined for @p window this method
0071      * will return @c NULL.
0072      * @param window The Window for which the shadow should be created
0073      * @return Created Shadow or @c NULL in case there is no shadow defined.
0074      */
0075     static std::unique_ptr<Shadow> createShadow(Window *window);
0076 
0077     Window *window() const;
0078 
0079     bool hasDecorationShadow() const
0080     {
0081         return m_decorationShadow != nullptr;
0082     }
0083     QImage decorationShadowImage() const;
0084 
0085     std::weak_ptr<KDecoration2::DecorationShadow> decorationShadow() const
0086     {
0087         return m_decorationShadow;
0088     }
0089 
0090     enum ShadowElements {
0091         ShadowElementTop,
0092         ShadowElementTopRight,
0093         ShadowElementRight,
0094         ShadowElementBottomRight,
0095         ShadowElementBottom,
0096         ShadowElementBottomLeft,
0097         ShadowElementLeft,
0098         ShadowElementTopLeft,
0099         ShadowElementsCount
0100     };
0101     QSize elementSize(ShadowElements element) const;
0102 
0103     QRectF rect() const
0104     {
0105         return QRectF(QPoint(0, 0), m_cachedSize);
0106     }
0107     QMargins offset() const
0108     {
0109         return m_offset;
0110     }
0111     inline const QImage &shadowElement(ShadowElements element) const
0112     {
0113         return m_shadowElements[element];
0114     }
0115 
0116 Q_SIGNALS:
0117     void offsetChanged();
0118     void rectChanged();
0119     void textureChanged();
0120 
0121 public Q_SLOTS:
0122     void geometryChanged();
0123 
0124 private:
0125     static std::unique_ptr<Shadow> createShadowFromX11(Window *window);
0126     static std::unique_ptr<Shadow> createShadowFromDecoration(Window *window);
0127     static std::unique_ptr<Shadow> createShadowFromWayland(Window *window);
0128     static std::unique_ptr<Shadow> createShadowFromInternalWindow(Window *window);
0129     static QList<uint32_t> readX11ShadowProperty(xcb_window_t id);
0130     bool init(const QList<uint32_t> &data);
0131     bool init(KDecoration2::Decoration *decoration);
0132     bool init(const QPointer<ShadowInterface> &shadow);
0133     bool init(const QWindow *window);
0134     Window *m_window;
0135     // shadow elements
0136     QImage m_shadowElements[ShadowElementsCount];
0137     // shadow offsets
0138     QMargins m_offset;
0139     // caches
0140     QSizeF m_cachedSize;
0141     // Decoration based shadows
0142     std::shared_ptr<KDecoration2::DecorationShadow> m_decorationShadow;
0143 };
0144 
0145 }