Merge lp:~3v1n0/unity/decomenu-fixes into lp:unity

Proposed by Marco Trevisan (Treviño)
Status: Merged
Approved by: Brandon Schaefer
Approved revision: no longer in the source branch.
Merged at revision: 3715
Proposed branch: lp:~3v1n0/unity/decomenu-fixes
Merge into: lp:unity
Prerequisite: lp:~3v1n0/unity/scale-layout-windows
Diff against target: 1014 lines (+220/-128)
19 files modified
decorations/DecoratedWindow.cpp (+23/-6)
decorations/DecoratedWindow.h (+1/-0)
decorations/DecorationsManager.cpp (+1/-0)
decorations/DecorationsPriv.h (+1/-0)
decorations/DecorationsTitle.cpp (+6/-0)
launcher/SwitcherController.cpp (+17/-37)
launcher/SwitcherController.h (+2/-4)
launcher/SwitcherControllerImpl.h (+1/-4)
launcher/SwitcherView.cpp (+4/-4)
launcher/SwitcherView.h (+1/-1)
panel/PanelMenuView.cpp (+38/-5)
plugins/unityshell/src/unityshell.cpp (+55/-26)
plugins/unityshell/src/unityshell.h (+2/-2)
services/panel-service.c (+44/-10)
tests/MockSwitcherController.h (+1/-3)
tests/test_switcher_controller.cpp (+8/-8)
tests/test_switcher_controller_slow.cpp (+2/-2)
unity-shared/CompizUtils.cpp (+6/-2)
unity-shared/PluginAdapter.cpp (+7/-14)
To merge this branch: bzr merge lp:~3v1n0/unity/decomenu-fixes
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Brandon Schaefer (community) Approve
Review via email: mp+210699@code.launchpad.net

Commit message

Decorations and Menus: a bunch of various fixes...

Description of the change

Lots of fixes in menu and decorations...

To post a comment you must log in.
Revision history for this message
Brandon Schaefer (brandontschaefer) wrote :

LGTM

review: Approve
Revision history for this message
Brandon Schaefer (brandontschaefer) wrote :

