Merge lp:~unity-team/unity/trusty-1276177 into lp:unity/7.2

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
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.

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

Subscribers

People subscribed via source and target branches

to all changes:
to status/vote changes: