Merge lp:~unity-team/unity/trusty-1276177 into lp:unity/7.2
- trusty-1276177
- Merge into trusty
Proposed by
Stephen M. Webb
Status: | Rejected |
---|---|
Rejected by: | Stephen M. Webb |
Proposed branch: | lp:~unity-team/unity/trusty-1276177 |
Merge into: | lp:unity/7.2 |
Diff against target: |
1021 lines (+341/-175) 13 files modified
debian/changelog (+8/-0) decorations/DecoratedWindow.cpp (+139/-64) decorations/DecorationsEdgeBorders.cpp (+32/-19) decorations/DecorationsForceQuitDialog.cpp (+17/-3) decorations/DecorationsManager.cpp (+16/-25) decorations/DecorationsPriv.h (+11/-3) decorations/DecorationsTitle.cpp (+1/-0) decorations/DecorationsWidgets.cpp (+13/-1) decorations/DecorationsWidgets.h (+5/-0) plugins/unityshell/src/unityshell.cpp (+1/-0) unity-shared/CompizUtils.cpp (+73/-54) unity-shared/CompizUtils.h (+24/-5) unity-shared/XWindowManager.cpp (+1/-1) |
To merge this branch: | bzr merge lp:~unity-team/unity/trusty-1276177 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Unity Team | Pending | ||
Review via email: mp+244065@code.launchpad.net |
This proposal supersedes a proposal from 2014-12-08.
Commit message
Description of the change
Fix edge decorations for windows with client-side decorations.
This change is cherry-picked from trunk for SRUing to Ubuntu 14.04 LTS.
To post a comment you must log in.
Unmerged revisions
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'debian/changelog' |
2 | --- debian/changelog 2014-08-26 13:49:00 +0000 |
3 | +++ debian/changelog 2014-12-08 22:42:16 +0000 |
4 | @@ -1,3 +1,11 @@ |
5 | +unity (7.2.3+14.04.20140826-0ubuntu2) UNRELEASED; urgency=medium |
6 | + |
7 | + * DecoratedWindow: make edges independent from borders and properly update |
8 | + them on actions change (lp: #1276177), (lp: #1299741), (lp: #1301776), |
9 | + (lp: #1324104), (lp: #1364225), (lp: #1373695) |
10 | + |
11 | + -- Marco Trevisan (TreviƱo) <mail@3v1n0.net> Mon, 08 Dec 2014 17:35:27 -0500 |
12 | + |
13 | unity (7.2.3+14.04.20140826-0ubuntu1) trusty; urgency=medium |
14 | |
15 | [ Andrea Azzarone ] |
16 | |
17 | === modified file 'decorations/DecoratedWindow.cpp' |
18 | --- decorations/DecoratedWindow.cpp 2014-04-02 12:26:14 +0000 |
19 | +++ decorations/DecoratedWindow.cpp 2014-12-08 22:42:16 +0000 |
20 | @@ -1,6 +1,6 @@ |
21 | // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- |
22 | /* |
23 | - * Copyright (C) 2013 Canonical Ltd |
24 | + * Copyright (C) 2013-2014 Canonical Ltd |
25 | * |
26 | * This program is free software: you can redistribute it and/or modify |
27 | * it under the terms of the GNU General Public License version 3 as |
28 | @@ -46,8 +46,12 @@ |
29 | , cwin_(CompositeWindow::get(win_)) |
30 | , glwin_(GLWindow::get(win_)) |
31 | , frame_(0) |
32 | + , monitor_(0) |
33 | , dirty_geo_(true) |
34 | - , monitor_(0) |
35 | + , dirty_frame_(false) |
36 | + , deco_elements_(cu::DecorationElement::NONE) |
37 | + , last_mwm_decor_(win_->mwmDecor()) |
38 | + , last_actions_(win_->actions()) |
39 | , cv_(Settings::Instance().em()) |
40 | { |
41 | active.changed.connect([this] (bool active) { |
42 | @@ -107,14 +111,27 @@ |
43 | |
44 | void Window::Impl::Update() |
45 | { |
46 | - ShouldBeDecorated() ? Decorate() : Undecorate(); |
47 | + UpdateElements(); |
48 | + (deco_elements_ & (cu::DecorationElement::EDGE | cu::DecorationElement::BORDER)) ? Decorate() : Undecorate(); |
49 | + last_mwm_decor_ = win_->mwmDecor(); |
50 | + last_actions_ = win_->actions(); |
51 | } |
52 | |
53 | void Window::Impl::Decorate() |
54 | { |
55 | SetupExtents(); |
56 | UpdateFrame(); |
57 | - SetupWindowControls(); |
58 | + SetupWindowEdges(); |
59 | + |
60 | + if (deco_elements_ & cu::DecorationElement::BORDER) |
61 | + { |
62 | + SetupWindowControls(); |
63 | + } |
64 | + else |
65 | + { |
66 | + CleanupWindowControls(); |
67 | + bg_textures_.clear(); |
68 | + } |
69 | } |
70 | |
71 | void Window::Impl::Undecorate() |
72 | @@ -122,6 +139,7 @@ |
73 | UnsetExtents(); |
74 | UnsetFrame(); |
75 | CleanupWindowControls(); |
76 | + CleanupWindowEdges(); |
77 | bg_textures_.clear(); |
78 | } |
79 | |
80 | @@ -141,17 +159,27 @@ |
81 | if (win_->hasUnmapReference()) |
82 | return; |
83 | |
84 | - auto const& sb = Style::Get()->Border(); |
85 | - CompWindowExtents border(cv_->CP(sb.left), |
86 | - cv_->CP(sb.right), |
87 | - cv_->CP(sb.top), |
88 | - cv_->CP(sb.bottom)); |
89 | - |
90 | - auto const& ib = Style::Get()->InputBorder(); |
91 | - CompWindowExtents input(cv_->CP(sb.left + ib.left), |
92 | - cv_->CP(sb.right + ib.right), |
93 | - cv_->CP(sb.top + ib.top), |
94 | - cv_->CP(sb.bottom + ib.bottom)); |
95 | + CompWindowExtents border; |
96 | + |
97 | + if (deco_elements_ & cu::DecorationElement::BORDER) |
98 | + { |
99 | + auto const& sb = Style::Get()->Border(); |
100 | + border.left = cv_->CP(sb.left); |
101 | + border.right = cv_->CP(sb.right); |
102 | + border.top = cv_->CP(sb.top); |
103 | + border.bottom = cv_->CP(sb.bottom); |
104 | + } |
105 | + |
106 | + CompWindowExtents input(border); |
107 | + |
108 | + if (deco_elements_ & cu::DecorationElement::EDGE) |
109 | + { |
110 | + auto const& ib = Style::Get()->InputBorder(); |
111 | + input.left += cv_->CP(ib.left); |
112 | + input.right += cv_->CP(ib.right); |
113 | + input.top += cv_->CP(ib.top); |
114 | + input.bottom += cv_->CP(ib.bottom); |
115 | + } |
116 | |
117 | if (win_->border() != border || win_->input() != input) |
118 | win_->setWindowFrameExtents(&border, &input); |
119 | @@ -185,6 +213,15 @@ |
120 | UpdateFrameGeo(frame_geo); |
121 | } |
122 | |
123 | +void Window::Impl::UpdateFrameActions() |
124 | +{ |
125 | + if (!dirty_frame_ && (win_->mwmDecor() != last_mwm_decor_ || win_->actions() != last_actions_)) |
126 | + { |
127 | + dirty_frame_ = true; |
128 | + Damage(); |
129 | + } |
130 | +} |
131 | + |
132 | void Window::Impl::CreateFrame(nux::Geometry const& frame_geo) |
133 | { |
134 | /* Since we're reparenting windows here, we need to grab the server |
135 | @@ -282,6 +319,42 @@ |
136 | win_->updateFrameRegion(); |
137 | } |
138 | |
139 | +void Window::Impl::SetupWindowEdges() |
140 | +{ |
141 | + if (input_mixer_) |
142 | + return; |
143 | + |
144 | + dpi_changed_ = Settings::Instance().dpi_changed.connect([this] { |
145 | + Update(); |
146 | + edge_borders_->scale = cv_->DPIScale(); |
147 | + if (top_layout_) top_layout_->scale = cv_->DPIScale(); |
148 | + }); |
149 | + |
150 | + input_mixer_ = std::make_shared<InputMixer>(); |
151 | + edge_borders_ = std::make_shared<EdgeBorders>(win_); |
152 | + edge_borders_->scale = cv_->DPIScale(); |
153 | + input_mixer_->PushToFront(edge_borders_); |
154 | + |
155 | + UpdateWindowEdgesGeo(); |
156 | +} |
157 | + |
158 | +void Window::Impl::UpdateWindowEdgesGeo() |
159 | +{ |
160 | + if (!edge_borders_) |
161 | + return; |
162 | + |
163 | + auto const& input = win_->inputRect(); |
164 | + edge_borders_->SetCoords(input.x(), input.y()); |
165 | + edge_borders_->SetSize(input.width(), input.height()); |
166 | +} |
167 | + |
168 | +void Window::Impl::CleanupWindowEdges() |
169 | +{ |
170 | + input_mixer_.reset(); |
171 | + edge_borders_.reset(); |
172 | + dpi_changed_->disconnect(); |
173 | +} |
174 | + |
175 | void Window::Impl::SetupWindowControls() |
176 | { |
177 | if (top_layout_) |
178 | @@ -293,26 +366,7 @@ |
179 | Decorate(); |
180 | }); |
181 | |
182 | - dpi_changed_ = Settings::Instance().dpi_changed.connect([this] { |
183 | - Update(); |
184 | - top_layout_->scale = cv_->DPIScale(); |
185 | - }); |
186 | - |
187 | - input_mixer_ = std::make_shared<InputMixer>(); |
188 | - |
189 | - if (win_->actions() & CompWindowActionResizeMask) |
190 | - { |
191 | - auto edges = std::make_shared<EdgeBorders>(win_); |
192 | - grab_edge_ = edges->GetEdge(Edge::Type::GRAB); |
193 | - edge_borders_ = edges; |
194 | - } |
195 | - else /*if (win_->actions() & CompWindowActionMoveMask)*/ |
196 | - { |
197 | - edge_borders_ = std::make_shared<GrabEdge>(win_); |
198 | - grab_edge_ = edge_borders_; |
199 | - } |
200 | - |
201 | - input_mixer_->PushToFront(edge_borders_); |
202 | + grab_edge_ = std::static_pointer_cast<EdgeBorders>(edge_borders_)->GetEdge(Edge::Type::GRAB); |
203 | |
204 | auto padding = style->Padding(Side::TOP); |
205 | top_layout_ = std::make_shared<Layout>(); |
206 | @@ -347,6 +401,7 @@ |
207 | top_layout_->Append(title_layout); |
208 | |
209 | input_mixer_->PushToFront(top_layout_); |
210 | + dirty_frame_ = false; |
211 | |
212 | SetupAppMenu(); |
213 | RedrawDecorations(); |
214 | @@ -357,12 +412,12 @@ |
215 | if (title_) |
216 | last_title_ = title_->text(); |
217 | |
218 | + if (input_mixer_) |
219 | + input_mixer_->Remove(top_layout_); |
220 | + |
221 | UnsetAppMenu(); |
222 | theme_changed_->disconnect(); |
223 | - dpi_changed_->disconnect(); |
224 | top_layout_.reset(); |
225 | - input_mixer_.reset(); |
226 | - edge_borders_.reset(); |
227 | } |
228 | |
229 | bool Window::Impl::IsMaximized() const |
230 | @@ -370,26 +425,25 @@ |
231 | return (win_->state() & MAXIMIZE_STATE) == MAXIMIZE_STATE; |
232 | } |
233 | |
234 | +void Window::Impl::UpdateElements() |
235 | +{ |
236 | + if (!parent_->scaled() && IsMaximized()) |
237 | + { |
238 | + deco_elements_ = cu::DecorationElement::NONE; |
239 | + return; |
240 | + } |
241 | + |
242 | + deco_elements_ = cu::WindowDecorationElements(win_); |
243 | +} |
244 | + |
245 | bool Window::Impl::ShadowDecorated() const |
246 | { |
247 | - if (!parent_->scaled() && IsMaximized()) |
248 | - return false; |
249 | - |
250 | - if (!cu::IsWindowShadowDecorable(win_)) |
251 | - return false; |
252 | - |
253 | - return true; |
254 | + return deco_elements_ & cu::DecorationElement::SHADOW; |
255 | } |
256 | |
257 | bool Window::Impl::FullyDecorated() const |
258 | { |
259 | - if (!parent_->scaled() && IsMaximized()) |
260 | - return false; |
261 | - |
262 | - if (!cu::IsWindowFullyDecorable(win_)) |
263 | - return false; |
264 | - |
265 | - return true; |
266 | + return deco_elements_ & cu::DecorationElement::BORDER; |
267 | } |
268 | |
269 | bool Window::Impl::ShouldBeDecorated() const |
270 | @@ -431,6 +485,7 @@ |
271 | } |
272 | |
273 | deco_tex.SetCoords(geo.x, geo.y); |
274 | + deco_tex.quad.region = deco_tex.quad.box; |
275 | } |
276 | |
277 | void Window::Impl::UpdateDecorationTextures() |
278 | @@ -442,7 +497,6 @@ |
279 | } |
280 | |
281 | auto const& geo = win_->borderRect(); |
282 | - auto const& input = win_->inputRect(); |
283 | auto const& border = win_->border(); |
284 | |
285 | bg_textures_.resize(4); |
286 | @@ -454,19 +508,18 @@ |
287 | top_layout_->SetCoords(geo.x(), geo.y()); |
288 | top_layout_->SetSize(geo.width(), border.top); |
289 | |
290 | - if (edge_borders_) |
291 | - { |
292 | - edge_borders_->SetCoords(input.x(), input.y()); |
293 | - edge_borders_->SetSize(input.width(), input.height()); |
294 | - } |
295 | - |
296 | SyncMenusGeometries(); |
297 | } |
298 | |
299 | void Window::Impl::ComputeShadowQuads() |
300 | { |
301 | - if (last_shadow_rect_.isEmpty() && !ShadowDecorated()) |
302 | + if (!(deco_elements_ & cu::DecorationElement::SHADOW)) |
303 | + { |
304 | + if (!last_shadow_rect_.isEmpty()) |
305 | + last_shadow_rect_.setGeometry(0, 0, 0, 0); |
306 | + |
307 | return; |
308 | + } |
309 | |
310 | const auto* texture = ShadowTexture(); |
311 | |
312 | @@ -554,6 +607,12 @@ |
313 | |
314 | if (shadows_rect != last_shadow_rect_) |
315 | { |
316 | + auto const& win_region = win_->region(); |
317 | + quads[Quads::Pos::TOP_LEFT].region = CompRegion(quads[Quads::Pos::TOP_LEFT].box) - win_region; |
318 | + quads[Quads::Pos::TOP_RIGHT].region = CompRegion(quads[Quads::Pos::TOP_RIGHT].box) - win_region; |
319 | + quads[Quads::Pos::BOTTOM_LEFT].region = CompRegion(quads[Quads::Pos::BOTTOM_LEFT].box) - win_region; |
320 | + quads[Quads::Pos::BOTTOM_RIGHT].region = CompRegion(quads[Quads::Pos::BOTTOM_RIGHT].box) - win_region; |
321 | + |
322 | last_shadow_rect_ = shadows_rect; |
323 | win_->updateWindowOutputExtents(); |
324 | } |
325 | @@ -563,15 +622,26 @@ |
326 | GLWindowPaintAttrib const& attrib, |
327 | CompRegion const& region, unsigned mask) |
328 | { |
329 | + if (win_->defaultViewport() != screen->vp()) |
330 | + return; |
331 | + |
332 | if (dirty_geo_) |
333 | parent_->UpdateDecorationPosition(); |
334 | + |
335 | + if (dirty_frame_) |
336 | + { |
337 | + dirty_frame_ = false; |
338 | + CleanupWindowControls(); |
339 | + CleanupWindowEdges(); |
340 | + Update(); |
341 | + } |
342 | } |
343 | |
344 | void Window::Impl::Draw(GLMatrix const& transformation, |
345 | GLWindowPaintAttrib const& attrib, |
346 | CompRegion const& region, unsigned mask) |
347 | { |
348 | - if (last_shadow_rect_.isEmpty()) |
349 | + if (last_shadow_rect_.isEmpty() || win_->defaultViewport() != screen->vp()) |
350 | return; |
351 | |
352 | auto const& clip_region = (mask & PAINT_WINDOW_TRANSFORMED_MASK) ? infiniteRegion : region; |
353 | @@ -582,7 +652,7 @@ |
354 | for (unsigned i = 0; i < shadow_quads_.size(); ++i) |
355 | { |
356 | auto& quad = shadow_quads_[Quads::Pos(i)]; |
357 | - glwin_->glAddGeometry({quad.matrix}, CompRegion(quad.box) - win_->region(), clip_region); |
358 | + glwin_->glAddGeometry(quad.matrices, quad.region, clip_region); |
359 | } |
360 | |
361 | if (glwin_->vertexBuffer()->end()) |
362 | @@ -594,7 +664,7 @@ |
363 | continue; |
364 | |
365 | glwin_->vertexBuffer()->begin(); |
366 | - glwin_->glAddGeometry({dtex.quad.matrix}, dtex.quad.box, clip_region); |
367 | + glwin_->glAddGeometry(dtex.quad.matrices, dtex.quad.region, clip_region); |
368 | |
369 | if (glwin_->vertexBuffer()->end()) |
370 | glwin_->glDrawTexture(dtex, transformation, attrib, mask); |
371 | @@ -707,6 +777,9 @@ |
372 | |
373 | if (top_layout_) |
374 | top_layout_->scale = cv_->DPIScale(); |
375 | + |
376 | + if (edge_borders_) |
377 | + edge_borders_->scale = cv_->DPIScale(); |
378 | } |
379 | } |
380 | |
381 | @@ -789,6 +862,7 @@ |
382 | { |
383 | impl_->UpdateMonitor(); |
384 | impl_->ComputeShadowQuads(); |
385 | + impl_->UpdateWindowEdgesGeo(); |
386 | impl_->UpdateDecorationTextures(); |
387 | impl_->UpdateForceQuitDialogPosition(); |
388 | impl_->dirty_geo_ = false; |
389 | @@ -808,7 +882,8 @@ |
390 | { |
391 | data.add(impl_->win_->borderRect()) |
392 | .add("input_geo", impl_->win_->inputRect()) |
393 | - .add("content_geo", impl_->win_->region().boundingRect()) |
394 | + .add("content_geo", impl_->win_->geometry()) |
395 | + .add("region", impl_->win_->region().boundingRect()) |
396 | .add("title", title()) |
397 | .add("active", impl_->active()) |
398 | .add("scaled", scaled()) |
399 | |
400 | === modified file 'decorations/DecorationsEdgeBorders.cpp' |
401 | --- decorations/DecorationsEdgeBorders.cpp 2014-02-18 23:01:33 +0000 |
402 | +++ decorations/DecorationsEdgeBorders.cpp 2014-12-08 22:42:16 +0000 |
403 | @@ -26,21 +26,31 @@ |
404 | { |
405 | namespace |
406 | { |
407 | -const int MIN_CORNER_EDGE = 10; |
408 | +const RawPixel MIN_CORNER_EDGE = 10_em; |
409 | } |
410 | |
411 | EdgeBorders::EdgeBorders(CompWindow* win) |
412 | { |
413 | - items_.resize(size_t(Edge::Type::Size)); |
414 | - |
415 | - for (unsigned i = 0; i < unsigned(Edge::Type::Size); ++i) |
416 | - { |
417 | - auto type = Edge::Type(i); |
418 | - |
419 | - if (type == Edge::Type::GRAB) |
420 | - items_[i] = std::make_shared<GrabEdge>(win); |
421 | - else |
422 | - items_[i] = std::make_shared<Edge>(win, type); |
423 | + scale.changed.connect(sigc::hide(sigc::mem_fun(this, &EdgeBorders::Relayout))); |
424 | + |
425 | + if (win->actions() & CompWindowActionResizeMask) |
426 | + { |
427 | + items_.resize(size_t(Edge::Type::Size)); |
428 | + |
429 | + for (unsigned i = 0; i < unsigned(Edge::Type::Size); ++i) |
430 | + { |
431 | + auto type = Edge::Type(i); |
432 | + |
433 | + if (type == Edge::Type::GRAB) |
434 | + items_[i] = std::make_shared<GrabEdge>(win); |
435 | + else |
436 | + items_[i] = std::make_shared<Edge>(win, type); |
437 | + } |
438 | + } |
439 | + else /*if (win->actions() & CompWindowActionMoveMask)*/ |
440 | + { |
441 | + items_.resize(size_t(Edge::Type::GRAB) + 1); |
442 | + items_[unsigned(Edge::Type::GRAB)] = std::make_shared<GrabEdge>(win); |
443 | } |
444 | |
445 | Relayout(); |
446 | @@ -54,10 +64,17 @@ |
447 | auto const& ib = win->input(); |
448 | |
449 | using namespace compiz::window::extents; |
450 | - Extents edges(std::max(ib.left, MIN_CORNER_EDGE), |
451 | - std::max(ib.right, MIN_CORNER_EDGE), |
452 | - std::max(ib.top, MIN_CORNER_EDGE), |
453 | - std::max(ib.bottom, MIN_CORNER_EDGE)); |
454 | + int min_corner_edge = MIN_CORNER_EDGE.CP(scale); |
455 | + Extents edges(std::max(ib.left, min_corner_edge), |
456 | + std::max(ib.right, min_corner_edge), |
457 | + std::max(ib.top, min_corner_edge), |
458 | + std::max(ib.bottom, min_corner_edge)); |
459 | + |
460 | + grab_edge->SetCoords(rect_.x() + ib.left, rect_.y() + ib.top - b.top); |
461 | + grab_edge->SetSize(rect_.width() - ib.left - ib.right, b.top); |
462 | + |
463 | + if (items_.size() != size_t(Edge::Type::Size)) |
464 | + return; |
465 | |
466 | auto item = items_[unsigned(Edge::Type::TOP)]; |
467 | item->SetCoords(rect_.x() + edges.left, rect_.y()); |
468 | @@ -90,10 +107,6 @@ |
469 | item = items_[unsigned(Edge::Type::BOTTOM_RIGHT)]; |
470 | item->SetCoords(rect_.x2() - edges.right, rect_.y2() - edges.bottom); |
471 | item->SetSize(edges.right, edges.bottom); |
472 | - |
473 | - item = items_[unsigned(Edge::Type::GRAB)]; |
474 | - item->SetCoords(rect_.x() + ib.left, rect_.y() + ib.top - b.top); |
475 | - item->SetSize(rect_.width() - ib.left - ib.right, b.top); |
476 | } |
477 | |
478 | Item::Ptr const& EdgeBorders::GetEdge(Edge::Type type) const |
479 | |
480 | === modified file 'decorations/DecorationsForceQuitDialog.cpp' |
481 | --- decorations/DecorationsForceQuitDialog.cpp 2014-04-02 13:14:43 +0000 |
482 | +++ decorations/DecorationsForceQuitDialog.cpp 2014-12-08 22:42:16 +0000 |
483 | @@ -141,7 +141,7 @@ |
484 | |
485 | auto const& deco_style = decoration::Style::Get(); |
486 | auto const& offset = deco_style->ShadowOffset(); |
487 | - int max_offset = std::max(std::abs(offset.x), std::abs(offset.y)); |
488 | + int max_offset = std::max(std::abs(offset.x * 4), std::abs(offset.y * 4)); |
489 | gtk_container_set_border_width(GTK_CONTAINER(self), deco_style->ActiveShadowRadius()+max_offset); |
490 | |
491 | auto* screen = gtk_window_get_screen(self); |
492 | @@ -259,18 +259,32 @@ |
493 | auto const& radius = deco_style->CornerRadius(); |
494 | auto const& offset = deco_style->ShadowOffset(); |
495 | auto const& color = deco_style->ActiveShadowColor(); |
496 | + auto const& backcolor = deco_style->InactiveShadowColor(); |
497 | int decoration_radius = std::max({radius.top, radius.left, radius.right, radius.bottom}); |
498 | |
499 | - gtk_css_provider_load_from_data(style, (R"(SheetStyleDialog { |
500 | + gtk_css_provider_load_from_data(style, (R"( |
501 | + SheetStyleDialog { |
502 | background-color: #f7f6f5; |
503 | color: #4a4a4a; |
504 | border-radius: )"+std::to_string(decoration_radius)+R"(px; |
505 | - box-shadow: )"+std::to_string(offset.x)+"px "+std::to_string(offset.y)+"px "+ |
506 | + box-shadow: )"+std::to_string(2 * offset.x)+"px "+std::to_string(2 * offset.y)+"px "+ |
507 | std::to_string(deco_style->ActiveShadowRadius())+"px "+ |
508 | "rgba("+std::to_string(int(color.red * 255.0))+", "+ |
509 | std::to_string(int(color.green * 255.0))+", "+ |
510 | std::to_string(int(color.blue * 255.0))+", "+ |
511 | std::to_string(int(color.alpha))+'.'+std::to_string(int(color.alpha*10000.0))+')'+R"(; |
512 | + } |
513 | + |
514 | + SheetStyleDialog:backdrop { |
515 | + background-color: shade(#f7f6f5, 1.2); |
516 | + color: shade(#4a4a4a, 1.5); |
517 | + border-radius: )"+std::to_string(decoration_radius)+R"(px; |
518 | + box-shadow: )"+std::to_string(2 * offset.x)+"px "+std::to_string(2 * offset.y)+"px "+ |
519 | + std::to_string(deco_style->InactiveShadowRadius())+"px "+ |
520 | + "rgba("+std::to_string(int(backcolor.red * 255.0))+", "+ |
521 | + std::to_string(int(backcolor.green * 255.0))+", "+ |
522 | + std::to_string(int(backcolor.blue * 255.0))+", "+ |
523 | + std::to_string(int(backcolor.alpha))+'.'+std::to_string(int(backcolor.alpha*10000.0))+')'+R"(; |
524 | })").c_str(), -1, nullptr); |
525 | |
526 | auto* style_ctx = gtk_widget_get_style_context(self); |
527 | |
528 | === modified file 'decorations/DecorationsManager.cpp' |
529 | --- decorations/DecorationsManager.cpp 2014-04-02 09:04:37 +0000 |
530 | +++ decorations/DecorationsManager.cpp 2014-12-08 22:42:16 +0000 |
531 | @@ -44,8 +44,7 @@ |
532 | } |
533 | |
534 | Manager::Impl::Impl(decoration::Manager* parent, menu::Manager::Ptr const& menu) |
535 | - : active_window_(0) |
536 | - , enable_add_supported_atoms_(true) |
537 | + : enable_add_supported_atoms_(true) |
538 | , data_pool_(DataPool::Get()) |
539 | , menu_manager_(menu) |
540 | { |
541 | @@ -55,7 +54,6 @@ |
542 | Display* dpy = screen->dpy(); |
543 | atom::_NET_REQUEST_FRAME_EXTENTS = XInternAtom(dpy, "_NET_REQUEST_FRAME_EXTENTS", False); |
544 | atom::_NET_WM_VISIBLE_NAME = XInternAtom(dpy, "_NET_WM_VISIBLE_NAME", False); |
545 | - screen->updateSupportedWmHints(); |
546 | |
547 | auto rebuild_cb = sigc::mem_fun(this, &Impl::OnShadowOptionsChanged); |
548 | manager_->active_shadow_color.changed.connect(sigc::hide(sigc::bind(rebuild_cb, true))); |
549 | @@ -208,8 +206,6 @@ |
550 | |
551 | bool Manager::Impl::HandleEventBefore(XEvent* event) |
552 | { |
553 | - active_window_ = screen->activeWindow(); |
554 | - |
555 | switch (event->type) |
556 | { |
557 | case ClientMessage: |
558 | @@ -254,31 +250,26 @@ |
559 | |
560 | bool Manager::Impl::HandleEventAfter(XEvent* event) |
561 | { |
562 | - if (screen->activeWindow() != active_window_) |
563 | - { |
564 | - // Do this when _NET_ACTIVE_WINDOW changes on root! |
565 | - if (active_deco_win_) |
566 | - active_deco_win_->impl_->active = false; |
567 | - |
568 | - active_window_ = screen->activeWindow(); |
569 | - auto const& new_active = GetWindowByXid(active_window_); |
570 | - active_deco_win_ = new_active; |
571 | - |
572 | - if (new_active) |
573 | - new_active->impl_->active = true; |
574 | - } |
575 | - |
576 | switch (event->type) |
577 | { |
578 | case PropertyNotify: |
579 | { |
580 | - if (event->xproperty.atom == Atoms::mwmHints) |
581 | + if (event->xproperty.atom == Atoms::winActive) |
582 | + { |
583 | + if (active_deco_win_) |
584 | + active_deco_win_->impl_->active = false; |
585 | + |
586 | + auto const& new_active = GetWindowByXid(screen->activeWindow()); |
587 | + active_deco_win_ = new_active; |
588 | + |
589 | + if (new_active) |
590 | + new_active->impl_->active = true; |
591 | + } |
592 | + else if (event->xproperty.atom == Atoms::mwmHints || |
593 | + event->xproperty.atom == Atoms::wmAllowedActions) |
594 | { |
595 | if (Window::Ptr const& win = GetWindowByXid(event->xproperty.window)) |
596 | - { |
597 | - win->impl_->CleanupWindowControls(); |
598 | - win->Update(); |
599 | - } |
600 | + win->impl_->UpdateFrameActions(); |
601 | } |
602 | else if (event->xproperty.atom == XA_WM_NAME || |
603 | event->xproperty.atom == Atoms::wmName || |
604 | @@ -445,7 +436,7 @@ |
605 | .add("active_shadow_radius", active_shadow_radius()) |
606 | .add("inactive_shadow_color", inactive_shadow_color()) |
607 | .add("inactive_shadow_radius", inactive_shadow_radius()) |
608 | - .add("active_window", impl_->active_window_); |
609 | + .add("active_window", screen->activeWindow()); |
610 | } |
611 | |
612 | debug::Introspectable::IntrospectableList Manager::GetIntrospectableChildren() |
613 | |
614 | === modified file 'decorations/DecorationsPriv.h' |
615 | --- decorations/DecorationsPriv.h 2014-04-02 09:05:59 +0000 |
616 | +++ decorations/DecorationsPriv.h 2014-12-08 22:42:16 +0000 |
617 | @@ -1,6 +1,6 @@ |
618 | // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- |
619 | /* |
620 | - * Copyright (C) 2013 Canonical Ltd |
621 | + * Copyright (C) 2013-2014 Canonical Ltd |
622 | * |
623 | * This program is free software: you can redistribute it and/or modify |
624 | * it under the terms of the GNU General Public License version 3 as |
625 | @@ -92,11 +92,15 @@ |
626 | private: |
627 | void UnsetExtents(); |
628 | void SetupExtents(); |
629 | + void UpdateElements(); |
630 | void UpdateMonitor(); |
631 | void UpdateFrame(); |
632 | void CreateFrame(nux::Geometry const&); |
633 | void UpdateFrameGeo(nux::Geometry const&); |
634 | + void UpdateFrameActions(); |
635 | void UnsetFrame(); |
636 | + void SetupWindowEdges(); |
637 | + void CleanupWindowEdges(); |
638 | void SetupWindowControls(); |
639 | void CleanupWindowControls(); |
640 | void UnsetAppMenu(); |
641 | @@ -109,6 +113,7 @@ |
642 | |
643 | void ComputeShadowQuads(); |
644 | void UpdateDecorationTextures(); |
645 | + void UpdateWindowEdgesGeo(); |
646 | void UpdateForceQuitDialogPosition(); |
647 | void RenderDecorationTexture(Side, nux::Geometry const&); |
648 | void Paint(GLMatrix const&, GLWindowPaintAttrib const&, CompRegion const&, unsigned mask); |
649 | @@ -122,8 +127,12 @@ |
650 | ::CompositeWindow* cwin_; |
651 | ::GLWindow* glwin_; |
652 | ::Window frame_; |
653 | + int monitor_; |
654 | bool dirty_geo_; |
655 | - int monitor_; |
656 | + bool dirty_frame_; |
657 | + unsigned deco_elements_; |
658 | + unsigned last_mwm_decor_; |
659 | + unsigned last_actions_; |
660 | |
661 | CompRect last_shadow_rect_; |
662 | Quads shadow_quads_; |
663 | @@ -176,7 +185,6 @@ |
664 | friend class Manager; |
665 | friend struct Window::Impl; |
666 | |
667 | - ::Window active_window_; |
668 | bool enable_add_supported_atoms_; |
669 | |
670 | DataPool::Ptr data_pool_; |
671 | |
672 | === modified file 'decorations/DecorationsTitle.cpp' |
673 | --- decorations/DecorationsTitle.cpp 2014-03-31 18:36:07 +0000 |
674 | +++ decorations/DecorationsTitle.cpp 2014-12-08 22:42:16 +0000 |
675 | @@ -80,6 +80,7 @@ |
676 | |
677 | Style::Get()->DrawTitle(text(), state, text_ctx, texture_size_.width / scale(), texture_size_.height / scale(), bg_geo * (1.0/scale)); |
678 | SetTexture(text_ctx); |
679 | + texture_.UpdateMatrix(); |
680 | } |
681 | |
682 | void Title::SetX(int x) |
683 | |
684 | === modified file 'decorations/DecorationsWidgets.cpp' |
685 | --- decorations/DecorationsWidgets.cpp 2014-02-27 07:10:31 +0000 |
686 | +++ decorations/DecorationsWidgets.cpp 2014-12-08 22:42:16 +0000 |
687 | @@ -226,6 +226,12 @@ |
688 | |
689 | // |
690 | |
691 | +TexturedItem::TexturedItem() |
692 | + : dirty_region_(false) |
693 | +{ |
694 | + geo_parameters_changed.connect([this] { dirty_region_ = true; }); |
695 | +} |
696 | + |
697 | void TexturedItem::SetTexture(cu::SimpleTexture::Ptr const& tex) |
698 | { |
699 | auto prev_geo = Geometry(); |
700 | @@ -254,8 +260,14 @@ |
701 | if (!visible || Geometry().isEmpty() || !texture_) |
702 | return; |
703 | |
704 | + if (dirty_region_) |
705 | + { |
706 | + texture_.quad.region = texture_.quad.box; |
707 | + dirty_region_ = false; |
708 | + } |
709 | + |
710 | ctx->vertexBuffer()->begin(); |
711 | - ctx->glAddGeometry({texture_.quad.matrix}, texture_.quad.box, clip); |
712 | + ctx->glAddGeometry(texture_.quad.matrices, texture_.quad.region, clip); |
713 | |
714 | if (ctx->vertexBuffer()->end()) |
715 | ctx->glDrawTexture(texture_, transformation, attrib, mask); |
716 | |
717 | === modified file 'decorations/DecorationsWidgets.h' |
718 | --- decorations/DecorationsWidgets.h 2014-02-27 07:10:31 +0000 |
719 | +++ decorations/DecorationsWidgets.h 2014-12-08 22:42:16 +0000 |
720 | @@ -121,6 +121,8 @@ |
721 | public: |
722 | typedef std::shared_ptr<TexturedItem> Ptr; |
723 | |
724 | + TexturedItem(); |
725 | + |
726 | void SetTexture(cu::SimpleTexture::Ptr const&); |
727 | void Draw(GLWindow*, GLMatrix const&, GLWindowPaintAttrib const&, CompRegion const&, unsigned mask); |
728 | void SetCoords(int x, int y); |
729 | @@ -133,6 +135,9 @@ |
730 | |
731 | CompRect& InternalGeo(); |
732 | cu::SimpleTextureQuad texture_; |
733 | + |
734 | +private: |
735 | + bool dirty_region_; |
736 | }; |
737 | |
738 | |
739 | |
740 | === modified file 'plugins/unityshell/src/unityshell.cpp' |
741 | --- plugins/unityshell/src/unityshell.cpp 2014-08-06 14:19:10 +0000 |
742 | +++ plugins/unityshell/src/unityshell.cpp 2014-12-08 22:42:16 +0000 |
743 | @@ -278,6 +278,7 @@ |
744 | CompositeScreenInterface::setHandler(cScreen); |
745 | GLScreenInterface::setHandler(gScreen); |
746 | ScaleScreenInterface::setHandler(sScreen); |
747 | + screen->updateSupportedWmHints(); |
748 | |
749 | PluginAdapter::Initialize(screen); |
750 | AddChild(&WindowManager::Default()); |
751 | |
752 | === modified file 'unity-shared/CompizUtils.cpp' |
753 | --- unity-shared/CompizUtils.cpp 2014-04-14 13:51:58 +0000 |
754 | +++ unity-shared/CompizUtils.cpp 2014-12-08 22:42:16 +0000 |
755 | @@ -1,6 +1,6 @@ |
756 | // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- |
757 | /* |
758 | -* Copyright (C) 2013 Canonical Ltd |
759 | +* Copyright (C) 2013-2014 Canonical Ltd |
760 | * |
761 | * This program is free software: you can redistribute it and/or modify |
762 | * it under the terms of the GNU General Public License version 3 as |
763 | @@ -30,6 +30,11 @@ |
764 | { |
765 | const unsigned PIXMAP_DEPTH = 32; |
766 | const float DEFAULT_SCALE = 1.0f; |
767 | + const unsigned DECORABLE_WINDOW_TYPES = CompWindowTypeDialogMask | |
768 | + CompWindowTypeModalDialogMask | |
769 | + CompWindowTypeUtilMask | |
770 | + CompWindowTypeMenuMask | |
771 | + CompWindowTypeNormalMask; |
772 | } |
773 | |
774 | SimpleTexture::SimpleTexture(GLTexture::List const& tex) |
775 | @@ -39,7 +44,7 @@ |
776 | // |
777 | |
778 | SimpleTextureQuad::SimpleTextureQuad() |
779 | - : scale(DEFAULT_SCALE) |
780 | + : scale_(DEFAULT_SCALE) |
781 | {} |
782 | |
783 | bool SimpleTextureQuad::SetTexture(SimpleTexture::Ptr const& simple_texture) |
784 | @@ -52,24 +57,27 @@ |
785 | if (st && st->texture()) |
786 | { |
787 | auto* tex = st->texture(); |
788 | - CompPoint old_coords(quad.box.x(), quad.box.y()); |
789 | - short invalid = std::numeric_limits<short>::min(); |
790 | - quad.box.setGeometry(invalid, invalid, tex->width() * scale, tex->height() * scale); |
791 | - SetCoords(old_coords.x(), old_coords.y()); |
792 | + CompSize size(tex->width() * scale_, tex->height() * scale_); |
793 | + |
794 | + if (quad.box.width() != size.width() || quad.box.height() != size.height()) |
795 | + { |
796 | + quad.box.setSize(size); |
797 | + UpdateMatrix(); |
798 | + } |
799 | } |
800 | |
801 | return true; |
802 | } |
803 | |
804 | -bool SimpleTextureQuad::SetScale(float s) |
805 | +bool SimpleTextureQuad::SetScale(double s) |
806 | { |
807 | - if (!st || scale == s) |
808 | + if (!st || scale_ == s) |
809 | return false; |
810 | |
811 | - scale = s; |
812 | + scale_ = s; |
813 | auto* tex = st->texture(); |
814 | - quad.box.setWidth(tex->width() * scale); |
815 | - quad.box.setHeight(tex->height() * scale); |
816 | + quad.box.setWidth(tex->width() * scale_); |
817 | + quad.box.setHeight(tex->height() * scale_); |
818 | UpdateMatrix(); |
819 | return true; |
820 | } |
821 | @@ -91,8 +99,8 @@ |
822 | int y = quad.box.y(); |
823 | |
824 | quad.matrix = (st && st->texture()) ? st->texture()->matrix() : GLTexture::Matrix(); |
825 | - quad.matrix.xx /= scale; |
826 | - quad.matrix.yy /= scale; |
827 | + quad.matrix.xx /= scale_; |
828 | + quad.matrix.yy /= scale_; |
829 | quad.matrix.x0 = 0.0f - COMP_TEX_COORD_X(quad.matrix, x); |
830 | quad.matrix.y0 = 0.0f - COMP_TEX_COORD_Y(quad.matrix, y); |
831 | } |
832 | @@ -166,57 +174,68 @@ |
833 | return cairo_xlib_surface_get_height(surface_); |
834 | } |
835 | |
836 | -bool IsWindowShadowDecorable(CompWindow* win) |
837 | +// |
838 | +// |
839 | + |
840 | +unsigned WindowDecorationElements(CompWindow* win) |
841 | { |
842 | + unsigned elements = DecorationElement::NONE; |
843 | + |
844 | if (!win) |
845 | - return false; |
846 | + return elements; |
847 | |
848 | if (!win->isViewable()) |
849 | - return false; |
850 | + return elements; |
851 | |
852 | if (win->wmType() & (CompWindowTypeDockMask | CompWindowTypeDesktopMask)) |
853 | - return false; |
854 | - |
855 | - if (win->region().numRects() != 1) // Non rectangular windows |
856 | - return false; |
857 | - |
858 | - if (win->alpha()) |
859 | - return WindowHasMotifDecorations(win); |
860 | - |
861 | - return true; |
862 | + return elements; |
863 | + |
864 | + if (win->inShowDesktopMode()) |
865 | + return elements; |
866 | + |
867 | + auto const& region = win->region(); |
868 | + bool rectangular = (region.numRects() == 1); |
869 | + bool alpha = win->alpha(); |
870 | + |
871 | + if (!rectangular && alpha) // Non-rectangular windows with alpha channel |
872 | + return elements; |
873 | + |
874 | + if (region.boundingRect() != win->geometry()) // Shaped windows |
875 | + return elements; |
876 | + |
877 | + if (rectangular) |
878 | + elements |= DecorationElement::SHADOW; |
879 | + |
880 | + if (!win->overrideRedirect() && |
881 | + (win->type() & DECORABLE_WINDOW_TYPES) && |
882 | + (win->frame() || win->hasUnmapReference())) |
883 | + { |
884 | + if (win->actions() & CompWindowActionResizeMask) |
885 | + elements |= DecorationElement::EDGE; |
886 | + |
887 | + if (rectangular && (win->mwmDecor() & (MwmDecorAll | MwmDecorTitle))) |
888 | + elements |= DecorationElement::BORDER; |
889 | + } |
890 | + |
891 | + if (alpha && !(elements & DecorationElement::BORDER) && !(win->mwmDecor() & MwmDecorBorder)) |
892 | + elements &= ~DecorationElement::SHADOW; |
893 | + |
894 | + return elements; |
895 | +} |
896 | + |
897 | +bool IsWindowEdgeDecorable(CompWindow* win) |
898 | +{ |
899 | + return WindowDecorationElements(win) & DecorationElement::EDGE; |
900 | +} |
901 | + |
902 | +bool IsWindowShadowDecorable(CompWindow* win) |
903 | +{ |
904 | + return WindowDecorationElements(win) & DecorationElement::SHADOW; |
905 | } |
906 | |
907 | bool IsWindowFullyDecorable(CompWindow* win) |
908 | { |
909 | - if (!win) |
910 | - return false; |
911 | - |
912 | - if (!IsWindowShadowDecorable(win)) |
913 | - return false; |
914 | - |
915 | - return WindowHasMotifDecorations(win); |
916 | -} |
917 | - |
918 | -bool WindowHasMotifDecorations(CompWindow* win) |
919 | -{ |
920 | - if (!win) |
921 | - return false; |
922 | - |
923 | - if (win->overrideRedirect()) |
924 | - return false; |
925 | - |
926 | - switch (win->type()) |
927 | - { |
928 | - case CompWindowTypeDialogMask: |
929 | - case CompWindowTypeModalDialogMask: |
930 | - case CompWindowTypeUtilMask: |
931 | - case CompWindowTypeMenuMask: |
932 | - case CompWindowTypeNormalMask: |
933 | - if (win->mwmDecor() & (MwmDecorAll | MwmDecorTitle)) |
934 | - return true; |
935 | - } |
936 | - |
937 | - return false; |
938 | + return WindowDecorationElements(win) & DecorationElement::BORDER; |
939 | } |
940 | |
941 | } // compiz_utils namespace |
942 | |
943 | === modified file 'unity-shared/CompizUtils.h' |
944 | --- unity-shared/CompizUtils.h 2014-04-14 13:51:58 +0000 |
945 | +++ unity-shared/CompizUtils.h 2014-12-08 22:42:16 +0000 |
946 | @@ -31,8 +31,15 @@ |
947 | |
948 | struct TextureQuad |
949 | { |
950 | + TextureQuad() |
951 | + : matrices(1) |
952 | + , matrix(matrices[0]) |
953 | + {} |
954 | + |
955 | CompRect box; |
956 | - GLTexture::Matrix matrix; |
957 | + CompRegion region; |
958 | + GLTexture::MatrixList matrices; |
959 | + GLTexture::Matrix& matrix; |
960 | }; |
961 | |
962 | struct SimpleTexture |
963 | @@ -59,11 +66,13 @@ |
964 | { |
965 | SimpleTextureQuad(); |
966 | bool SetTexture(SimpleTexture::Ptr const&); |
967 | - bool SetScale(float scale); |
968 | + bool SetScale(double scale); |
969 | bool SetCoords(int x, int y); |
970 | bool SetX(int x); |
971 | bool SetY(int y); |
972 | |
973 | + void UpdateMatrix(); |
974 | + |
975 | operator SimpleTexture::Ptr() const { return st; } |
976 | operator bool() const { return st && st->texture(); } |
977 | operator GLTexture*() const { return st ? st->texture() : nullptr; } |
978 | @@ -73,8 +82,7 @@ |
979 | TextureQuad quad; |
980 | |
981 | private: |
982 | - void UpdateMatrix(); |
983 | - float scale; |
984 | + double scale_; |
985 | }; |
986 | |
987 | struct PixmapTexture : SimpleTexture |
988 | @@ -111,9 +119,20 @@ |
989 | cairo_t *cr_; |
990 | }; |
991 | |
992 | +enum DecorationElement |
993 | +{ |
994 | + NONE = 0, |
995 | + EDGE = (1 << 0), |
996 | + SHADOW = (1 << 1), |
997 | + BORDER = (1 << 2), |
998 | + FULL = EDGE|SHADOW|BORDER |
999 | +}; |
1000 | + |
1001 | +unsigned WindowDecorationElements(CompWindow*); |
1002 | + |
1003 | +bool IsWindowEdgeDecorable(CompWindow*); |
1004 | bool IsWindowShadowDecorable(CompWindow*); |
1005 | bool IsWindowFullyDecorable(CompWindow*); |
1006 | -bool WindowHasMotifDecorations(CompWindow*); |
1007 | |
1008 | } // compiz_utils namespace |
1009 | } // unity namespace |
1010 | |
1011 | === modified file 'unity-shared/XWindowManager.cpp' |
1012 | --- unity-shared/XWindowManager.cpp 2014-02-14 03:05:02 +0000 |
1013 | +++ unity-shared/XWindowManager.cpp 2014-12-08 22:42:16 +0000 |
1014 | @@ -83,7 +83,7 @@ |
1015 | { |
1016 | LOG_ERROR(logger) << "Impossible to get the property " << gdk_x11_get_xatom_name(atom) |
1017 | << " for window " << window_id << ": invalid string type: " |
1018 | - << gdk_x11_get_xatom_name(Atoms::utf8String); |
1019 | + << gdk_x11_get_xatom_name(type); |
1020 | return std::string(); |
1021 | } |
1022 |