LGTM

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)

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 2014-03-12 23:07:10 +0000
3+++ decorations/DecoratedWindow.cpp 2014-03-12 23:07:10 +0000
4@@ -415,6 +415,9 @@
5
6 void Window::Impl::RenderDecorationTexture(Side s, nux::Geometry const& geo)
7 {
8+ if (geo.width <= 0 || geo.height <= 0)
9+ return;
10+
11 auto& deco_tex = bg_textures_[unsigned(s)];
12
13 if (deco_tex.quad.box.width() != geo.width || deco_tex.quad.box.height() != geo.height)
14@@ -461,7 +464,7 @@
15
16 void Window::Impl::ComputeShadowQuads()
17 {
18- if (!ShadowDecorated())
19+ if (last_shadow_rect_.isEmpty() && !ShadowDecorated())
20 return;
21
22 const auto* texture = ShadowTexture();
23@@ -555,19 +558,24 @@
24 }
25 }
26
27+void Window::Impl::Paint(GLMatrix const& transformation,
28+ GLWindowPaintAttrib const& attrib,
29+ CompRegion const& region, unsigned mask)
30+{
31+ if (dirty_geo_)
32+ parent_->UpdateDecorationPosition();
33+}
34+
35 void Window::Impl::Draw(GLMatrix const& transformation,
36 GLWindowPaintAttrib const& attrib,
37 CompRegion const& region, unsigned mask)
38 {
39- if (!ShadowDecorated())
40+ if (last_shadow_rect_.isEmpty())
41 return;
42
43 auto const& clip_region = (mask & PAINT_WINDOW_TRANSFORMED_MASK) ? infiniteRegion : region;
44 mask |= PAINT_WINDOW_BLEND_MASK;
45
46- if (dirty_geo_)
47- parent_->UpdateDecorationPosition();
48-
49 glwin_->vertexBuffer()->begin();
50
51 for (unsigned i = 0; i < shadow_quads_.size(); ++i)
52@@ -581,6 +589,9 @@
53
54 for (auto const& dtex : bg_textures_)
55 {
56+ if (!dtex)
57+ continue;
58+
59 glwin_->vertexBuffer()->begin();
60 glwin_->glAddGeometry({dtex.quad.matrix}, dtex.quad.box, clip_region);
61
62@@ -613,7 +624,7 @@
63 sliding_layout->SetInputItem(nullptr);
64 sliding_layout->mouse_owner = false;
65
66- if (!menu_manager->HasAppMenu())
67+ if (!menu_manager->HasAppMenu() || !Style::Get()->integrated_menus())
68 return;
69
70 auto visibility_cb = sigc::hide(sigc::mem_fun(this, &Impl::UpdateAppMenuVisibility));
71@@ -738,6 +749,12 @@
72 impl_->Draw(matrix, attrib, region, mask);
73 }
74
75+void Window::Paint(GLMatrix const& matrix, GLWindowPaintAttrib const& attrib,
76+ CompRegion const& region, unsigned mask)
77+{
78+ impl_->Paint(matrix, attrib, region, mask);
79+}
80+
81 void Window::Undecorate()
82 {
83 impl_->Undecorate();
84
85=== modified file 'decorations/DecoratedWindow.h'
86--- decorations/DecoratedWindow.h 2014-02-24 17:55:50 +0000
87+++ decorations/DecoratedWindow.h 2014-03-12 23:07:10 +0000
88@@ -51,6 +51,7 @@
89 void UpdateDecorationPositionDelayed();
90 void UpdateFrameRegion(CompRegion&);
91 void UpdateOutputExtents(compiz::window::extents::Extents&);
92+ void Paint(GLMatrix const&, GLWindowPaintAttrib const&, CompRegion const&, unsigned mask);
93 void Draw(GLMatrix const&, GLWindowPaintAttrib const&, CompRegion const&, unsigned mask);
94
95 protected:
96
97=== modified file 'decorations/DecorationsManager.cpp'
98--- decorations/DecorationsManager.cpp 2014-02-14 18:42:38 +0000
99+++ decorations/DecorationsManager.cpp 2014-03-12 23:07:10 +0000
100@@ -209,6 +209,7 @@
101 bool Manager::Impl::HandleEventBefore(XEvent* event)
102 {
103 active_window_ = screen->activeWindow();
104+
105 switch (event->type)
106 {
107 case ClientMessage:
108
109=== modified file 'decorations/DecorationsPriv.h'
110--- decorations/DecorationsPriv.h 2014-02-23 21:55:29 +0000
111+++ decorations/DecorationsPriv.h 2014-03-12 23:07:10 +0000
112@@ -108,6 +108,7 @@
113 void ComputeShadowQuads();
114 void UpdateDecorationTextures();
115 void RenderDecorationTexture(Side, nux::Geometry const&);
116+ void Paint(GLMatrix const&, GLWindowPaintAttrib const&, CompRegion const&, unsigned mask);
117 void Draw(GLMatrix const&, GLWindowPaintAttrib const&, CompRegion const&, unsigned mask);
118
119 friend class Window;
120
121=== modified file 'decorations/DecorationsTitle.cpp'
122--- decorations/DecorationsTitle.cpp 2014-02-24 16:00:02 +0000
123+++ decorations/DecorationsTitle.cpp 2014-03-12 23:07:10 +0000
124@@ -61,6 +61,12 @@
125
126 void Title::RenderTexture()
127 {
128+ if (!texture_size_.width || !texture_size_.height)
129+ {
130+ SetTexture(nullptr);
131+ return;
132+ }
133+
134 auto state = focused() ? WidgetState::NORMAL : WidgetState::BACKDROP;
135 cu::CairoContext text_ctx(texture_size_.width, texture_size_.height, scale());
136 Style::Get()->DrawTitle(text(), state, text_ctx, texture_size_.width / scale(), texture_size_.height / scale());
137
138=== modified file 'launcher/SwitcherController.cpp'
139--- launcher/SwitcherController.cpp 2014-02-12 20:23:26 +0000
140+++ launcher/SwitcherController.cpp 2014-03-12 23:07:10 +0000
141@@ -69,7 +69,9 @@
142 {
143
144 Controller::Controller(WindowCreator const& create_window)
145- : detail_mode([this] { return detail_mode_; })
146+ : detail([this] { return impl_->model_ && impl_->model_->detail_selection(); },
147+ [this] (bool d) { if (impl_->model_) { impl_->model_->detail_selection = d; } return false; })
148+ , detail_mode([this] { return detail_mode_; })
149 , timeout_length(0)
150 , detail_on_timeout(true)
151 , detail_timeout_length(500)
152@@ -133,8 +135,7 @@
153 {
154 if (obj_->visible_)
155 {
156- if (IsDetailViewShown() &&
157- HasNextDetailRow())
158+ if (obj_->detail() && HasNextDetailRow())
159 {
160 NextDetailRow();
161 }
162@@ -149,8 +150,7 @@
163 {
164 if (obj_->visible_)
165 {
166- if (IsDetailViewShown() &&
167- HasPrevDetailRow())
168+ if (obj_->detail() && HasPrevDetailRow())
169 {
170 PrevDetailRow();
171 }
172@@ -176,11 +176,6 @@
173 return impl_->GetView();
174 }
175
176-bool Controller::IsDetailViewShown()
177-{
178- return impl_->IsDetailViewShown();
179-}
180-
181 void Controller::SetDetail(bool value, unsigned int min_windows)
182 {
183 impl_->SetDetail(value, min_windows);
184@@ -201,16 +196,11 @@
185 impl_->PrevDetail();
186 }
187
188-LayoutWindow::Vector Controller::ExternalRenderTargets()
189+LayoutWindow::Vector const& Controller::ExternalRenderTargets() const
190 {
191 return impl_->ExternalRenderTargets();
192 }
193
194-guint Controller::GetSwitcherInputWindowId() const
195-{
196- return impl_->GetSwitcherInputWindowId();
197-}
198-
199 bool Controller::IsShowDesktopDisabled() const
200 {
201 return show_desktop_disabled_;
202@@ -251,11 +241,6 @@
203 return impl_->view_built.connect(f);
204 }
205
206-void Controller::SetDetailOnTimeout(bool timeout)
207-{
208- detail_on_timeout = timeout;
209-}
210-
211 double Controller::Opacity() const
212 {
213 if (!impl_->view_window_)
214@@ -512,12 +497,16 @@
215 {
216 // FIXME We need to refactor SwitcherModel so we can add/remove icons without causing
217 // a crash. If you remove the last application in the list it crashes.
218+ obj_->detail.changed.emit(false);
219 model_->detail_selection = false;
220 Hide(false);
221 }
222
223 void Controller::Impl::HideWindow()
224 {
225+ if (model_->detail_selection())
226+ obj_->detail.changed.emit(false);
227+
228 main_layout_->RemoveChildObject(view_.GetPointer());
229
230 view_window_->SetOpacity(0.0f);
231@@ -591,20 +580,17 @@
232 return view_;
233 }
234
235-bool Controller::Impl::IsDetailViewShown()
236-{
237- return model_ && model_->detail_selection();
238-}
239-
240 void Controller::Impl::SetDetail(bool value, unsigned int min_windows)
241 {
242 if (value && model_->Selection()->AllowDetailViewInSwitcher() && model_->DetailXids().size() >= min_windows)
243 {
244 model_->detail_selection = true;
245 obj_->detail_mode_ = DetailMode::TAB_NEXT_WINDOW;
246+ obj_->detail.changed.emit(true);
247 }
248 else
249 {
250+ obj_->detail.changed.emit(false);
251 model_->detail_selection = false;
252 }
253 }
254@@ -673,22 +659,17 @@
255 return model_->HasPrevDetailRow();
256 }
257
258-LayoutWindow::Vector Controller::Impl::ExternalRenderTargets()
259+LayoutWindow::Vector const& Controller::Impl::ExternalRenderTargets() const
260 {
261 if (!view_)
262 {
263- LayoutWindow::Vector result;
264- return result;
265+ static LayoutWindow::Vector empty_list;
266+ return empty_list;
267 }
268+
269 return view_->ExternalTargets();
270 }
271
272-guint Controller::Impl::GetSwitcherInputWindowId() const
273-{
274- return view_window_->GetInputWindowId();
275-}
276-
277-
278 Selection Controller::Impl::GetCurrentSelection() const
279 {
280 AbstractLauncherIcon::Ptr application;
281@@ -712,7 +693,6 @@
282 return {application, window};
283 }
284
285-
286 void Controller::Impl::SelectFirstItem()
287 {
288 if (!model_)
289@@ -743,7 +723,7 @@
290 for (auto& window : first->Windows())
291 {
292 Window xid = window->window_id();
293-
294+
295 if (model_->only_detail_on_viewport && !wm.IsWindowOnCurrentDesktop(xid))
296 continue;
297
298
299=== modified file 'launcher/SwitcherController.h'
300--- launcher/SwitcherController.h 2013-11-14 00:17:19 +0000
301+++ launcher/SwitcherController.h 2014-03-12 23:07:10 +0000
302@@ -107,9 +107,7 @@
303
304 nux::ObjectPtr<SwitcherView> GetView() const;
305
306- ui::LayoutWindow::Vector ExternalRenderTargets();
307-
308- guint GetSwitcherInputWindowId() const;
309+ ui::LayoutWindow::Vector const& ExternalRenderTargets() const;
310
311 bool IsShowDesktopDisabled() const;
312 void SetShowDesktopDisabled(bool disabled);
313@@ -123,12 +121,12 @@
314 Selection GetCurrentSelection() const;
315
316 sigc::connection ConnectToViewBuilt(sigc::slot<void> const&);
317- void SetDetailOnTimeout(bool timeout);
318
319 // Introspectable methods
320 std::string GetName() const;
321 void AddProperties(debug::IntrospectionData&);
322
323+ nux::RWProperty<bool> detail;
324 nux::ROProperty<DetailMode> detail_mode;
325 nux::Property<int> timeout_length;
326 nux::Property<bool> detail_on_timeout;
327
328=== modified file 'launcher/SwitcherControllerImpl.h'
329--- launcher/SwitcherControllerImpl.h 2013-11-19 18:48:35 +0000
330+++ launcher/SwitcherControllerImpl.h 2014-03-12 23:07:10 +0000
331@@ -71,10 +71,7 @@
332 void SelectFirstItem();
333
334 virtual SwitcherView::Ptr GetView() const;
335-
336- ui::LayoutWindow::Vector ExternalRenderTargets();
337-
338- guint GetSwitcherInputWindowId() const;
339+ ui::LayoutWindow::Vector const& ExternalRenderTargets() const;
340
341 int StartIndex() const;
342 Selection GetCurrentSelection() const;
343
344=== modified file 'launcher/SwitcherView.cpp'
345--- launcher/SwitcherView.cpp 2014-02-14 04:23:23 +0000
346+++ launcher/SwitcherView.cpp 2014-03-12 23:07:10 +0000
347@@ -141,7 +141,7 @@
348 return introspection_results;
349 }
350
351-LayoutWindow::Vector SwitcherView::ExternalTargets ()
352+LayoutWindow::Vector const& SwitcherView::ExternalTargets() const
353 {
354 return render_targets_;
355 }
356@@ -588,8 +588,8 @@
357
358 for (LayoutWindow::Ptr const& win : render_targets_)
359 {
360- auto final_geo = win->result;
361- win->result = final_geo * progress;
362+ win->scale *= progress;
363+ win->result = win->result * progress;
364 win->result.x += layout_abs_center.x;
365 win->result.y += layout_abs_center.y;
366 }
367@@ -934,7 +934,7 @@
368 if (render_boxes)
369 {
370 float val = 0.1f;
371- for (LayoutWindow::Ptr const& layout : ExternalTargets())
372+ for (LayoutWindow::Ptr const& layout : render_targets_)
373 {
374 gPainter.Paint2DQuadColor(GfxContext, layout->result, nux::Color(val, val, val ,val));
375 val += 0.1f;
376
377=== modified file 'launcher/SwitcherView.h'
378--- launcher/SwitcherView.h 2013-11-21 16:06:58 +0000
379+++ launcher/SwitcherView.h 2014-03-12 23:07:10 +0000
380@@ -51,7 +51,7 @@
381
382 SwitcherView();
383
384- ui::LayoutWindow::Vector ExternalTargets();
385+ ui::LayoutWindow::Vector const& ExternalTargets() const;
386
387 void SetModel(SwitcherModel::Ptr model);
388 SwitcherModel::Ptr GetModel();
389
390=== modified file 'panel/PanelMenuView.cpp'
391--- panel/PanelMenuView.cpp 2014-03-12 23:07:10 +0000
392+++ panel/PanelMenuView.cpp 2014-03-12 23:07:10 +0000
393@@ -131,6 +131,7 @@
394 auto const& deco_style = decoration::Style::Get();
395 lim_changed_connection_ = deco_style->integrated_menus.changed.connect([this] (bool lim) {
396 integrated_menus_ = lim;
397+ new_application_ = nullptr;
398 if (!integrated_menus_)
399 {
400 auto mouse = nux::GetGraphicsDisplay()->GetMouseScreenCoord();
401@@ -928,11 +929,16 @@
402 {
403 last_active_view_ = nullptr;
404
405- if (integrated_menus_ && is_maximized_)
406+ if (!integrated_menus_ || is_maximized_)
407 {
408 auto mouse = nux::GetGraphicsDisplay()->GetMouseScreenCoord();
409- is_inside_ = GetAbsoluteGeometry().IsInside(mouse);
410- FullRedraw();
411+ bool inside = GetAbsoluteGeometry().IsInside(mouse);
412+
413+ if (is_inside_ != inside)
414+ {
415+ is_inside_ = inside;
416+ QueueDraw();
417+ }
418 }
419 }
420
421@@ -981,7 +987,7 @@
422
423 void PanelMenuView::OnApplicationClosed(BamfApplication* app)
424 {
425- if (BAMF_IS_APPLICATION(app))
426+ if (BAMF_IS_APPLICATION(app) && !integrated_menus_)
427 {
428 if (std::find(new_apps_.begin(), new_apps_.end(), app) != new_apps_.end())
429 {
430@@ -1029,10 +1035,12 @@
431 {
432 if (BAMF_IS_APPLICATION(new_app))
433 {
434- app_name_changed_signal_.Disconnect();
435 app_name_changed_signal_.Connect(BAMF_VIEW(new_app), "name-changed",
436 sigc::mem_fun(this, &PanelMenuView::OnNameChanged));
437
438+ if (integrated_menus_)
439+ return;
440+
441 if (std::find(new_apps_.begin(), new_apps_.end(), new_app) != new_apps_.end())
442 {
443 if (new_application_ != new_app)
444@@ -1152,6 +1160,11 @@
445 if (Refresh())
446 QueueDraw();
447 }
448+ else if (integrated_menus_ && window_buttons_->controlled_window == xid)
449+ {
450+ if (Refresh())
451+ QueueDraw();
452+ }
453 }
454
455 void PanelMenuView::OnWindowUnminimized(Window xid)
456@@ -1164,6 +1177,11 @@
457 if (Refresh())
458 QueueDraw();
459 }
460+ else if (integrated_menus_ && IsWindowUnderOurControl(xid))
461+ {
462+ if (Refresh())
463+ QueueDraw();
464+ }
465 }
466
467 void PanelMenuView::OnWindowUnmapped(Window xid)
468@@ -1177,6 +1195,11 @@
469 if (Refresh())
470 QueueDraw();
471 }
472+ else if (integrated_menus_ && window_buttons_->controlled_window == xid)
473+ {
474+ if (Refresh())
475+ QueueDraw();
476+ }
477 }
478
479 void PanelMenuView::OnWindowMapped(Window xid)
480@@ -1207,6 +1230,11 @@
481 if (Refresh())
482 FullRedraw();
483 }
484+ else if (integrated_menus_ && IsWindowUnderOurControl(xid))
485+ {
486+ if (Refresh())
487+ QueueDraw();
488+ }
489 }
490
491 void PanelMenuView::OnWindowRestored(Window xid)
492@@ -1221,6 +1249,11 @@
493 if (Refresh())
494 FullRedraw();
495 }
496+ else if (integrated_menus_ && window_buttons_->controlled_window == xid)
497+ {
498+ if (Refresh())
499+ QueueDraw();
500+ }
501 }
502
503 bool PanelMenuView::UpdateActiveWindowPosition()
504
505=== modified file 'plugins/unityshell/src/unityshell.cpp'
506--- plugins/unityshell/src/unityshell.cpp 2014-03-12 23:07:10 +0000
507+++ plugins/unityshell/src/unityshell.cpp 2014-03-12 23:07:10 +0000
508@@ -391,9 +391,6 @@
509 ubus_manager_.RegisterInterest(UBUS_LAUNCHER_END_KEY_SWITCHER,
510 sigc::mem_fun(this, &UnityScreen::OnLauncherEndKeyNav));
511
512- ubus_manager_.RegisterInterest(UBUS_SWITCHER_END,
513- sigc::mem_fun(this, &UnityScreen::OnSwitcherEnd));
514-
515 auto init_plugins_cb = sigc::mem_fun(this, &UnityScreen::initPluginActions);
516 sources_.Add(std::make_shared<glib::Idle>(init_plugins_cb, glib::Source::Priority::DEFAULT));
517
518@@ -531,7 +528,11 @@
519 });
520
521 for (auto const& swin : sScreen->getWindows())
522- UnityWindow::get(swin->window)->OnInitiateSpread();
523+ {
524+ auto* uwin = UnityWindow::get(swin->window);
525+ fake_decorated_windows_.insert(uwin);
526+ uwin->OnInitiateSpread();
527+ }
528 }
529
530 void UnityScreen::OnTerminateSpread()
531@@ -540,6 +541,8 @@
532
533 for (auto const& swin : sScreen->getWindows())
534 UnityWindow::get(swin->window)->OnTerminateSpread();
535+
536+ fake_decorated_windows_.clear();
537 }
538
539 void UnityScreen::DamagePanelShadow()
540@@ -874,9 +877,9 @@
541 }
542 }
543
544- if (switcher_controller_->Opacity() > 0.0f)
545+ if (switcher_controller_->detail())
546 {
547- LayoutWindow::Vector const& targets = switcher_controller_->ExternalRenderTargets();
548+ auto const& targets = switcher_controller_->ExternalRenderTargets();
549
550 for (LayoutWindow::Ptr const& target : targets)
551 {
552@@ -1707,7 +1710,7 @@
553 if (CompWindow *w = screen->findWindow(sScreen->getSelectedWindow()))
554 skip_other_plugins = UnityWindow::get(w)->handleEvent(event);
555 }
556- else if (switcher_controller_->IsDetailViewShown())
557+ else if (switcher_controller_->detail())
558 {
559 Window win = switcher_controller_->GetCurrentSelection().window_;
560 CompWindow* w = screen->findWindow(win);
561@@ -1738,7 +1741,7 @@
562 skip_other_plugins = UnityWindow::get(w)->handleEvent(event);
563 }
564 }
565- else if (switcher_controller_->IsDetailViewShown())
566+ else if (switcher_controller_->detail())
567 {
568 Window win = switcher_controller_->GetCurrentSelection().window_;
569 CompWindow* w = screen->findWindow(win);
570@@ -1800,7 +1803,7 @@
571 break;
572 case ButtonRelease:
573
574- if (switcher_controller_->IsDetailViewShown())
575+ if (switcher_controller_->detail())
576 {
577 Window win = switcher_controller_->GetCurrentSelection().window_;
578 CompWindow* w = screen->findWindow(win);
579@@ -2307,13 +2310,13 @@
580 switcher_controller_->Select((switcher_controller_->StartIndex())); // always select the current application
581 switcher_controller_->InitiateDetail();
582 }
583- else if (switcher_controller_->IsDetailViewShown())
584+ else if (switcher_controller_->detail())
585 {
586 switcher_controller_->NextDetail();
587 }
588 else
589 {
590- switcher_controller_->SetDetail(true);
591+ switcher_controller_->detail = true;
592 }
593
594 action->setState(action->state() | CompAction::StateTermKey);
595@@ -2408,13 +2411,27 @@
596 PluginAdapter::Default().RestoreInputFocus();
597 }
598
599-void UnityScreen::OnSwitcherEnd(GVariant* data)
600+void UnityScreen::OnSwitcherDetailChanged(bool detail)
601 {
602- for (UnityWindow* uwin : fake_decorated_windows_)
603- {
604- uwin->close_icon_state_ = decoration::WidgetState::NORMAL;
605- uwin->middle_clicked_ = false;
606- uwin->CleanupCachedTextures();
607+ if (detail)
608+ {
609+ for (LayoutWindow::Ptr const& target : switcher_controller_->ExternalRenderTargets())
610+ {
611+ if (CompWindow* window = screen->findWindow(target->xid))
612+ {
613+ auto* uwin = UnityWindow::get(window);
614+ uwin->close_icon_state_ = decoration::WidgetState::NORMAL;
615+ uwin->middle_clicked_ = false;
616+ fake_decorated_windows_.insert(uwin);
617+ }
618+ }
619+ }
620+ else
621+ {
622+ for (UnityWindow* uwin : fake_decorated_windows_)
623+ uwin->CleanupCachedTextures();
624+
625+ fake_decorated_windows_.clear();
626 }
627 }
628
629@@ -2876,7 +2893,9 @@
630 wAttrib.brightness *= 0.75f;
631 }
632
633- return gWindow->glPaint(wAttrib, matrix, region, mask);
634+ bool ret = gWindow->glPaint(wAttrib, matrix, region, mask);
635+ deco_win_->Paint(matrix, wAttrib, region, mask);
636+ return ret;
637 }
638
639 /* handle window painting in an opengl context
640@@ -3486,7 +3505,7 @@
641 launcher_options->super_tap_duration = optionGetDashTapDuration();
642 break;
643 case UnityshellOptions::AltTabTimeout:
644- switcher_controller_->SetDetailOnTimeout(optionGetAltTabTimeout());
645+ switcher_controller_->detail_on_timeout = optionGetAltTabTimeout();
646 case UnityshellOptions::AltTabBiasViewport:
647 PluginAdapter::Default().bias_active_to_viewport = optionGetAltTabBiasViewport();
648 break;
649@@ -3707,6 +3726,7 @@
650 AddChild(launcher_controller_.get());
651
652 switcher_controller_ = std::make_shared<switcher::Controller>();
653+ switcher_controller_->detail.changed.connect(sigc::mem_fun(this, &UnityScreen::OnSwitcherDetailChanged));
654 AddChild(switcher_controller_.get());
655
656 LOG_INFO(logger) << "initLauncher-Launcher " << timer.ElapsedSeconds() << "s";
657@@ -3880,6 +3900,7 @@
658 , gWindow(GLWindow::get(window))
659 , close_icon_state_(decoration::WidgetState::NORMAL)
660 , deco_win_(uScreen->deco_manager_->HandleWindow(window))
661+ , need_fake_deco_redraw_(false)
662 , is_nux_window_(isNuxWindow(window))
663 {
664 WindowInterface::setHandler(window);
665@@ -4053,14 +4074,11 @@
666 {
667 mask |= PAINT_WINDOW_BLEND_MASK;
668
669+ if (!decoration_tex_ && compiz_utils::IsWindowFullyDecorable(window))
670+ BuildDecorationTexture();
671+
672 if (!highlighted)
673 {
674- if (!compiz_utils::IsWindowFullyDecorable(window))
675- return;
676-
677- if (!decoration_tex_)
678- BuildDecorationTexture();
679-
680 if (decoration_tex_)
681 DrawTexture(*decoration_tex_, attrib, transform, mask, geo.x, geo.y, scale);
682
683@@ -4103,7 +4121,14 @@
684 int text_x = padding.left + (close_texture ? close_texture->width() : 0) / dpi_scale;
685 RenderTitle(context, text_x, padding.top, (width - padding.right) / dpi_scale, height / dpi_scale, scale);
686 decoration_selected_tex_ = context;
687+ decoration_title_ = deco_win_->title();
688 uScreen->damageRegion(CompRegionFromNuxGeo(geo));
689+ need_fake_deco_redraw_ = true;
690+
691+ if (decoration_tex_)
692+ DrawTexture(*decoration_tex_, attrib, transform, mask, geo.x, geo.y, scale);
693+
694+ return; // Let's draw this at next repaint cycle
695 }
696 else
697 {
698@@ -4111,6 +4136,10 @@
699 redraw_decoration = false;
700 }
701 }
702+ else
703+ {
704+ need_fake_deco_redraw_ = false;
705+ }
706
707 if (decoration_selected_tex_)
708 DrawTexture(*decoration_selected_tex_, attrib, transform, mask, geo.x, geo.y);
709@@ -4147,7 +4176,7 @@
710
711 auto state = uScreen->sScreen->getState();
712
713- if (state != ScaleScreen::Wait && state != ScaleScreen::Out)
714+ if (state != ScaleScreen::Wait && state != ScaleScreen::Out && !need_fake_deco_redraw_)
715 return;
716
717 nux::Geometry const& scale_geo = GetScaledGeometry();
718
719=== modified file 'plugins/unityshell/src/unityshell.h'
720--- plugins/unityshell/src/unityshell.h 2014-03-12 23:07:10 +0000
721+++ plugins/unityshell/src/unityshell.h 2014-03-12 23:07:10 +0000
722@@ -278,8 +278,7 @@
723
724 void OnLauncherStartKeyNav(GVariant* data);
725 void OnLauncherEndKeyNav(GVariant* data);
726-
727- void OnSwitcherEnd(GVariant* data);
728+ void OnSwitcherDetailChanged(bool detail);
729
730 void OnInitiateSpread();
731 void OnTerminateSpread();
732@@ -558,6 +557,7 @@
733 nux::Geometry close_button_geo_;
734 std::shared_ptr<decoration::Window> deco_win_;
735 bool middle_clicked_;
736+ bool need_fake_deco_redraw_;
737 bool is_nux_window_;
738 glib::Source::UniquePtr focus_desktop_timeout_;
739
740
741=== modified file 'services/panel-service.c'
742--- services/panel-service.c 2014-03-11 14:10:50 +0000
743+++ services/panel-service.c 2014-03-12 23:07:10 +0000
744@@ -277,7 +277,7 @@
745 g_type_class_add_private (obj_class, sizeof (PanelServicePrivate));
746 }
747
748-static IndicatorObjectEntry *
749+IndicatorObjectEntry *
750 get_entry_at (PanelService *self, gint x, gint y)
751 {
752 GHashTableIter panel_iter, entries_iter;
753@@ -305,6 +305,37 @@
754 return NULL;
755 }
756
757+static IndicatorObjectEntry *
758+get_entry_at_panel (PanelService *self, const gchar *panel, gint x, gint y)
759+{
760+ GHashTable *entry2geometry_hash;
761+ GHashTableIter entries_iter;
762+ gpointer key, value;
763+
764+ if (!panel)
765+ return NULL;
766+
767+ entry2geometry_hash = g_hash_table_lookup (self->priv->panel2entries_hash, panel);
768+
769+ if (!entry2geometry_hash)
770+ return NULL;
771+
772+ g_hash_table_iter_init (&entries_iter, entry2geometry_hash);
773+ while (g_hash_table_iter_next (&entries_iter, &key, &value))
774+ {
775+ IndicatorObjectEntry *entry = key;
776+ GdkRectangle *geo = value;
777+
778+ if (x >= geo->x && x <= (geo->x + geo->width) &&
779+ y >= geo->y && y <= (geo->y + geo->height))
780+ {
781+ return entry;
782+ }
783+ }
784+
785+ return NULL;
786+}
787+
788 static const gchar*
789 get_panel_at (PanelService *self, gint x, gint y)
790 {
791@@ -493,7 +524,7 @@
792
793 case XI_ButtonPress:
794 {
795- priv->pressed_entry = get_entry_at (self, event->root_x, event->root_y);
796+ priv->pressed_entry = get_entry_at_panel (self, priv->last_panel, event->root_x, event->root_y);
797 priv->use_event = (priv->pressed_entry == NULL);
798
799 if (priv->pressed_entry)
800@@ -504,9 +535,9 @@
801
802 case XI_ButtonRelease:
803 {
804- IndicatorObjectEntry *entry;
805+ IndicatorObjectEntry *entry = NULL;
806 gboolean event_is_a_click = FALSE;
807- entry = get_entry_at (self, event->root_x, event->root_y);
808+ entry = get_entry_at_panel (self, priv->last_panel, event->root_x, event->root_y);
809
810 if (event->detail == 1 || event->detail == 3)
811 {
812@@ -1414,6 +1445,9 @@
813 static gchar *
814 gtk_image_to_data (GtkImage *image, guint32 *storage_type)
815 {
816+ if (!GTK_IS_IMAGE (image))
817+ return NULL;
818+
819 *storage_type = gtk_image_get_storage_type (image);
820 gchar *ret = NULL;
821
822@@ -1453,8 +1487,6 @@
823 g_warning ("Unable to convert pixbuf to png data: '%s'", error ? error->message : "unknown");
824 if (error)
825 g_error_free (error);
826-
827- ret = g_strdup ("");
828 }
829
830 break;
831@@ -1480,12 +1512,10 @@
832 }
833 case GTK_IMAGE_EMPTY:
834 {
835- ret = g_strdup ("");
836 break;
837 }
838 default:
839 {
840- ret = g_strdup ("");
841 g_warning ("Unable to support GtkImageType: %u", *storage_type);
842 }
843 }
844@@ -1513,7 +1543,7 @@
845 is_label ? gtk_widget_get_sensitive (GTK_WIDGET (entry->label)) : FALSE,
846 is_label ? gtk_widget_get_visible (GTK_WIDGET (entry->label)) : FALSE,
847 is_image ? image_type : 0,
848- is_image ? image_data : "",
849+ image_data ? image_data : "",
850 is_image ? gtk_widget_get_sensitive (GTK_WIDGET (entry->image)) : FALSE,
851 is_image ? gtk_widget_get_visible (GTK_WIDGET (entry->image)) : FALSE,
852 prio);
853@@ -1612,7 +1642,11 @@
854 PanelService *self = PANEL_SERVICE (user_data);
855 PanelServicePrivate *priv = self->priv;
856
857- gint scale = get_monitor_scale_at (priv->last_x, priv->last_y);
858+ GdkScreen *screen = gdk_screen_get_default ();
859+ gint monitor = gdk_screen_get_monitor_at_point (screen, priv->last_x, priv->last_y);
860+ gtk_menu_set_monitor (menu, monitor);
861+
862+ gint scale = gdk_screen_get_monitor_scale_factor (screen, monitor);
863 *x = priv->last_x / scale;
864 *y = priv->last_y / scale;
865 *push = TRUE;
866
867=== modified file 'tests/MockSwitcherController.h'
868--- tests/MockSwitcherController.h 2013-11-06 11:21:43 +0000
869+++ tests/MockSwitcherController.h 2014-03-12 23:07:10 +0000
870@@ -49,11 +49,9 @@
871 MOCK_CONST_METHOD1(CanShowSwitcher, bool(const std::vector<launcher::AbstractLauncherIcon::Ptr> &));
872 MOCK_METHOD0(NextDetail, void());
873 MOCK_METHOD0(PrevDetail, void());
874- MOCK_METHOD2(SetDetail, void(bool, unsigned int));
875 MOCK_METHOD0(SelectFirstItem, void());
876 MOCK_METHOD2(SetWorkspace, void(nux::Geometry, int));
877- MOCK_METHOD0(ExternalRenderTargets, unity::ui::LayoutWindow::Vector ());
878- MOCK_CONST_METHOD0(GetSwitcherInputWindowId, guint());
879+ MOCK_CONST_METHOD0(ExternalRenderTargets, unity::ui::LayoutWindow::Vector const&());
880 MOCK_CONST_METHOD0(IsShowDesktopDisabled, bool());
881 MOCK_METHOD1(SetShowDesktopDisabled, void(bool));
882 MOCK_CONST_METHOD0(StartIndex, int());
883
884=== modified file 'tests/test_switcher_controller.cpp'
885--- tests/test_switcher_controller.cpp 2013-11-19 18:33:11 +0000
886+++ tests/test_switcher_controller.cpp 2014-03-12 23:07:10 +0000
887@@ -83,27 +83,27 @@
888 {
889 controller_->Show(ShowMode::ALL, SortMode::LAUNCHER_ORDER, icons_);
890 controller_->InitiateDetail();
891- EXPECT_TRUE(controller_->IsDetailViewShown());
892+ EXPECT_TRUE(controller_->detail());
893
894 auto const& view = controller_->GetView();
895
896 view->switcher_stop_detail.emit();
897- EXPECT_FALSE(controller_->IsDetailViewShown());
898+ EXPECT_FALSE(controller_->detail());
899
900 view->switcher_start_detail.emit();
901- EXPECT_TRUE(controller_->IsDetailViewShown());
902+ EXPECT_TRUE(controller_->detail());
903 }
904
905 TEST_F(TestSwitcherController, StopDetailMode)
906 {
907 controller_->Show(ShowMode::ALL, SortMode::LAUNCHER_ORDER, icons_);
908 controller_->InitiateDetail();
909- EXPECT_TRUE(controller_->IsDetailViewShown());
910+ EXPECT_TRUE(controller_->detail());
911
912 auto const& view = controller_->GetView();
913
914 view->switcher_stop_detail.emit();
915- EXPECT_FALSE(controller_->IsDetailViewShown());
916+ EXPECT_FALSE(controller_->detail());
917 }
918
919 TEST_F(TestSwitcherController, StartDetailModeMovesNextRows)
920@@ -117,7 +117,7 @@
921 model->SetRowSizes({2,2});
922
923 view->switcher_start_detail.emit();
924- EXPECT_TRUE(controller_->IsDetailViewShown());
925+ EXPECT_TRUE(controller_->detail());
926
927 view->switcher_start_detail.emit();
928
929@@ -137,7 +137,7 @@
930 auto const& view = controller_->GetView();
931
932 view->switcher_start_detail.emit();
933- EXPECT_TRUE(controller_->IsDetailViewShown());
934+ EXPECT_TRUE(controller_->detail());
935
936 auto model = view->GetModel();
937 model->SetRowSizes({2,2});
938@@ -153,7 +153,7 @@
939
940 // Now we are in index 0, stoping detail mode must exit detail mode
941 view->switcher_stop_detail.emit();
942- EXPECT_FALSE(controller_->IsDetailViewShown());
943+ EXPECT_FALSE(controller_->detail());
944 }
945
946 TEST_F(TestSwitcherController, ShowSwitcher)
947
948=== modified file 'tests/test_switcher_controller_slow.cpp'
949--- tests/test_switcher_controller_slow.cpp 2013-05-17 22:03:08 +0000
950+++ tests/test_switcher_controller_slow.cpp 2014-03-12 23:07:10 +0000
951@@ -107,8 +107,8 @@
952 EXPECT_EQ(controller_->GetCurrentSelection().window_, 0);
953
954 // Manually open-close the detail mode before that the timeout has occurred
955- controller_->SetDetail(true);
956- controller_->SetDetail(false);
957+ controller_->detail = true;
958+ controller_->detail = false;
959
960 Utils::WaitForTimeoutMSec(initial_details_timeout * 1.1);
961 EXPECT_EQ(controller_->GetCurrentSelection().window_, 0);
962
963=== modified file 'unity-shared/CompizUtils.cpp'
964--- unity-shared/CompizUtils.cpp 2014-02-24 16:00:02 +0000
965+++ unity-shared/CompizUtils.cpp 2014-03-12 23:07:10 +0000
966@@ -110,9 +110,13 @@
967 //
968
969 PixmapTexture::PixmapTexture(int w, int h)
970- : pixmap_(XCreatePixmap(screen->dpy(), screen->root(), w, h, PIXMAP_DEPTH))
971+ : pixmap_(0)
972 {
973- texture_ = GLTexture::bindPixmapToTexture(pixmap_, w, h, PIXMAP_DEPTH);
974+ if (w > 0 && h > 0)
975+ {
976+ pixmap_ = XCreatePixmap(screen->dpy(), screen->root(), w, h, PIXMAP_DEPTH);
977+ texture_ = GLTexture::bindPixmapToTexture(pixmap_, w, h, PIXMAP_DEPTH);
978+ }
979 }
980
981 PixmapTexture::~PixmapTexture()
982
983=== modified file 'unity-shared/PluginAdapter.cpp'
984--- unity-shared/PluginAdapter.cpp 2014-03-05 14:18:31 +0000
985+++ unity-shared/PluginAdapter.cpp 2014-03-12 23:07:10 +0000
986@@ -699,21 +699,14 @@
987 if (window && (window->state() & MAXIMIZE_STATE))
988 {
989 nux::Geometry new_geo(GetWindowSavedGeometry(window_id));
990- decoration::Border border;
991- double scale = 1.0f;
992-
993- if (compiz_utils::IsWindowFullyDecorable(window))
994- {
995- auto& settings = Settings::Instance();
996- border = decoration::Style::Get()->Border();
997- scale = settings.em(MonitorGeometryIn(new_geo))->DPIScale();
998- }
999-
1000+ window->maximize(0);
1001+
1002+ auto const& border = window->border();
1003 new_geo.x = x;
1004- new_geo.y = y;
1005- new_geo.width -= (border.left - border.right) * scale;
1006- new_geo.height -= (border.top - border.bottom) * scale;
1007- window->maximize(0);
1008+ new_geo.y = y + border.top;
1009+ new_geo.width -= (border.left + border.right);
1010+ new_geo.height -= (border.top + border.bottom);
1011+
1012 MoveResizeWindow(window_id, new_geo);
1013 }
1014 }