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