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 | #include "WindowManager.h" |
6 | #include "UnitySettings.h" |
7 | |
8 | -#include <X11/extensions/shape.h> |
9 | - |
10 | namespace unity |
11 | { |
12 | namespace decoration |
13 | @@ -40,6 +38,7 @@ |
14 | namespace |
15 | { |
16 | const std::string MENUS_PANEL_NAME = "WindowLIM"; |
17 | +const int SHADOW_BLUR_MARGIN_FACTOR = 2; |
18 | } |
19 | |
20 | Window::Impl::Impl(Window* parent, CompWindow* win) |
21 | @@ -504,13 +503,21 @@ |
22 | return (win_->frame() || win_->hasUnmapReference()) && FullyDecorated(); |
23 | } |
24 | |
25 | +bool Window::Impl::IsRectangular() const |
26 | +{ |
27 | + return win_->region().numRects() == 1; |
28 | +} |
29 | + |
30 | GLTexture* Window::Impl::ShadowTexture() const |
31 | { |
32 | + if (!IsRectangular()) |
33 | + return shaped_shadow_pixmap_->texture(); |
34 | + |
35 | auto const& mi = manager_->impl_; |
36 | if (active() || parent_->scaled()) |
37 | - return win_->region().numRects() > 1 ? shaped_shadow_pixmap_->texture() : mi->active_shadow_pixmap_->texture(); |
38 | + return mi->active_shadow_pixmap_->texture(); |
39 | |
40 | - return win_->region().numRects() > 1 ? shaped_shadow_pixmap_->texture() : mi->inactive_shadow_pixmap_->texture(); |
41 | + return mi->inactive_shadow_pixmap_->texture(); |
42 | } |
43 | |
44 | unsigned Window::Impl::ShadowRadius() const |
45 | @@ -678,6 +685,26 @@ |
46 | } |
47 | } |
48 | |
49 | +cu::PixmapTexture::Ptr Window::Impl::BuildShapedShadowTexture(nux::Size const& size, unsigned radius, nux::Color const& color, Shape const& shape) { |
50 | + nux::CairoGraphics img(CAIRO_FORMAT_ARGB32, size.width, size.height); |
51 | + auto* img_ctx = img.GetInternalContext(); |
52 | + |
53 | + for (auto const& rect : shape.GetRectangles()) |
54 | + { |
55 | + 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 | + cairo_set_source_rgba(img_ctx, color.red, color.green, color.blue, color.alpha); |
57 | + cairo_fill(img_ctx); |
58 | + } |
59 | + |
60 | + img.BlurSurface(radius); |
61 | + |
62 | + cu::CairoContext shadow_ctx(size.width, size.height); |
63 | + cairo_set_source_surface(shadow_ctx, img.GetSurface(), 0, 0); |
64 | + cairo_paint(shadow_ctx); |
65 | + |
66 | + return shadow_ctx; |
67 | +} |
68 | + |
69 | void Window::Impl::ComputeShapedShadowQuad() |
70 | { |
71 | if (!(deco_elements_ & cu::DecorationElement::SHADOW)) |
72 | @@ -690,23 +717,26 @@ |
73 | |
74 | nux::Color color = active() ? manager_->active_shadow_color() : manager_->inactive_shadow_color(); |
75 | unsigned int radius = active() ? manager_->active_shadow_radius() : manager_->inactive_shadow_radius(); |
76 | - DecorationsShape shape; |
77 | - shape.initShape(win_->id()); |
78 | - shaped_shadow_pixmap_ = manager_->impl_->BuildShapedShadowTexture(radius, color, shape); |
79 | - |
80 | - const auto* texture = ShadowTexture(); |
81 | + |
82 | + Shape shape(win_->id()); |
83 | + auto const& border = win_->borderRect(); |
84 | + auto const& shadow_offset = manager_->shadow_offset(); |
85 | + |
86 | + // Ideally it would be shape.getWidth + radius * 2 but Cairographics::BlurSurface |
87 | + // isn't bounded by the radius and we need to compensate by using a larger texture. |
88 | + int width = shape.Width() + radius * 2 * SHADOW_BLUR_MARGIN_FACTOR; |
89 | + int height = shape.Height() + radius * 2 * SHADOW_BLUR_MARGIN_FACTOR; |
90 | + |
91 | + if (width != last_shadow_rect_.width() || height != last_shadow_rect_.height()) |
92 | + shaped_shadow_pixmap_ = BuildShapedShadowTexture({width, height}, radius, color, shape); |
93 | + |
94 | + const auto* texture = shaped_shadow_pixmap_->texture(); |
95 | |
96 | if (!texture || !texture->width() || !texture->height()) |
97 | return; |
98 | |
99 | - CompRect border = win_->borderRect(); |
100 | - nux::Point2D<int> shadow_offset = manager_->shadow_offset(); |
101 | -// ideally it would be -radius for the *2 part see comment in Manager::Impl::BuildShapedShadowTexture |
102 | -// in DecorationsManager.cpp Make sure to keep these factors in sync. |
103 | - int x = border.x() + shadow_offset.x - radius * 2 + shape.getXoffs(); |
104 | - int y = border.y() + shadow_offset.y - radius * 2 + shape.getYoffs(); |
105 | - int width = texture->width(); |
106 | - int height = texture->height(); |
107 | + int x = border.x() + shadow_offset.x - radius * 2 + shape.XOffset(); |
108 | + int y = border.y() + shadow_offset.y - radius * 2 + shape.YOffset(); |
109 | |
110 | auto* quad = &shadow_quads_[Quads::Pos(0)]; |
111 | quad->box.setGeometry(x, y, width, height); |
112 | @@ -715,14 +745,14 @@ |
113 | quad->matrix.y0 = -COMP_TEX_COORD_Y(quad->matrix, quad->box.y1()); |
114 | |
115 | CompRect shaped_shadow_rect(x, y, width, height); |
116 | - if (shaped_shadow_rect != last_shadow_rect_) { |
117 | + if (shaped_shadow_rect != last_shadow_rect_) |
118 | + { |
119 | auto const& win_region = win_->region(); |
120 | quad->region = CompRegion(quad->box) - win_region; |
121 | |
122 | last_shadow_rect_ = shaped_shadow_rect; |
123 | win_->updateWindowOutputExtents(); |
124 | } |
125 | - cwin_->addDamage(true); |
126 | } |
127 | |
128 | void Window::Impl::Paint(GLMatrix const& transformation, |
129 | @@ -763,11 +793,7 @@ |
130 | |
131 | glwin_->vertexBuffer()->begin(); |
132 | |
133 | - // numRects is != 1 when the window is shaped |
134 | - unsigned int num_quads = shadow_quads_.size(); |
135 | - if (win_->region().numRects() != 1) |
136 | - num_quads = 1; |
137 | - |
138 | + unsigned int num_quads = IsRectangular() ? shadow_quads_.size() : 1; |
139 | for (unsigned int i = 0; i < num_quads; ++i) |
140 | { |
141 | auto& quad = shadow_quads_[Quads::Pos(i)]; |
142 | @@ -775,7 +801,10 @@ |
143 | } |
144 | |
145 | if (glwin_->vertexBuffer()->end()) |
146 | - glwin_->glDrawTexture(ShadowTexture(), transformation, attrib, mask); |
147 | + { |
148 | + if (GLTexture* texture = ShadowTexture()) |
149 | + glwin_->glDrawTexture(texture, transformation, attrib, mask); |
150 | + } |
151 | |
152 | for (auto const& dtex : bg_textures_) |
153 | { |
154 | @@ -800,6 +829,9 @@ |
155 | |
156 | void Window::Impl::RedrawDecorations() |
157 | { |
158 | + if (!win_->isMapped()) |
159 | + return; |
160 | + |
161 | dirty_geo_ = true; |
162 | cwin_->damageOutputExtents(); |
163 | } |
164 | @@ -1003,10 +1035,7 @@ |
165 | void Window::UpdateDecorationPosition() |
166 | { |
167 | impl_->UpdateMonitor(); |
168 | - if (impl_->win_->region().numRects() > 1) |
169 | - impl_->ComputeShapedShadowQuad(); |
170 | - else |
171 | - impl_->ComputeShadowQuads(); |
172 | + impl_->IsRectangular() ? impl_->ComputeShadowQuads() : impl_->ComputeShapedShadowQuad(); |
173 | impl_->UpdateWindowEdgesGeo(); |
174 | impl_->UpdateDecorationTextures(); |
175 | impl_->UpdateForceQuitDialogPosition(); |
176 | |
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 | #define UNITY_DECORATED_WINDOW |
182 | |
183 | #include "Introspectable.h" |
184 | +#include <NuxCore/Property.h> |
185 | #include <memory> |
186 | |
187 | class CompRegion; |
188 | |
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 | #include "DecorationsPriv.h" |
194 | |
195 | #include <core/atoms.h> |
196 | -#include <NuxGraphics/CairoGraphics.h> |
197 | #include <UnityCore/DBusIndicators.h> |
198 | #include <X11/Xatom.h> |
199 | -#include <X11/extensions/shape.h> |
200 | |
201 | #include "WindowManager.h" |
202 | |
203 | @@ -82,31 +80,6 @@ |
204 | return shadow_ctx; |
205 | } |
206 | |
207 | -cu::PixmapTexture::Ptr Manager::Impl::BuildShapedShadowTexture(unsigned int radius, nux::Color const& color, DecorationsShape const& shape) { |
208 | - //Ideally it would be shape.getWidth + radius * 2 but Cairographics::BlurSurface isn't bounded by the radius |
209 | - //and we need to compensate by using a larger texture. Make sure to modify Window::Impl::ComputeShapedShadowQuad in |
210 | - //DecoratedWindow.cpp if you change the factor. |
211 | - int blur_margin_factor = 2; |
212 | - int img_width = shape.getWidth() + radius * 2 * blur_margin_factor; |
213 | - int img_height = shape.getHeight() + radius * 2 * blur_margin_factor; |
214 | - nux::CairoGraphics img(CAIRO_FORMAT_ARGB32, img_width, img_height); |
215 | - auto* img_ctx = img.GetInternalContext(); |
216 | - |
217 | - for (int i=0; i<shape.getRectangleCount(); i++) { |
218 | - XRectangle rect = shape.getRectangle(i); |
219 | - 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 | - cairo_set_source_rgba(img_ctx, color.red, color.green, color.blue, color.alpha); |
221 | - cairo_fill(img_ctx); |
222 | - } |
223 | - img.BlurSurface(radius); |
224 | - |
225 | - cu::CairoContext shadow_ctx(img_width, img_height); |
226 | - cairo_set_source_surface(shadow_ctx, img.GetSurface(), 0, 0); |
227 | - cairo_paint(shadow_ctx); |
228 | - |
229 | - return shadow_ctx; |
230 | -} |
231 | - |
232 | void Manager::Impl::BuildActiveShadowTexture() |
233 | { |
234 | active_shadow_pixmap_ = BuildShadowTexture(manager_->active_shadow_radius(), manager_->active_shadow_color()); |
235 | |
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 | #include <unordered_map> |
241 | #include <NuxCore/NuxCore.h> |
242 | #include <NuxCore/Rect.h> |
243 | +#include <NuxGraphics/CairoGraphics.h> |
244 | #include <UnityCore/ConnectionManager.h> |
245 | #include <UnityCore/Indicators.h> |
246 | #include <core/core.h> |
247 | #include <opengl/opengl.h> |
248 | #include <composite/composite.h> |
249 | +#include <X11/extensions/shape.h> |
250 | |
251 | #include "DecorationsShape.h" |
252 | #include "DecorationsDataPool.h" |
253 | @@ -116,6 +118,7 @@ |
254 | void SyncXShapeWithFrameRegion(); |
255 | void SyncMenusGeometries() const; |
256 | bool ShouldBeDecorated() const; |
257 | + bool IsRectangular() const; |
258 | GLTexture* ShadowTexture() const; |
259 | unsigned ShadowRadius() const; |
260 | std::string const& GetMenusPanelID() const; |
261 | @@ -126,6 +129,7 @@ |
262 | void UpdateWindowEdgesGeo(); |
263 | void UpdateForceQuitDialogPosition(); |
264 | void RenderDecorationTexture(Side, nux::Geometry const&); |
265 | + cu::PixmapTexture::Ptr BuildShapedShadowTexture(nux::Size const&, unsigned radius, nux::Color const&, Shape const&); |
266 | void Paint(GLMatrix const&, GLWindowPaintAttrib const&, CompRegion const&, unsigned mask); |
267 | void Draw(GLMatrix const&, GLWindowPaintAttrib const&, CompRegion const&, unsigned mask); |
268 | |
269 | @@ -156,6 +160,7 @@ |
270 | std::string last_title_; |
271 | std::string panel_id_; |
272 | std::vector<cu::SimpleTextureQuad> bg_textures_; |
273 | + cu::PixmapTexture::Ptr shaped_shadow_pixmap_; |
274 | std::shared_ptr<ForceQuitDialog> force_quit_; |
275 | InputMixer::Ptr input_mixer_; |
276 | Layout::Ptr top_layout_; |
277 | @@ -166,8 +171,6 @@ |
278 | Item::Ptr edge_borders_; |
279 | |
280 | EMConverter::Ptr cv_; |
281 | - |
282 | - cu::PixmapTexture::Ptr shaped_shadow_pixmap_; |
283 | }; |
284 | |
285 | struct Manager::Impl : sigc::trackable |
286 | @@ -192,7 +195,6 @@ |
287 | void BuildActiveShadowTexture(); |
288 | void BuildInactiveShadowTexture(); |
289 | cu::PixmapTexture::Ptr BuildShadowTexture(unsigned radius, nux::Color const&); |
290 | - cu::PixmapTexture::Ptr BuildShapedShadowTexture(unsigned int radius, nux::Color const& color, DecorationsShape const& shape); |
291 | void OnShadowOptionsChanged(bool active); |
292 | void OnWindowFrameChanged(bool, ::Window, std::weak_ptr<decoration::Window> const&); |
293 | bool OnMenuKeyActivated(std::string const&); |
294 | |
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 | * Authored by: Eleni Maria Stea <elenimaria.stea@canonical.com> |
300 | */ |
301 | |
302 | -#include <string.h> |
303 | +#include "DecorationsShape.h" |
304 | + |
305 | +#include <core/core.h> |
306 | +#include <NuxCore/Logger.h> |
307 | #include <X11/extensions/shape.h> |
308 | -#include "DecoratedWindow.h" |
309 | -#include "DecorationsShape.h" |
310 | - |
311 | -bool DecorationsShape::initShape(XID win) |
312 | + |
313 | +namespace unity |
314 | +{ |
315 | +namespace decoration |
316 | +{ |
317 | +namespace |
318 | +{ |
319 | +DECLARE_LOGGER(logger, "unity.decoration.shape"); |
320 | +} |
321 | + |
322 | +Shape::Shape(Window xid) |
323 | { |
324 | Bool buse, cuse; |
325 | int bx, by, cx, cy; |
326 | unsigned int bw, bh, cw, ch; |
327 | Display *dpy = screen->dpy(); |
328 | |
329 | - XShapeQueryExtents(dpy, win, &buse, &bx, &by, &bw, &bh, &cuse, &cx, &cy, &cw, &ch); |
330 | + XShapeQueryExtents(dpy, xid, &buse, &bx, &by, &bw, &bh, &cuse, &cx, &cy, &cw, &ch); |
331 | |
332 | int kind; |
333 | - if (buse) { |
334 | - width = bw; |
335 | - height = bh; |
336 | - xoffs = bx; |
337 | - yoffs = by; |
338 | + |
339 | + if (buse) |
340 | + { |
341 | + width_ = bw; |
342 | + height_ = bh; |
343 | + xoffs_ = bx; |
344 | + yoffs_ = by; |
345 | kind = ShapeBounding; |
346 | } |
347 | - else if (cuse) { |
348 | - width = cw; |
349 | - height = ch; |
350 | - xoffs = cx; |
351 | - yoffs = cy; |
352 | + else if (cuse) |
353 | + { |
354 | + width_ = cw; |
355 | + height_ = ch; |
356 | + xoffs_ = cx; |
357 | + yoffs_ = cy; |
358 | kind = ShapeClip; |
359 | } |
360 | - else { |
361 | - fprintf(stderr, "XShapeQueryExtend returned no extends.\n"); |
362 | - return false; |
363 | + else |
364 | + { |
365 | + LOG_ERROR(logger) << "XShapeQueryExtend returned no extents"; |
366 | + return; |
367 | } |
368 | |
369 | int rect_count, rect_order; |
370 | - XRectangle *rectangles; |
371 | - if (!(rectangles = XShapeGetRectangles(dpy, win, kind, &rect_count, &rect_order))) { |
372 | - fprintf(stderr, "Failed to get shape rectangles\n"); |
373 | - return false; |
374 | - } |
375 | - |
376 | - for (int i=0; i< rect_count; i++) { |
377 | - rects.push_back(rectangles[i]); |
378 | - } |
379 | - |
380 | - XFree(rectangles); |
381 | - return true; |
382 | -} |
383 | - |
384 | -const XRectangle& DecorationsShape::getRectangle(int idx) const |
385 | -{ |
386 | - return rects[idx]; |
387 | -} |
388 | - |
389 | -int DecorationsShape::getRectangleCount() const |
390 | -{ |
391 | - return (int)rects.size(); |
392 | -} |
393 | - |
394 | -int DecorationsShape::getWidth() const |
395 | -{ |
396 | - return width; |
397 | -} |
398 | - |
399 | -int DecorationsShape::getHeight() const |
400 | -{ |
401 | - return height; |
402 | -} |
403 | - |
404 | -int DecorationsShape::getXoffs() const |
405 | -{ |
406 | - return xoffs; |
407 | -} |
408 | - |
409 | -int DecorationsShape::getYoffs() const |
410 | -{ |
411 | - return yoffs; |
412 | -} |
413 | -void DecorationsShape::clear() |
414 | -{ |
415 | - width = height = 0; |
416 | - rects.clear(); |
417 | -} |
418 | + std::unique_ptr<XRectangle[], int(*)(void*)> rectangles(XShapeGetRectangles(dpy, xid, kind, &rect_count, &rect_order), XFree); |
419 | + |
420 | + if (!rectangles) |
421 | + { |
422 | + LOG_ERROR(logger) << "Failed to get shape rectangles"; |
423 | + return; |
424 | + } |
425 | + |
426 | + for (int i = 0; i < rect_count; ++i) |
427 | + rectangles_.push_back(rectangles[i]); |
428 | +} |
429 | + |
430 | +std::vector<XRectangle> const& Shape::GetRectangles() const |
431 | +{ |
432 | + return rectangles_; |
433 | +} |
434 | + |
435 | +int Shape::Width() const |
436 | +{ |
437 | + return width_; |
438 | +} |
439 | + |
440 | +int Shape::Height() const |
441 | +{ |
442 | + return height_; |
443 | +} |
444 | + |
445 | +int Shape::XOffset() const |
446 | +{ |
447 | + return xoffs_; |
448 | +} |
449 | + |
450 | +int Shape::YOffset() const |
451 | +{ |
452 | + return yoffs_; |
453 | +} |
454 | + |
455 | +} // decoration namespace |
456 | +} // unity namespace |
457 | |
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 | #ifndef DECORATIONS_SHAPE_H_ |
463 | #define DECORATIONS_SHAPE_H_ |
464 | |
465 | -#include "WindowManager.h" |
466 | -#include "DecoratedWindow.h" |
467 | - |
468 | -class DecorationsShape |
469 | -{ |
470 | +#include <X11/Xlib.h> |
471 | +#include <vector> |
472 | + |
473 | +namespace unity |
474 | +{ |
475 | +namespace decoration |
476 | +{ |
477 | +class Shape |
478 | +{ |
479 | +public: |
480 | + Shape(Window); |
481 | + |
482 | + int Width() const; |
483 | + int Height() const; |
484 | + int XOffset() const; |
485 | + int YOffset() const; |
486 | + |
487 | + std::vector<XRectangle> const& GetRectangles() const; |
488 | + |
489 | private: |
490 | - std::vector<XRectangle> rects; |
491 | - int width, height; |
492 | - int xoffs, yoffs; |
493 | + int width_; |
494 | + int height_; |
495 | + int xoffs_; |
496 | + int yoffs_; |
497 | |
498 | -public: |
499 | - bool initShape(XID win); |
500 | - const XRectangle& getRectangle(int idx) const; |
501 | - int getRectangleCount() const; |
502 | - int getWidth() const; |
503 | - int getHeight() const; |
504 | - int getXoffs() const; |
505 | - int getYoffs() const; |
506 | - void clear(); |
507 | + std::vector<XRectangle> rectangles_; |
508 | }; |
509 | + |
510 | +} // decoration namespace |
511 | +} // unity namespace |
512 | + |
513 | #endif //DECORATIONS_SHAPE_H_ |
514 | |
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 | PluginAdapter::Default().UpdateShowDesktopState(); |
520 | break; |
521 | case CompWindowNotifyBeforeDestroy: |
522 | + deco_win_->Undecorate(); |
523 | being_destroyed.emit(); |
524 | break; |
525 | case CompWindowNotifyMinimize: |
526 | |
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 | if (win->wmType() & (CompWindowTypeDockMask | CompWindowTypeDesktopMask)) |
532 | return elements; |
533 | |
534 | - auto const& region = win->region(); |
535 | - bool rectangular = (region.numRects() == 1); |
536 | - bool alpha = win->alpha(); |
537 | - |
538 | - if (alpha) |
539 | + if (win->alpha()) |
540 | { |
541 | if (wf == WindowFilter::CLIENTSIDE_DECORATED) |
542 | { |
543 | @@ -205,7 +201,7 @@ |
544 | |
545 | return elements; |
546 | } |
547 | - else if (!rectangular) // Non-rectangular windows with alpha channel |
548 | + else if (win->region().numRects() != 1) // Non-rectangular windows with alpha channel |
549 | { |
550 | return elements; |
551 | } |
552 | @@ -220,11 +216,14 @@ |
553 | if (win->actions() & CompWindowActionResizeMask) |
554 | elements |= DecorationElement::EDGE; |
555 | |
556 | + auto const& region = win->region(); |
557 | + bool rectangular = (region.numRects() == 1); |
558 | + |
559 | if (rectangular && (win->mwmDecor() & (MwmDecorAll | MwmDecorTitle))) |
560 | elements |= DecorationElement::BORDER; |
561 | } |
562 | |
563 | - if (alpha && !(elements & DecorationElement::BORDER) && !(win->mwmDecor() & MwmDecorBorder)) |
564 | + if (win->alpha() && !(elements & DecorationElement::BORDER) && !(win->mwmDecor() & MwmDecorBorder)) |
565 | elements &= ~DecorationElement::SHADOW; |
566 | |
567 | return elements; |
The changes to the prerequiste make sense to me.