1 | /******************************************************************** |
2 | KWin - the KDE window manager |
3 | This file is part of the KDE project. |
4 | |
5 | Copyright (C) 2011 Martin Gräßlin <mgraesslin@kde.org> |
6 | |
7 | This program is free software; you can redistribute it and/or modify |
8 | it under the terms of the GNU General Public License as published by |
9 | the Free Software Foundation; either version 2 of the License, or |
10 | (at your option) any later version. |
11 | |
12 | This program is distributed in the hope that it will be useful, |
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 | GNU General Public License for more details. |
16 | |
17 | You should have received a copy of the GNU General Public License |
18 | along with this program. If not, see <http://www.gnu.org/licenses/>. |
19 | *********************************************************************/ |
20 | #ifndef KWIN_SHADOW_H |
21 | #define KWIN_SHADOW_H |
22 | |
23 | #include <QObject> |
24 | #include <QtGui/QPixmap> |
25 | #include <kwineffects.h> |
26 | #include <qvarlengtharray.h> |
27 | |
28 | namespace KWin { |
29 | |
30 | class Toplevel; |
31 | |
32 | /** |
33 | * @short Class representing a Window's Shadow to be rendered by the Compositor. |
34 | * |
35 | * This class holds all information about the Shadow to be rendered together with the |
36 | * window during the Compositing stage. The Shadow consists of several pixmaps and offsets. |
37 | * For a complete description please refer to http://community.kde.org/KWin/Shadow |
38 | * |
39 | * To create a Shadow instance use the static factory method @link createShadow which will |
40 | * create an instance for the currently used Compositing Backend. It will read the X11 Property |
41 | * and create the Shadow and all required data (such as WindowQuads). If there is no Shadow |
42 | * defined for the Toplevel the factory method returns @c NULL. |
43 | * |
44 | * @author Martin Gräßlin <mgraesslin@kde.org> |
45 | * @todo React on Toplevel size changes. |
46 | **/ |
47 | class Shadow : public QObject |
48 | { |
49 | Q_OBJECT |
50 | public: |
51 | virtual ~Shadow(); |
52 | |
53 | /** |
54 | * @return Region of the shadow. |
55 | **/ |
56 | const QRegion &shadowRegion() const { |
57 | return m_shadowRegion; |
58 | }; |
59 | /** |
60 | * @return Cached Shadow Quads |
61 | **/ |
62 | const WindowQuadList &shadowQuads() const { |
63 | return m_shadowQuads; |
64 | }; |
65 | WindowQuadList &shadowQuads() { |
66 | return m_shadowQuads; |
67 | }; |
68 | |
69 | /** |
70 | * This method updates the Shadow when the property has been changed. |
71 | * It is the responsibility of the owner of the Shadow to call this method |
72 | * whenever the owner receives a PropertyNotify event. |
73 | * This method will invoke a re-read of the Property. In case the Property has |
74 | * been withdrawn the method returns @c false. In that case the owner should |
75 | * delete the Shadow. |
76 | * @returns @c true when the shadow has been updated, @c false if the property is not set anymore. |
77 | **/ |
78 | virtual bool updateShadow(); |
79 | |
80 | /** |
81 | * Factory Method to create the shadow from the property. |
82 | * This method takes care of creating an instance of the |
83 | * Shadow class for the current Compositing Backend. |
84 | * |
85 | * If there is no shadow defined for @p toplevel this method |
86 | * will return @c NULL. |
87 | * @param toplevel The Toplevel for which the shadow should be created |
88 | * @return Created Shadow or @c NULL in case there is no shadow defined. |
89 | **/ |
90 | static Shadow *createShadow(Toplevel *toplevel); |
91 | |
92 | /** |
93 | * Reparents the shadow to @p toplevel. |
94 | * Used when a window is deleted. |
95 | * @param toplevel The new parent |
96 | **/ |
97 | void setToplevel(Toplevel *toplevel); |
98 | |
99 | public Q_SLOTS: |
100 | void geometryChanged(); |
101 | |
102 | protected: |
103 | Shadow(Toplevel *toplevel); |
104 | enum ShadowElements { |
105 | ShadowElementTop, |
106 | ShadowElementTopRight, |
107 | ShadowElementRight, |
108 | ShadowElementBottomRight, |
109 | ShadowElementBottom, |
110 | ShadowElementBottomLeft, |
111 | ShadowElementLeft, |
112 | ShadowElementTopLeft, |
113 | ShadowElementsCount |
114 | }; |
115 | |
116 | inline const QPixmap &shadowPixmap(ShadowElements element) const { |
117 | return m_shadowElements[element]; |
118 | }; |
119 | |
120 | int topOffset() const { |
121 | return m_topOffset; |
122 | }; |
123 | int rightOffset() const { |
124 | return m_rightOffset; |
125 | }; |
126 | int bottomOffset() const { |
127 | return m_bottomOffset; |
128 | }; |
129 | int leftOffset() const { |
130 | return m_leftOffset; |
131 | }; |
132 | virtual void buildQuads(); |
133 | void updateShadowRegion(); |
134 | Toplevel *topLevel() { |
135 | return m_topLevel; |
136 | }; |
137 | void setShadowRegion(const QRegion ®ion) { |
138 | m_shadowRegion = region; |
139 | }; |
140 | virtual bool prepareBackend() = 0; |
141 | WindowQuadList m_shadowQuads; |
142 | |
143 | private: |
144 | static QVector<long> readX11ShadowProperty(WId id); |
145 | bool init(const QVector<long> &data); |
146 | Toplevel *m_topLevel; |
147 | // shadow pixmaps |
148 | QPixmap m_shadowElements[ShadowElementsCount]; |
149 | // shadow offsets |
150 | int m_topOffset; |
151 | int m_rightOffset; |
152 | int m_bottomOffset; |
153 | int m_leftOffset; |
154 | // caches |
155 | QRegion m_shadowRegion; |
156 | QSize m_cachedSize; |
157 | }; |
158 | |
159 | } |
160 | |
161 | #endif // KWIN_SHADOW_H |
162 | |