Merge lp:~3v1n0/unity/shadows-on-existing-pixmaps-cleanup into lp:unity
- shadows-on-existing-pixmaps-cleanup
- Merge into trunk
Proposed by
Marco Trevisan (Treviño)
Status: | Merged |
---|---|
Approved by: | Andrea Azzarone |
Approved revision: | no longer in the source branch. |
Merged at revision: | 4162 |
Proposed branch: | lp:~3v1n0/unity/shadows-on-existing-pixmaps-cleanup |
Merge into: | lp:unity |
Prerequisite: | lp:~hikiko/unity/unity.shadows-on-existing-pixmaps |
Diff against target: |
567 lines (+171/-150) 8 files modified
decorations/DecoratedWindow.cpp (+58/-29) decorations/DecoratedWindow.h (+1/-0) decorations/DecorationsManager.cpp (+0/-27) decorations/DecorationsPriv.h (+5/-3) decorations/DecorationsShape.cpp (+72/-67) decorations/DecorationsShape.h (+28/-17) plugins/unityshell/src/unityshell.cpp (+1/-0) unity-shared/CompizUtils.cpp (+6/-7) |
To merge this branch: | bzr merge lp:~3v1n0/unity/shadows-on-existing-pixmaps-cleanup |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Andrea Azzarone (community) | Approve | ||
Review via email: mp+301099@code.launchpad.net |
Commit message
DecoratedWindow: Cleanup shadows for shaped windows, reduce recomputation
Description of the change
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'decorations/DecoratedWindow.cpp' | |||
2 | --- decorations/DecoratedWindow.cpp 2016-07-27 10:19:12 +0000 | |||
3 | +++ decorations/DecoratedWindow.cpp 2016-07-27 10:19:13 +0000 | |||
4 | @@ -31,8 +31,6 @@ | |||
5 | 31 | #include "WindowManager.h" | 31 | #include "WindowManager.h" |
6 | 32 | #include "UnitySettings.h" | 32 | #include "UnitySettings.h" |
7 | 33 | 33 | ||
8 | 34 | #include <X11/extensions/shape.h> | ||
9 | 35 | |||
10 | 36 | namespace unity | 34 | namespace unity |
11 | 37 | { | 35 | { |
12 | 38 | namespace decoration | 36 | namespace decoration |
13 | @@ -40,6 +38,7 @@ | |||
14 | 40 | namespace | 38 | namespace |
15 | 41 | { | 39 | { |
16 | 42 | const std::string MENUS_PANEL_NAME = "WindowLIM"; | 40 | const std::string MENUS_PANEL_NAME = "WindowLIM"; |
17 | 41 | const int SHADOW_BLUR_MARGIN_FACTOR = 2; | ||
18 | 43 | } | 42 | } |
19 | 44 | 43 | ||
20 | 45 | Window::Impl::Impl(Window* parent, CompWindow* win) | 44 | Window::Impl::Impl(Window* parent, CompWindow* win) |
21 | @@ -504,13 +503,21 @@ | |||
22 | 504 | return (win_->frame() || win_->hasUnmapReference()) && FullyDecorated(); | 503 | return (win_->frame() || win_->hasUnmapReference()) && FullyDecorated(); |
23 | 505 | } | 504 | } |
24 | 506 | 505 | ||
25 | 506 | bool Window::Impl::IsRectangular() const | ||
26 | 507 | { | ||
27 | 508 | return win_->region().numRects() == 1; | ||
28 | 509 | } | ||
29 | 510 | |||
30 | 507 | GLTexture* Window::Impl::ShadowTexture() const | 511 | GLTexture* Window::Impl::ShadowTexture() const |
31 | 508 | { | 512 | { |
32 | 513 | if (!IsRectangular()) | ||
33 | 514 | return shaped_shadow_pixmap_->texture(); | ||
34 | 515 | |||
35 | 509 | auto const& mi = manager_->impl_; | 516 | auto const& mi = manager_->impl_; |
36 | 510 | if (active() || parent_->scaled()) | 517 | if (active() || parent_->scaled()) |
38 | 511 | return win_->region().numRects() > 1 ? shaped_shadow_pixmap_->texture() : mi->active_shadow_pixmap_->texture(); | 518 | return mi->active_shadow_pixmap_->texture(); |
39 | 512 | 519 | ||
41 | 513 | return win_->region().numRects() > 1 ? shaped_shadow_pixmap_->texture() : mi->inactive_shadow_pixmap_->texture(); | 520 | return mi->inactive_shadow_pixmap_->texture(); |
42 | 514 | } | 521 | } |
43 | 515 | 522 | ||
44 | 516 | unsigned Window::Impl::ShadowRadius() const | 523 | unsigned Window::Impl::ShadowRadius() const |
45 | @@ -678,6 +685,26 @@ | |||
46 | 678 | } | 685 | } |
47 | 679 | } | 686 | } |
48 | 680 | 687 | ||
49 | 688 | cu::PixmapTexture::Ptr Window::Impl::BuildShapedShadowTexture(nux::Size const& size, unsigned radius, nux::Color const& color, Shape const& shape) { | ||
50 | 689 | nux::CairoGraphics img(CAIRO_FORMAT_ARGB32, size.width, size.height); | ||
51 | 690 | auto* img_ctx = img.GetInternalContext(); | ||
52 | 691 | |||
53 | 692 | for (auto const& rect : shape.GetRectangles()) | ||
54 | 693 | { | ||
55 | 694 | cairo_rectangle(img_ctx, rect.x + radius * SHADOW_BLUR_MARGIN_FACTOR - shape.XOffset(), rect.y + radius * SHADOW_BLUR_MARGIN_FACTOR - shape.YOffset(), rect.width, rect.height); | ||
56 | 695 | cairo_set_source_rgba(img_ctx, color.red, color.green, color.blue, color.alpha); | ||
57 | 696 | cairo_fill(img_ctx); | ||
58 | 697 | } | ||
59 | 698 | |||
60 | 699 | img.BlurSurface(radius); | ||
61 | 700 | |||
62 | 701 | cu::CairoContext shadow_ctx(size.width, size.height); | ||
63 | 702 | cairo_set_source_surface(shadow_ctx, img.GetSurface(), 0, 0); | ||
64 | 703 | cairo_paint(shadow_ctx); | ||
65 | 704 | |||
66 | 705 | return shadow_ctx; | ||
67 | 706 | } | ||
68 | 707 | |||
69 | 681 | void Window::Impl::ComputeShapedShadowQuad() | 708 | void Window::Impl::ComputeShapedShadowQuad() |
70 | 682 | { | 709 | { |
71 | 683 | if (!(deco_elements_ & cu::DecorationElement::SHADOW)) | 710 | if (!(deco_elements_ & cu::DecorationElement::SHADOW)) |
72 | @@ -690,23 +717,26 @@ | |||
73 | 690 | 717 | ||
74 | 691 | nux::Color color = active() ? manager_->active_shadow_color() : manager_->inactive_shadow_color(); | 718 | nux::Color color = active() ? manager_->active_shadow_color() : manager_->inactive_shadow_color(); |
75 | 692 | unsigned int radius = active() ? manager_->active_shadow_radius() : manager_->inactive_shadow_radius(); | 719 | unsigned int radius = active() ? manager_->active_shadow_radius() : manager_->inactive_shadow_radius(); |
81 | 693 | DecorationsShape shape; | 720 | |
82 | 694 | shape.initShape(win_->id()); | 721 | Shape shape(win_->id()); |
83 | 695 | shaped_shadow_pixmap_ = manager_->impl_->BuildShapedShadowTexture(radius, color, shape); | 722 | auto const& border = win_->borderRect(); |
84 | 696 | 723 | auto const& shadow_offset = manager_->shadow_offset(); | |
85 | 697 | const auto* texture = ShadowTexture(); | 724 | |
86 | 725 | // Ideally it would be shape.getWidth + radius * 2 but Cairographics::BlurSurface | ||
87 | 726 | // isn't bounded by the radius and we need to compensate by using a larger texture. | ||
88 | 727 | int width = shape.Width() + radius * 2 * SHADOW_BLUR_MARGIN_FACTOR; | ||
89 | 728 | int height = shape.Height() + radius * 2 * SHADOW_BLUR_MARGIN_FACTOR; | ||
90 | 729 | |||
91 | 730 | if (width != last_shadow_rect_.width() || height != last_shadow_rect_.height()) | ||
92 | 731 | shaped_shadow_pixmap_ = BuildShapedShadowTexture({width, height}, radius, color, shape); | ||
93 | 732 | |||
94 | 733 | const auto* texture = shaped_shadow_pixmap_->texture(); | ||
95 | 698 | 734 | ||
96 | 699 | if (!texture || !texture->width() || !texture->height()) | 735 | if (!texture || !texture->width() || !texture->height()) |
97 | 700 | return; | 736 | return; |
98 | 701 | 737 | ||
107 | 702 | CompRect border = win_->borderRect(); | 738 | int x = border.x() + shadow_offset.x - radius * 2 + shape.XOffset(); |
108 | 703 | nux::Point2D<int> shadow_offset = manager_->shadow_offset(); | 739 | int y = border.y() + shadow_offset.y - radius * 2 + shape.YOffset(); |
101 | 704 | // ideally it would be -radius for the *2 part see comment in Manager::Impl::BuildShapedShadowTexture | ||
102 | 705 | // in DecorationsManager.cpp Make sure to keep these factors in sync. | ||
103 | 706 | int x = border.x() + shadow_offset.x - radius * 2 + shape.getXoffs(); | ||
104 | 707 | int y = border.y() + shadow_offset.y - radius * 2 + shape.getYoffs(); | ||
105 | 708 | int width = texture->width(); | ||
106 | 709 | int height = texture->height(); | ||
109 | 710 | 740 | ||
110 | 711 | auto* quad = &shadow_quads_[Quads::Pos(0)]; | 741 | auto* quad = &shadow_quads_[Quads::Pos(0)]; |
111 | 712 | quad->box.setGeometry(x, y, width, height); | 742 | quad->box.setGeometry(x, y, width, height); |
112 | @@ -715,14 +745,14 @@ | |||
113 | 715 | quad->matrix.y0 = -COMP_TEX_COORD_Y(quad->matrix, quad->box.y1()); | 745 | quad->matrix.y0 = -COMP_TEX_COORD_Y(quad->matrix, quad->box.y1()); |
114 | 716 | 746 | ||
115 | 717 | CompRect shaped_shadow_rect(x, y, width, height); | 747 | CompRect shaped_shadow_rect(x, y, width, height); |
117 | 718 | if (shaped_shadow_rect != last_shadow_rect_) { | 748 | if (shaped_shadow_rect != last_shadow_rect_) |
118 | 749 | { | ||
119 | 719 | auto const& win_region = win_->region(); | 750 | auto const& win_region = win_->region(); |
120 | 720 | quad->region = CompRegion(quad->box) - win_region; | 751 | quad->region = CompRegion(quad->box) - win_region; |
121 | 721 | 752 | ||
122 | 722 | last_shadow_rect_ = shaped_shadow_rect; | 753 | last_shadow_rect_ = shaped_shadow_rect; |
123 | 723 | win_->updateWindowOutputExtents(); | 754 | win_->updateWindowOutputExtents(); |
124 | 724 | } | 755 | } |
125 | 725 | cwin_->addDamage(true); | ||
126 | 726 | } | 756 | } |
127 | 727 | 757 | ||
128 | 728 | void Window::Impl::Paint(GLMatrix const& transformation, | 758 | void Window::Impl::Paint(GLMatrix const& transformation, |
129 | @@ -763,11 +793,7 @@ | |||
130 | 763 | 793 | ||
131 | 764 | glwin_->vertexBuffer()->begin(); | 794 | glwin_->vertexBuffer()->begin(); |
132 | 765 | 795 | ||
138 | 766 | // numRects is != 1 when the window is shaped | 796 | unsigned int num_quads = IsRectangular() ? shadow_quads_.size() : 1; |
134 | 767 | unsigned int num_quads = shadow_quads_.size(); | ||
135 | 768 | if (win_->region().numRects() != 1) | ||
136 | 769 | num_quads = 1; | ||
137 | 770 | |||
139 | 771 | for (unsigned int i = 0; i < num_quads; ++i) | 797 | for (unsigned int i = 0; i < num_quads; ++i) |
140 | 772 | { | 798 | { |
141 | 773 | auto& quad = shadow_quads_[Quads::Pos(i)]; | 799 | auto& quad = shadow_quads_[Quads::Pos(i)]; |
142 | @@ -775,7 +801,10 @@ | |||
143 | 775 | } | 801 | } |
144 | 776 | 802 | ||
145 | 777 | if (glwin_->vertexBuffer()->end()) | 803 | if (glwin_->vertexBuffer()->end()) |
147 | 778 | glwin_->glDrawTexture(ShadowTexture(), transformation, attrib, mask); | 804 | { |
148 | 805 | if (GLTexture* texture = ShadowTexture()) | ||
149 | 806 | glwin_->glDrawTexture(texture, transformation, attrib, mask); | ||
150 | 807 | } | ||
151 | 779 | 808 | ||
152 | 780 | for (auto const& dtex : bg_textures_) | 809 | for (auto const& dtex : bg_textures_) |
153 | 781 | { | 810 | { |
154 | @@ -800,6 +829,9 @@ | |||
155 | 800 | 829 | ||
156 | 801 | void Window::Impl::RedrawDecorations() | 830 | void Window::Impl::RedrawDecorations() |
157 | 802 | { | 831 | { |
158 | 832 | if (!win_->isMapped()) | ||
159 | 833 | return; | ||
160 | 834 | |||
161 | 803 | dirty_geo_ = true; | 835 | dirty_geo_ = true; |
162 | 804 | cwin_->damageOutputExtents(); | 836 | cwin_->damageOutputExtents(); |
163 | 805 | } | 837 | } |
164 | @@ -1003,10 +1035,7 @@ | |||
165 | 1003 | void Window::UpdateDecorationPosition() | 1035 | void Window::UpdateDecorationPosition() |
166 | 1004 | { | 1036 | { |
167 | 1005 | impl_->UpdateMonitor(); | 1037 | impl_->UpdateMonitor(); |
172 | 1006 | if (impl_->win_->region().numRects() > 1) | 1038 | impl_->IsRectangular() ? impl_->ComputeShadowQuads() : impl_->ComputeShapedShadowQuad(); |
169 | 1007 | impl_->ComputeShapedShadowQuad(); | ||
170 | 1008 | else | ||
171 | 1009 | impl_->ComputeShadowQuads(); | ||
173 | 1010 | impl_->UpdateWindowEdgesGeo(); | 1039 | impl_->UpdateWindowEdgesGeo(); |
174 | 1011 | impl_->UpdateDecorationTextures(); | 1040 | impl_->UpdateDecorationTextures(); |
175 | 1012 | impl_->UpdateForceQuitDialogPosition(); | 1041 | impl_->UpdateForceQuitDialogPosition(); |
176 | 1013 | 1042 | ||
177 | === modified file 'decorations/DecoratedWindow.h' | |||
178 | --- decorations/DecoratedWindow.h 2015-08-07 18:54:07 +0000 | |||
179 | +++ decorations/DecoratedWindow.h 2016-07-27 10:19:13 +0000 | |||
180 | @@ -21,6 +21,7 @@ | |||
181 | 21 | #define UNITY_DECORATED_WINDOW | 21 | #define UNITY_DECORATED_WINDOW |
182 | 22 | 22 | ||
183 | 23 | #include "Introspectable.h" | 23 | #include "Introspectable.h" |
184 | 24 | #include <NuxCore/Property.h> | ||
185 | 24 | #include <memory> | 25 | #include <memory> |
186 | 25 | 26 | ||
187 | 26 | class CompRegion; | 27 | class CompRegion; |
188 | 27 | 28 | ||
189 | === modified file 'decorations/DecorationsManager.cpp' | |||
190 | --- decorations/DecorationsManager.cpp 2016-07-27 10:19:12 +0000 | |||
191 | +++ decorations/DecorationsManager.cpp 2016-07-27 10:19:13 +0000 | |||
192 | @@ -20,10 +20,8 @@ | |||
193 | 20 | #include "DecorationsPriv.h" | 20 | #include "DecorationsPriv.h" |
194 | 21 | 21 | ||
195 | 22 | #include <core/atoms.h> | 22 | #include <core/atoms.h> |
196 | 23 | #include <NuxGraphics/CairoGraphics.h> | ||
197 | 24 | #include <UnityCore/DBusIndicators.h> | 23 | #include <UnityCore/DBusIndicators.h> |
198 | 25 | #include <X11/Xatom.h> | 24 | #include <X11/Xatom.h> |
199 | 26 | #include <X11/extensions/shape.h> | ||
200 | 27 | 25 | ||
201 | 28 | #include "WindowManager.h" | 26 | #include "WindowManager.h" |
202 | 29 | 27 | ||
203 | @@ -82,31 +80,6 @@ | |||
204 | 82 | return shadow_ctx; | 80 | return shadow_ctx; |
205 | 83 | } | 81 | } |
206 | 84 | 82 | ||
207 | 85 | cu::PixmapTexture::Ptr Manager::Impl::BuildShapedShadowTexture(unsigned int radius, nux::Color const& color, DecorationsShape const& shape) { | ||
208 | 86 | //Ideally it would be shape.getWidth + radius * 2 but Cairographics::BlurSurface isn't bounded by the radius | ||
209 | 87 | //and we need to compensate by using a larger texture. Make sure to modify Window::Impl::ComputeShapedShadowQuad in | ||
210 | 88 | //DecoratedWindow.cpp if you change the factor. | ||
211 | 89 | int blur_margin_factor = 2; | ||
212 | 90 | int img_width = shape.getWidth() + radius * 2 * blur_margin_factor; | ||
213 | 91 | int img_height = shape.getHeight() + radius * 2 * blur_margin_factor; | ||
214 | 92 | nux::CairoGraphics img(CAIRO_FORMAT_ARGB32, img_width, img_height); | ||
215 | 93 | auto* img_ctx = img.GetInternalContext(); | ||
216 | 94 | |||
217 | 95 | for (int i=0; i<shape.getRectangleCount(); i++) { | ||
218 | 96 | XRectangle rect = shape.getRectangle(i); | ||
219 | 97 | cairo_rectangle(img_ctx, rect.x + radius * blur_margin_factor - shape.getXoffs(), rect.y + radius * blur_margin_factor - shape.getYoffs(), rect.width, rect.height); | ||
220 | 98 | cairo_set_source_rgba(img_ctx, color.red, color.green, color.blue, color.alpha); | ||
221 | 99 | cairo_fill(img_ctx); | ||
222 | 100 | } | ||
223 | 101 | img.BlurSurface(radius); | ||
224 | 102 | |||
225 | 103 | cu::CairoContext shadow_ctx(img_width, img_height); | ||
226 | 104 | cairo_set_source_surface(shadow_ctx, img.GetSurface(), 0, 0); | ||
227 | 105 | cairo_paint(shadow_ctx); | ||
228 | 106 | |||
229 | 107 | return shadow_ctx; | ||
230 | 108 | } | ||
231 | 109 | |||
232 | 110 | void Manager::Impl::BuildActiveShadowTexture() | 83 | void Manager::Impl::BuildActiveShadowTexture() |
233 | 111 | { | 84 | { |
234 | 112 | active_shadow_pixmap_ = BuildShadowTexture(manager_->active_shadow_radius(), manager_->active_shadow_color()); | 85 | active_shadow_pixmap_ = BuildShadowTexture(manager_->active_shadow_radius(), manager_->active_shadow_color()); |
235 | 113 | 86 | ||
236 | === modified file 'decorations/DecorationsPriv.h' | |||
237 | --- decorations/DecorationsPriv.h 2016-07-27 10:19:12 +0000 | |||
238 | +++ decorations/DecorationsPriv.h 2016-07-27 10:19:13 +0000 | |||
239 | @@ -23,11 +23,13 @@ | |||
240 | 23 | #include <unordered_map> | 23 | #include <unordered_map> |
241 | 24 | #include <NuxCore/NuxCore.h> | 24 | #include <NuxCore/NuxCore.h> |
242 | 25 | #include <NuxCore/Rect.h> | 25 | #include <NuxCore/Rect.h> |
243 | 26 | #include <NuxGraphics/CairoGraphics.h> | ||
244 | 26 | #include <UnityCore/ConnectionManager.h> | 27 | #include <UnityCore/ConnectionManager.h> |
245 | 27 | #include <UnityCore/Indicators.h> | 28 | #include <UnityCore/Indicators.h> |
246 | 28 | #include <core/core.h> | 29 | #include <core/core.h> |
247 | 29 | #include <opengl/opengl.h> | 30 | #include <opengl/opengl.h> |
248 | 30 | #include <composite/composite.h> | 31 | #include <composite/composite.h> |
249 | 32 | #include <X11/extensions/shape.h> | ||
250 | 31 | 33 | ||
251 | 32 | #include "DecorationsShape.h" | 34 | #include "DecorationsShape.h" |
252 | 33 | #include "DecorationsDataPool.h" | 35 | #include "DecorationsDataPool.h" |
253 | @@ -116,6 +118,7 @@ | |||
254 | 116 | void SyncXShapeWithFrameRegion(); | 118 | void SyncXShapeWithFrameRegion(); |
255 | 117 | void SyncMenusGeometries() const; | 119 | void SyncMenusGeometries() const; |
256 | 118 | bool ShouldBeDecorated() const; | 120 | bool ShouldBeDecorated() const; |
257 | 121 | bool IsRectangular() const; | ||
258 | 119 | GLTexture* ShadowTexture() const; | 122 | GLTexture* ShadowTexture() const; |
259 | 120 | unsigned ShadowRadius() const; | 123 | unsigned ShadowRadius() const; |
260 | 121 | std::string const& GetMenusPanelID() const; | 124 | std::string const& GetMenusPanelID() const; |
261 | @@ -126,6 +129,7 @@ | |||
262 | 126 | void UpdateWindowEdgesGeo(); | 129 | void UpdateWindowEdgesGeo(); |
263 | 127 | void UpdateForceQuitDialogPosition(); | 130 | void UpdateForceQuitDialogPosition(); |
264 | 128 | void RenderDecorationTexture(Side, nux::Geometry const&); | 131 | void RenderDecorationTexture(Side, nux::Geometry const&); |
265 | 132 | cu::PixmapTexture::Ptr BuildShapedShadowTexture(nux::Size const&, unsigned radius, nux::Color const&, Shape const&); | ||
266 | 129 | void Paint(GLMatrix const&, GLWindowPaintAttrib const&, CompRegion const&, unsigned mask); | 133 | void Paint(GLMatrix const&, GLWindowPaintAttrib const&, CompRegion const&, unsigned mask); |
267 | 130 | void Draw(GLMatrix const&, GLWindowPaintAttrib const&, CompRegion const&, unsigned mask); | 134 | void Draw(GLMatrix const&, GLWindowPaintAttrib const&, CompRegion const&, unsigned mask); |
268 | 131 | 135 | ||
269 | @@ -156,6 +160,7 @@ | |||
270 | 156 | std::string last_title_; | 160 | std::string last_title_; |
271 | 157 | std::string panel_id_; | 161 | std::string panel_id_; |
272 | 158 | std::vector<cu::SimpleTextureQuad> bg_textures_; | 162 | std::vector<cu::SimpleTextureQuad> bg_textures_; |
273 | 163 | cu::PixmapTexture::Ptr shaped_shadow_pixmap_; | ||
274 | 159 | std::shared_ptr<ForceQuitDialog> force_quit_; | 164 | std::shared_ptr<ForceQuitDialog> force_quit_; |
275 | 160 | InputMixer::Ptr input_mixer_; | 165 | InputMixer::Ptr input_mixer_; |
276 | 161 | Layout::Ptr top_layout_; | 166 | Layout::Ptr top_layout_; |
277 | @@ -166,8 +171,6 @@ | |||
278 | 166 | Item::Ptr edge_borders_; | 171 | Item::Ptr edge_borders_; |
279 | 167 | 172 | ||
280 | 168 | EMConverter::Ptr cv_; | 173 | EMConverter::Ptr cv_; |
281 | 169 | |||
282 | 170 | cu::PixmapTexture::Ptr shaped_shadow_pixmap_; | ||
283 | 171 | }; | 174 | }; |
284 | 172 | 175 | ||
285 | 173 | struct Manager::Impl : sigc::trackable | 176 | struct Manager::Impl : sigc::trackable |
286 | @@ -192,7 +195,6 @@ | |||
287 | 192 | void BuildActiveShadowTexture(); | 195 | void BuildActiveShadowTexture(); |
288 | 193 | void BuildInactiveShadowTexture(); | 196 | void BuildInactiveShadowTexture(); |
289 | 194 | cu::PixmapTexture::Ptr BuildShadowTexture(unsigned radius, nux::Color const&); | 197 | cu::PixmapTexture::Ptr BuildShadowTexture(unsigned radius, nux::Color const&); |
290 | 195 | cu::PixmapTexture::Ptr BuildShapedShadowTexture(unsigned int radius, nux::Color const& color, DecorationsShape const& shape); | ||
291 | 196 | void OnShadowOptionsChanged(bool active); | 198 | void OnShadowOptionsChanged(bool active); |
292 | 197 | void OnWindowFrameChanged(bool, ::Window, std::weak_ptr<decoration::Window> const&); | 199 | void OnWindowFrameChanged(bool, ::Window, std::weak_ptr<decoration::Window> const&); |
293 | 198 | bool OnMenuKeyActivated(std::string const&); | 200 | bool OnMenuKeyActivated(std::string const&); |
294 | 199 | 201 | ||
295 | === modified file 'decorations/DecorationsShape.cpp' | |||
296 | --- decorations/DecorationsShape.cpp 2016-07-27 10:19:12 +0000 | |||
297 | +++ decorations/DecorationsShape.cpp 2016-07-27 10:19:13 +0000 | |||
298 | @@ -17,86 +17,91 @@ | |||
299 | 17 | * Authored by: Eleni Maria Stea <elenimaria.stea@canonical.com> | 17 | * Authored by: Eleni Maria Stea <elenimaria.stea@canonical.com> |
300 | 18 | */ | 18 | */ |
301 | 19 | 19 | ||
303 | 20 | #include <string.h> | 20 | #include "DecorationsShape.h" |
304 | 21 | |||
305 | 22 | #include <core/core.h> | ||
306 | 23 | #include <NuxCore/Logger.h> | ||
307 | 21 | #include <X11/extensions/shape.h> | 24 | #include <X11/extensions/shape.h> |
312 | 22 | #include "DecoratedWindow.h" | 25 | |
313 | 23 | #include "DecorationsShape.h" | 26 | namespace unity |
314 | 24 | 27 | { | |
315 | 25 | bool DecorationsShape::initShape(XID win) | 28 | namespace decoration |
316 | 29 | { | ||
317 | 30 | namespace | ||
318 | 31 | { | ||
319 | 32 | DECLARE_LOGGER(logger, "unity.decoration.shape"); | ||
320 | 33 | } | ||
321 | 34 | |||
322 | 35 | Shape::Shape(Window xid) | ||
323 | 26 | { | 36 | { |
324 | 27 | Bool buse, cuse; | 37 | Bool buse, cuse; |
325 | 28 | int bx, by, cx, cy; | 38 | int bx, by, cx, cy; |
326 | 29 | unsigned int bw, bh, cw, ch; | 39 | unsigned int bw, bh, cw, ch; |
327 | 30 | Display *dpy = screen->dpy(); | 40 | Display *dpy = screen->dpy(); |
328 | 31 | 41 | ||
330 | 32 | XShapeQueryExtents(dpy, win, &buse, &bx, &by, &bw, &bh, &cuse, &cx, &cy, &cw, &ch); | 42 | XShapeQueryExtents(dpy, xid, &buse, &bx, &by, &bw, &bh, &cuse, &cx, &cy, &cw, &ch); |
331 | 33 | 43 | ||
332 | 34 | int kind; | 44 | int kind; |
338 | 35 | if (buse) { | 45 | |
339 | 36 | width = bw; | 46 | if (buse) |
340 | 37 | height = bh; | 47 | { |
341 | 38 | xoffs = bx; | 48 | width_ = bw; |
342 | 39 | yoffs = by; | 49 | height_ = bh; |
343 | 50 | xoffs_ = bx; | ||
344 | 51 | yoffs_ = by; | ||
345 | 40 | kind = ShapeBounding; | 52 | kind = ShapeBounding; |
346 | 41 | } | 53 | } |
352 | 42 | else if (cuse) { | 54 | else if (cuse) |
353 | 43 | width = cw; | 55 | { |
354 | 44 | height = ch; | 56 | width_ = cw; |
355 | 45 | xoffs = cx; | 57 | height_ = ch; |
356 | 46 | yoffs = cy; | 58 | xoffs_ = cx; |
357 | 59 | yoffs_ = cy; | ||
358 | 47 | kind = ShapeClip; | 60 | kind = ShapeClip; |
359 | 48 | } | 61 | } |
363 | 49 | else { | 62 | else |
364 | 50 | fprintf(stderr, "XShapeQueryExtend returned no extends.\n"); | 63 | { |
365 | 51 | return false; | 64 | LOG_ERROR(logger) << "XShapeQueryExtend returned no extents"; |
366 | 65 | return; | ||
367 | 52 | } | 66 | } |
368 | 53 | 67 | ||
369 | 54 | int rect_count, rect_order; | 68 | int rect_count, rect_order; |
418 | 55 | XRectangle *rectangles; | 69 | std::unique_ptr<XRectangle[], int(*)(void*)> rectangles(XShapeGetRectangles(dpy, xid, kind, &rect_count, &rect_order), XFree); |
419 | 56 | if (!(rectangles = XShapeGetRectangles(dpy, win, kind, &rect_count, &rect_order))) { | 70 | |
420 | 57 | fprintf(stderr, "Failed to get shape rectangles\n"); | 71 | if (!rectangles) |
421 | 58 | return false; | 72 | { |
422 | 59 | } | 73 | LOG_ERROR(logger) << "Failed to get shape rectangles"; |
423 | 60 | 74 | return; | |
424 | 61 | for (int i=0; i< rect_count; i++) { | 75 | } |
425 | 62 | rects.push_back(rectangles[i]); | 76 | |
426 | 63 | } | 77 | for (int i = 0; i < rect_count; ++i) |
427 | 64 | 78 | rectangles_.push_back(rectangles[i]); | |
428 | 65 | XFree(rectangles); | 79 | } |
429 | 66 | return true; | 80 | |
430 | 67 | } | 81 | std::vector<XRectangle> const& Shape::GetRectangles() const |
431 | 68 | 82 | { | |
432 | 69 | const XRectangle& DecorationsShape::getRectangle(int idx) const | 83 | return rectangles_; |
433 | 70 | { | 84 | } |
434 | 71 | return rects[idx]; | 85 | |
435 | 72 | } | 86 | int Shape::Width() const |
436 | 73 | 87 | { | |
437 | 74 | int DecorationsShape::getRectangleCount() const | 88 | return width_; |
438 | 75 | { | 89 | } |
439 | 76 | return (int)rects.size(); | 90 | |
440 | 77 | } | 91 | int Shape::Height() const |
441 | 78 | 92 | { | |
442 | 79 | int DecorationsShape::getWidth() const | 93 | return height_; |
443 | 80 | { | 94 | } |
444 | 81 | return width; | 95 | |
445 | 82 | } | 96 | int Shape::XOffset() const |
446 | 83 | 97 | { | |
447 | 84 | int DecorationsShape::getHeight() const | 98 | return xoffs_; |
448 | 85 | { | 99 | } |
449 | 86 | return height; | 100 | |
450 | 87 | } | 101 | int Shape::YOffset() const |
451 | 88 | 102 | { | |
452 | 89 | int DecorationsShape::getXoffs() const | 103 | return yoffs_; |
453 | 90 | { | 104 | } |
454 | 91 | return xoffs; | 105 | |
455 | 92 | } | 106 | } // decoration namespace |
456 | 93 | 107 | } // unity namespace | |
409 | 94 | int DecorationsShape::getYoffs() const | ||
410 | 95 | { | ||
411 | 96 | return yoffs; | ||
412 | 97 | } | ||
413 | 98 | void DecorationsShape::clear() | ||
414 | 99 | { | ||
415 | 100 | width = height = 0; | ||
416 | 101 | rects.clear(); | ||
417 | 102 | } | ||
457 | 103 | 108 | ||
458 | === modified file 'decorations/DecorationsShape.h' | |||
459 | --- decorations/DecorationsShape.h 2016-07-27 10:19:12 +0000 | |||
460 | +++ decorations/DecorationsShape.h 2016-07-27 10:19:13 +0000 | |||
461 | @@ -20,24 +20,35 @@ | |||
462 | 20 | #ifndef DECORATIONS_SHAPE_H_ | 20 | #ifndef DECORATIONS_SHAPE_H_ |
463 | 21 | #define DECORATIONS_SHAPE_H_ | 21 | #define DECORATIONS_SHAPE_H_ |
464 | 22 | 22 | ||
470 | 23 | #include "WindowManager.h" | 23 | #include <X11/Xlib.h> |
471 | 24 | #include "DecoratedWindow.h" | 24 | #include <vector> |
472 | 25 | 25 | ||
473 | 26 | class DecorationsShape | 26 | namespace unity |
474 | 27 | { | 27 | { |
475 | 28 | namespace decoration | ||
476 | 29 | { | ||
477 | 30 | class Shape | ||
478 | 31 | { | ||
479 | 32 | public: | ||
480 | 33 | Shape(Window); | ||
481 | 34 | |||
482 | 35 | int Width() const; | ||
483 | 36 | int Height() const; | ||
484 | 37 | int XOffset() const; | ||
485 | 38 | int YOffset() const; | ||
486 | 39 | |||
487 | 40 | std::vector<XRectangle> const& GetRectangles() const; | ||
488 | 41 | |||
489 | 28 | private: | 42 | private: |
493 | 29 | std::vector<XRectangle> rects; | 43 | int width_; |
494 | 30 | int width, height; | 44 | int height_; |
495 | 31 | int xoffs, yoffs; | 45 | int xoffs_; |
496 | 46 | int yoffs_; | ||
497 | 32 | 47 | ||
507 | 33 | public: | 48 | std::vector<XRectangle> rectangles_; |
499 | 34 | bool initShape(XID win); | ||
500 | 35 | const XRectangle& getRectangle(int idx) const; | ||
501 | 36 | int getRectangleCount() const; | ||
502 | 37 | int getWidth() const; | ||
503 | 38 | int getHeight() const; | ||
504 | 39 | int getXoffs() const; | ||
505 | 40 | int getYoffs() const; | ||
506 | 41 | void clear(); | ||
508 | 42 | }; | 49 | }; |
509 | 50 | |||
510 | 51 | } // decoration namespace | ||
511 | 52 | } // unity namespace | ||
512 | 53 | |||
513 | 43 | #endif //DECORATIONS_SHAPE_H_ | 54 | #endif //DECORATIONS_SHAPE_H_ |
514 | 44 | 55 | ||
515 | === modified file 'plugins/unityshell/src/unityshell.cpp' | |||
516 | --- plugins/unityshell/src/unityshell.cpp 2016-07-27 10:19:12 +0000 | |||
517 | +++ plugins/unityshell/src/unityshell.cpp 2016-07-27 10:19:13 +0000 | |||
518 | @@ -3357,6 +3357,7 @@ | |||
519 | 3357 | PluginAdapter::Default().UpdateShowDesktopState(); | 3357 | PluginAdapter::Default().UpdateShowDesktopState(); |
520 | 3358 | break; | 3358 | break; |
521 | 3359 | case CompWindowNotifyBeforeDestroy: | 3359 | case CompWindowNotifyBeforeDestroy: |
522 | 3360 | deco_win_->Undecorate(); | ||
523 | 3360 | being_destroyed.emit(); | 3361 | being_destroyed.emit(); |
524 | 3361 | break; | 3362 | break; |
525 | 3362 | case CompWindowNotifyMinimize: | 3363 | case CompWindowNotifyMinimize: |
526 | 3363 | 3364 | ||
527 | === modified file 'unity-shared/CompizUtils.cpp' | |||
528 | --- unity-shared/CompizUtils.cpp 2016-07-27 10:19:12 +0000 | |||
529 | +++ unity-shared/CompizUtils.cpp 2016-07-27 10:19:13 +0000 | |||
530 | @@ -190,11 +190,7 @@ | |||
531 | 190 | if (win->wmType() & (CompWindowTypeDockMask | CompWindowTypeDesktopMask)) | 190 | if (win->wmType() & (CompWindowTypeDockMask | CompWindowTypeDesktopMask)) |
532 | 191 | return elements; | 191 | return elements; |
533 | 192 | 192 | ||
539 | 193 | auto const& region = win->region(); | 193 | if (win->alpha()) |
535 | 194 | bool rectangular = (region.numRects() == 1); | ||
536 | 195 | bool alpha = win->alpha(); | ||
537 | 196 | |||
538 | 197 | if (alpha) | ||
540 | 198 | { | 194 | { |
541 | 199 | if (wf == WindowFilter::CLIENTSIDE_DECORATED) | 195 | if (wf == WindowFilter::CLIENTSIDE_DECORATED) |
542 | 200 | { | 196 | { |
543 | @@ -205,7 +201,7 @@ | |||
544 | 205 | 201 | ||
545 | 206 | return elements; | 202 | return elements; |
546 | 207 | } | 203 | } |
548 | 208 | else if (!rectangular) // Non-rectangular windows with alpha channel | 204 | else if (win->region().numRects() != 1) // Non-rectangular windows with alpha channel |
549 | 209 | { | 205 | { |
550 | 210 | return elements; | 206 | return elements; |
551 | 211 | } | 207 | } |
552 | @@ -220,11 +216,14 @@ | |||
553 | 220 | if (win->actions() & CompWindowActionResizeMask) | 216 | if (win->actions() & CompWindowActionResizeMask) |
554 | 221 | elements |= DecorationElement::EDGE; | 217 | elements |= DecorationElement::EDGE; |
555 | 222 | 218 | ||
556 | 219 | auto const& region = win->region(); | ||
557 | 220 | bool rectangular = (region.numRects() == 1); | ||
558 | 221 | |||
559 | 223 | if (rectangular && (win->mwmDecor() & (MwmDecorAll | MwmDecorTitle))) | 222 | if (rectangular && (win->mwmDecor() & (MwmDecorAll | MwmDecorTitle))) |
560 | 224 | elements |= DecorationElement::BORDER; | 223 | elements |= DecorationElement::BORDER; |
561 | 225 | } | 224 | } |
562 | 226 | 225 | ||
564 | 227 | if (alpha && !(elements & DecorationElement::BORDER) && !(win->mwmDecor() & MwmDecorBorder)) | 226 | if (win->alpha() && !(elements & DecorationElement::BORDER) && !(win->mwmDecor() & MwmDecorBorder)) |
565 | 228 | elements &= ~DecorationElement::SHADOW; | 227 | elements &= ~DecorationElement::SHADOW; |
566 | 229 | 228 | ||
567 | 230 | return elements; | 229 | return elements; |
The changes to the prerequiste make sense to me.