Merge lp:~3v1n0/unity/lim-visibility-fixes into lp:unity

Proposed by Marco Trevisan (Treviño)
Status: Merged
Approved by: Stephen M. Webb
Approved revision: no longer in the source branch.
Merged at revision: 3907
Proposed branch: lp:~3v1n0/unity/lim-visibility-fixes
Merge into: lp:unity
Diff against target: 845 lines (+217/-96)
17 files modified
UnityCore/AppmenuIndicator.cpp (+24/-0)
UnityCore/AppmenuIndicator.h (+8/-0)
com.canonical.Unity.gschema.xml (+8/-0)
decorations/DecoratedWindow.cpp (+24/-14)
decorations/DecorationsForceQuitDialog.cpp (+24/-18)
decorations/DecorationsManager.cpp (+10/-3)
decorations/DecorationsSlidingLayout.cpp (+14/-8)
decorations/DecorationsSlidingLayout.h (+2/-0)
panel/PanelMenuView.cpp (+63/-32)
panel/PanelMenuView.h (+4/-1)
plugins/unityshell/src/unityshell.cpp (+1/-1)
unity-shared/DecorationStyle.cpp (+0/-1)
unity-shared/DecorationStyle.h (+0/-1)
unity-shared/MenuManager.cpp (+27/-4)
unity-shared/MenuManager.h (+5/-1)
unity-shared/UScreen.cpp (+3/-6)
unity-shared/UnitySettings.cpp (+0/-6)
To merge this branch: bzr merge lp:~3v1n0/unity/lim-visibility-fixes
Reviewer Review Type Date Requested Status
Christopher Townsend (community) Approve
PS Jenkins bot (community) continuous-integration Approve
Stephen M. Webb (community) Approve
Review via email: mp+245189@code.launchpad.net

Commit message

MenuManager: make sure menus are always shown when mouse is over them or when the always-show-menus option is on

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Stephen M. Webb (bregma) wrote :

Builds OK (thanks for nothing, Jenkins).

Will do more rigourous testing from the landing silo.

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

Ok

review: Approve
Revision history for this message
Christopher Townsend (townsend) wrote :

lol, I meant to approve the SRU branch. My Firefox tabs got me confused:)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'UnityCore/AppmenuIndicator.cpp'
2--- UnityCore/AppmenuIndicator.cpp 2012-12-04 00:33:18 +0000
3+++ UnityCore/AppmenuIndicator.cpp 2015-01-15 14:44:53 +0000
4@@ -17,6 +17,7 @@
5 * Authored by: Marco Trevisan (Treviño) <3v1n0@ubuntu.com>
6 */
7
8+#include "GLibSource.h"
9 #include "AppmenuIndicator.h"
10
11 namespace unity
12@@ -24,8 +25,31 @@
13 namespace indicator
14 {
15
16+struct AppmenuIndicator::Impl
17+{
18+ Impl(AppmenuIndicator* parent)
19+ {
20+ // When the active window has changed we might need to emit an updated signal
21+ parent->active_window.changed.connect([this, parent] (unsigned long) {
22+ update_wait_.reset(new glib::Timeout(250, [parent] {
23+ parent->updated.emit();
24+ return false;
25+ }));
26+ });
27+
28+ parent->updated.connect([this] { update_wait_.reset(); });
29+ }
30+
31+ glib::Source::UniquePtr update_wait_;
32+};
33+
34 AppmenuIndicator::AppmenuIndicator(std::string const& name)
35 : Indicator(name)
36+ , active_window(0)
37+ , impl_(new AppmenuIndicator::Impl(this))
38+{}
39+
40+AppmenuIndicator::~AppmenuIndicator()
41 {}
42
43 void AppmenuIndicator::ShowAppmenu(unsigned int xid, int x, int y) const
44
45=== modified file 'UnityCore/AppmenuIndicator.h'
46--- UnityCore/AppmenuIndicator.h 2014-02-12 00:51:09 +0000
47+++ UnityCore/AppmenuIndicator.h 2015-01-15 14:44:53 +0000
48@@ -20,6 +20,7 @@
49 #ifndef UNITY_APPMENU_INDICATOR_H
50 #define UNITY_APPMENU_INDICATOR_H
51
52+#include <NuxCore/Property.h>
53 #include "Indicator.h"
54
55 namespace unity
56@@ -33,12 +34,19 @@
57 typedef std::shared_ptr<AppmenuIndicator> Ptr;
58
59 AppmenuIndicator(std::string const& name);
60+ ~AppmenuIndicator();
61+
62+ nux::Property<unsigned> active_window;
63
64 virtual bool IsAppmenu() const { return true; }
65
66 void ShowAppmenu(unsigned xid, int x, int y) const;
67
68 sigc::signal<void, unsigned, int, int> on_show_appmenu;
69+
70+private:
71+ struct Impl;
72+ std::unique_ptr<Impl> impl_;
73 };
74
75 }
76
77=== modified file 'com.canonical.Unity.gschema.xml'
78--- com.canonical.Unity.gschema.xml 2014-09-10 12:48:03 +0000
79+++ com.canonical.Unity.gschema.xml 2015-01-15 14:44:53 +0000
80@@ -53,6 +53,14 @@
81 on the window decoration, otherwise they will be always shown on the
82 unity top panel</description>
83 </key>
84+ <key type="b" name="always-show-menus">
85+ <default>false</default>
86+ <summary>Toggle the menu visibility based on mouse hovering.</summary>
87+ <description>When this is enabled, the application menus will be always
88+ shown (on the window decoration or in the unity panel, depending whether
89+ integrated menus are enabled), otherwise they will be shown only when
90+ the mouse cursor is over the relative mouse area.</description>
91+ </key>
92 </schema>
93 <schema path="/com/canonical/unity/interface/" id="com.canonical.Unity.Interface" gettext-domain="unity">
94 <key type="d" name="text-scale-factor">
95
96=== modified file 'decorations/DecoratedWindow.cpp'
97--- decorations/DecoratedWindow.cpp 2014-11-28 12:55:13 +0000
98+++ decorations/DecoratedWindow.cpp 2015-01-15 14:44:53 +0000
99@@ -708,16 +708,14 @@
100 auto const& sliding_layout = sliding_layout_.lock();
101 sliding_layout->SetInputItem(nullptr);
102 sliding_layout->mouse_owner = false;
103+ sliding_layout->override_main_item = false;
104+ grab_mouse_changed_->disconnect();
105
106- if (!menu_manager->HasAppMenu() || !Style::Get()->integrated_menus())
107+ if (!menu_manager->HasAppMenu() || !menu_manager->integrated_menus())
108 return;
109
110- auto visibility_cb = sigc::hide(sigc::mem_fun(this, &Impl::UpdateAppMenuVisibility));
111 auto menus = std::make_shared<MenuLayout>(menu_manager, win_);
112 menus->Setup();
113- menus->active.changed.connect(visibility_cb);
114- menus->show_now.changed.connect(visibility_cb);
115- menus->mouse_owner.changed.connect(visibility_cb);
116 menus_ = menus;
117
118 auto const& grab_edge = grab_edge_.lock();
119@@ -725,15 +723,27 @@
120 sliding_layout->fadein = menu_manager->fadein();
121 sliding_layout->fadeout = menu_manager->fadeout();
122
123- if (grab_edge->mouse_owner() || grab_edge->Geometry().contains(CompPoint(pointerX, pointerY)))
124- sliding_layout->mouse_owner = true;
125-
126- grab_mouse_changed_ = grab_edge->mouse_owner.changed.connect([this] (bool owner) {
127- sliding_layout_->mouse_owner = owner;
128- });
129-
130- if (sliding_layout->mouse_owner())
131- input_mixer_->ForceMouseOwnerCheck();
132+ if (menu_manager->always_show_menus())
133+ {
134+ sliding_layout->override_main_item = true;
135+ }
136+ else
137+ {
138+ auto visibility_cb = sigc::hide(sigc::mem_fun(this, &Impl::UpdateAppMenuVisibility));
139+ menus->active.changed.connect(visibility_cb);
140+ menus->show_now.changed.connect(visibility_cb);
141+ menus->mouse_owner.changed.connect(visibility_cb);
142+
143+ if (grab_edge->mouse_owner() || grab_edge->Geometry().contains(CompPoint(pointerX, pointerY)))
144+ sliding_layout->mouse_owner = true;
145+
146+ grab_mouse_changed_ = grab_edge->mouse_owner.changed.connect([this] (bool owner) {
147+ sliding_layout_->mouse_owner = owner || menus_->show_now();
148+ });
149+
150+ if (sliding_layout->mouse_owner())
151+ input_mixer_->ForceMouseOwnerCheck();
152+ }
153
154 SyncMenusGeometries();
155 }
156
157=== modified file 'decorations/DecorationsForceQuitDialog.cpp'
158--- decorations/DecorationsForceQuitDialog.cpp 2015-01-12 18:30:09 +0000
159+++ decorations/DecorationsForceQuitDialog.cpp 2015-01-15 14:44:53 +0000
160@@ -97,6 +97,20 @@
161 static void close_button_init(CloseButton*);
162 static void close_button_class_init(CloseButtonClass*);
163
164+bool gdk_error_trap_pop_with_output(std::string const& prefix)
165+{
166+ if (int error_code = gdk_error_trap_pop())
167+ {
168+ gchar tmp[1024];
169+ XGetErrorText(gdk_x11_get_default_xdisplay(), error_code, tmp, sizeof(tmp) - 1);
170+ tmp[sizeof(tmp) - 1] = '\0';
171+ LOG_ERROR(logger) << (prefix.empty() ? "X error: " : prefix+": ") << tmp;
172+ return true;
173+ }
174+
175+ return false;
176+}
177+
178 // Window implementation
179 GtkWidget* sheet_style_window_new(ForceQuitDialog* main_dialog, Window parent_xid)
180 {
181@@ -112,15 +126,20 @@
182 gtk_window_set_deletable(self, FALSE);
183 gtk_window_set_title(self, "Force Quit Dialog");
184
185+ gdk_error_trap_push();
186 XClassHint parent_class = {nullptr, nullptr};
187 XGetClassHint(dpy, parent_xid, &parent_class);
188- gtk_window_set_wmclass(self, parent_class.res_name, parent_class.res_class);
189+
190+ if (!gdk_error_trap_pop_with_output("Impossible to get window class"))
191+ gtk_window_set_wmclass(self, parent_class.res_name, parent_class.res_class);
192+
193 XFree(parent_class.res_class);
194 XFree(parent_class.res_name);
195
196 Atom WM_PID = gdk_x11_get_xatom_by_name("_NET_WM_PID");
197 Atom WM_CLIENT_MACHINE = gdk_x11_get_xatom_by_name("WM_CLIENT_MACHINE");
198
199+ gdk_error_trap_push();
200 auto& wm = WindowManager::Default();
201 auto parent_hostname = wm.GetStringProperty(parent_xid, WM_CLIENT_MACHINE);
202 long parent_pid = 0;
203@@ -139,6 +158,8 @@
204 }
205 }
206
207+ gdk_error_trap_pop_with_output("Impossible to get window client machine and PID");
208+
209 auto const& deco_style = decoration::Style::Get();
210 auto const& offset = deco_style->ShadowOffset();
211 int max_offset = std::max(std::abs(offset.x * 4), std::abs(offset.y * 4));
212@@ -162,14 +183,7 @@
213 auto xid = gdk_x11_window_get_xid(gwindow);
214 XSetTransientForHint(dpy, xid, parent_xid);
215 XSync(dpy, False);
216-
217- if (int error_code = gdk_error_trap_pop())
218- {
219- gchar tmp[1024];
220- XGetErrorText(dpy, error_code, tmp, sizeof(tmp) - 1);
221- tmp[sizeof(tmp) - 1] = '\0';
222- LOG_ERROR(logger) << "Impossible to reparent dialog: " << tmp;
223- }
224+ gdk_error_trap_pop_with_output("Impossible to reparent dialog");
225
226 XChangeProperty(dpy, xid, WM_CLIENT_MACHINE, XA_STRING, 8, PropModeReplace,
227 (unsigned char *) parent_hostname.c_str(), parent_hostname.size());
228@@ -227,17 +241,9 @@
229
230 gdk_error_trap_push();
231 XSync(dpy, False);
232-
233- if (int error_code = gdk_error_trap_pop())
234- {
235- gchar tmp[1024];
236- XGetErrorText(dpy, error_code, tmp, sizeof(tmp) - 1);
237- tmp[sizeof(tmp) - 1] = '\0';
238- LOG_ERROR(logger) << "Impossible to kill window " << parent_xid << ": " << tmp;
239- }
240-
241 XKillClient(dpy, parent_xid);
242 XSync(dpy, False);
243+ gdk_error_trap_pop_with_output("Impossible to kill window "+std::to_string(parent_xid));
244
245 if (parent_pid > 0)
246 kill(parent_pid, 9);
247
248=== modified file 'decorations/DecorationsManager.cpp'
249--- decorations/DecorationsManager.cpp 2014-10-22 14:38:06 +0000
250+++ decorations/DecorationsManager.cpp 2015-01-15 14:44:53 +0000
251@@ -58,7 +58,7 @@
252 manager_->inactive_shadow_color.changed.connect(sigc::hide(sigc::bind(rebuild_cb, false)));
253 manager_->inactive_shadow_radius.changed.connect(sigc::hide(sigc::bind(rebuild_cb, false)));
254 manager_->shadow_offset.changed.connect(sigc::hide(sigc::mem_fun(this, &Impl::UpdateWindowsExtents)));
255- Style::Get()->integrated_menus.changed.connect(sigc::hide(sigc::mem_fun(this, &Impl::SetupIntegratedMenus)));
256+ menu_manager_->integrated_menus.changed.connect(sigc::hide(sigc::mem_fun(this, &Impl::SetupIntegratedMenus)));
257
258 BuildInactiveShadowTexture();
259 BuildActiveShadowTexture();
260@@ -110,7 +110,7 @@
261
262 void Manager::Impl::SetupIntegratedMenus()
263 {
264- if (!Style::Get()->integrated_menus())
265+ if (!menu_manager_->integrated_menus())
266 {
267 UnsetAppMenu();
268 menu_connections_.Clear();
269@@ -120,6 +120,7 @@
270 menu_connections_.Add(menu_manager_->appmenu_added.connect(sigc::mem_fun(this, &Impl::SetupAppMenu)));
271 menu_connections_.Add(menu_manager_->appmenu_removed.connect(sigc::mem_fun(this, &Impl::UnsetAppMenu)));
272 menu_connections_.Add(menu_manager_->key_activate_entry.connect(sigc::mem_fun(this, &Impl::OnMenuKeyActivated)));
273+ menu_connections_.Add(menu_manager_->always_show_menus.changed.connect(sigc::hide(sigc::mem_fun(this, &Impl::SetupAppMenu))));
274
275 SetupAppMenu();
276 }
277@@ -140,6 +141,8 @@
278 return;
279 }
280
281+ appmenu->active_window = screen->activeWindow();
282+
283 auto setup_active_window = [this] {
284 if (Window::Ptr const& active_win = active_deco_win_.lock())
285 active_win->impl_->SetupAppMenu();
286@@ -256,11 +259,15 @@
287 if (active_deco_win_)
288 active_deco_win_->impl_->active = false;
289
290- auto const& new_active = GetWindowByXid(screen->activeWindow());
291+ auto active_xid = screen->activeWindow();
292+ auto const& new_active = GetWindowByXid(active_xid);
293 active_deco_win_ = new_active;
294
295 if (new_active)
296 new_active->impl_->active = true;
297+
298+ if (indicator::AppmenuIndicator::Ptr const& appmenu = menu_manager_->AppMenu())
299+ appmenu->active_window = active_xid;
300 }
301 else if (event->xproperty.atom == Atoms::mwmHints ||
302 event->xproperty.atom == Atoms::wmAllowedActions)
303
304=== modified file 'decorations/DecorationsSlidingLayout.cpp'
305--- decorations/DecorationsSlidingLayout.cpp 2014-02-24 15:50:23 +0000
306+++ decorations/DecorationsSlidingLayout.cpp 2015-01-15 14:44:53 +0000
307@@ -37,17 +37,13 @@
308 SlidingLayout::SlidingLayout()
309 : fadein(100)
310 , fadeout(120)
311+ , override_main_item(false)
312 , fade_animator_(fadein())
313 {
314 items_.resize(2);
315 fade_animator_.updated.connect(sigc::hide(sigc::mem_fun(this, &SlidingLayout::Damage)));
316- mouse_owner.changed.connect([this] (bool owner) {
317- if (items_[ItemRole::INPUT])
318- {
319- fade_animator_.SetDuration(owner ? fadein() : fadeout());
320- animation::StartOrReverseIf(fade_animator_, owner);
321- }
322- });
323+ mouse_owner.changed.connect(sigc::hide(sigc::mem_fun(this, &SlidingLayout::StartAnimation)));
324+ override_main_item.changed.connect(sigc::hide(sigc::mem_fun(this, &SlidingLayout::StartAnimation)));
325 }
326
327 void SlidingLayout::SetMainItem(Item::Ptr const& main)
328@@ -126,6 +122,16 @@
329 rect_.setHeight(contents.height);
330 }
331
332+void SlidingLayout::StartAnimation()
333+{
334+ if (items_[ItemRole::INPUT])
335+ {
336+ bool show_input = (mouse_owner() || override_main_item());
337+ fade_animator_.SetDuration(show_input ? fadein() : fadeout());
338+ animation::StartOrReverseIf(fade_animator_, show_input);
339+ }
340+}
341+
342 void SlidingLayout::Draw(GLWindow* ctx, GLMatrix const& transformation, GLWindowPaintAttrib const& attrib, CompRegion const& clip, unsigned mask)
343 {
344 auto& main_item_ = items_[ItemRole::MAIN];
345@@ -152,7 +158,7 @@
346 }
347 else
348 {
349- auto const& draw_area = mouse_owner() ? input_item_ : main_item_;
350+ auto const& draw_area = (mouse_owner() || override_main_item()) ? input_item_ : main_item_;
351 draw_area->Draw(ctx, transformation, attrib, clip, mask);
352 }
353 }
354
355=== modified file 'decorations/DecorationsSlidingLayout.h'
356--- decorations/DecorationsSlidingLayout.h 2014-02-13 07:31:31 +0000
357+++ decorations/DecorationsSlidingLayout.h 2015-01-15 14:44:53 +0000
358@@ -37,6 +37,7 @@
359
360 nux::Property<unsigned> fadein;
361 nux::Property<unsigned> fadeout;
362+ nux::Property<bool> override_main_item;
363
364 void SetMainItem(Item::Ptr const& main);
365 void SetInputItem(Item::Ptr const& input);
366@@ -47,6 +48,7 @@
367
368 private:
369 void DoRelayout() override;
370+ void StartAnimation();
371
372 nux::animation::AnimateValue<double> fade_animator_;
373 };
374
375=== modified file 'panel/PanelMenuView.cpp'
376--- panel/PanelMenuView.cpp 2014-10-24 13:57:11 +0000
377+++ panel/PanelMenuView.cpp 2015-01-15 14:44:53 +0000
378@@ -65,7 +65,7 @@
379 {
380 while (getline(fin, temp))
381 {
382- if (temp.substr(0,4) == "NAME")
383+ if (temp.substr(0, 4) == "NAME")
384 {
385 os_release_name = boost::erase_all_copy(temp.substr(temp.find_last_of('=')+1), "\"");
386 break;
387@@ -98,7 +98,8 @@
388 , we_control_active_(false)
389 , new_app_menu_shown_(false)
390 , ignore_menu_visibility_(false)
391- , integrated_menus_(decoration::Style::Get()->integrated_menus())
392+ , integrated_menus_(menu_manager_->integrated_menus())
393+ , always_show_menus_(menu_manager_->always_show_menus())
394 , active_xid_(0)
395 , desktop_name_(get_current_desktop())
396 {
397@@ -154,19 +155,8 @@
398 entry_added.connect(sigc::mem_fun(this, &PanelMenuView::OnEntryViewAdded));
399 Style::Instance().changed.connect(sigc::mem_fun(this, &PanelMenuView::OnStyleChanged));
400
401- auto const& deco_style = decoration::Style::Get();
402- lim_changed_connection_ = deco_style->integrated_menus.changed.connect([this] (bool lim) {
403- integrated_menus_ = lim;
404- new_application_ = nullptr;
405- if (!integrated_menus_)
406- {
407- auto mouse = nux::GetGraphicsDisplay()->GetMouseScreenCoord();
408- is_inside_ = GetAbsoluteGeometry().IsInside(mouse);
409- window_buttons_->focused = true;
410- }
411- Refresh(true);
412- FullRedraw();
413- });
414+ menu_manager_->integrated_menus.changed.connect(sigc::mem_fun(this, &PanelMenuView::OnLIMChanged));
415+ menu_manager_->always_show_menus.changed.connect(sigc::mem_fun(this, &PanelMenuView::OnAlwaysShowMenusChanged));
416 }
417
418 void PanelMenuView::SetupWindowButtons()
419@@ -268,6 +258,31 @@
420 window_buttons_->QueueDraw();
421 }
422
423+void PanelMenuView::OnLIMChanged(bool lim)
424+{
425+ integrated_menus_ = lim;
426+ new_application_ = nullptr;
427+
428+ if (!integrated_menus_)
429+ {
430+ CheckMouseInside();
431+ window_buttons_->focused = true;
432+ }
433+
434+ Refresh(true);
435+ FullRedraw();
436+}
437+
438+void PanelMenuView::OnAlwaysShowMenusChanged(bool always_show_menus)
439+{
440+ always_show_menus_ = always_show_menus;
441+
442+ if (!always_show_menus_)
443+ CheckMouseInside();
444+
445+ FullRedraw();
446+}
447+
448 nux::Area* PanelMenuView::FindAreaUnderMouse(const nux::Point& mouse_position, nux::NuxEventType event_type)
449 {
450 bool mouse_inside = TestMousePointerInclusionFilterMouseWheel(mouse_position, event_type);
451@@ -376,7 +391,7 @@
452
453 if (!wm.IsExpoActive() && !wm.IsScaleActive())
454 {
455- if (is_inside_ || last_active_view_ || show_now_activated_ || new_application_)
456+ if (is_inside_ || last_active_view_ || show_now_activated_ || new_application_ || always_show_menus_)
457 return true;
458
459 if (is_maximized_)
460@@ -404,7 +419,7 @@
461 {
462 if (!WindowManager::Default().IsExpoActive())
463 {
464- if (is_inside_ || show_now_activated_ || new_application_)
465+ if (is_inside_ || show_now_activated_ || new_application_ || always_show_menus_)
466 return true;
467
468 if (window_buttons_->IsMouseOwner() || titlebar_grab_area_->IsMouseOwner())
469@@ -848,6 +863,9 @@
470
471 std::string PanelMenuView::GetCurrentTitle() const
472 {
473+ if (always_show_menus_ && is_maximized_ && we_control_active_)
474+ return std::string();
475+
476 if (integrated_menus_ || (!switcher_showing_ && !launcher_keynav_))
477 {
478 std::string new_title;
479@@ -958,14 +976,10 @@
480
481 if (!integrated_menus_ || is_maximized_)
482 {
483- auto mouse = nux::GetGraphicsDisplay()->GetMouseScreenCoord();
484- bool inside = GetAbsoluteGeometry().IsInside(mouse);
485+ bool was_inside = is_inside_;
486
487- if (is_inside_ != inside)
488- {
489- is_inside_ = inside;
490+ if (CheckMouseInside() != was_inside)
491 QueueDraw();
492- }
493 }
494 }
495
496@@ -1065,7 +1079,7 @@
497 app_name_changed_signal_.Connect(BAMF_VIEW(new_app), "name-changed",
498 sigc::mem_fun(this, &PanelMenuView::OnNameChanged));
499
500- if (integrated_menus_)
501+ if (integrated_menus_ || always_show_menus_)
502 return;
503
504 if (std::find(new_apps_.begin(), new_apps_.end(), new_app) != new_apps_.end())
505@@ -1263,8 +1277,7 @@
506 maximized_wins_.push_front(xid);
507
508 // We need to update the is_inside_ state in the case of maximization by grab
509- auto mouse = nux::GetGraphicsDisplay()->GetMouseScreenCoord();
510- is_inside_ = GetAbsoluteGeometry().IsInside(mouse);
511+ CheckMouseInside();
512 is_maximized_ = true;
513
514 if (Refresh())
515@@ -1674,6 +1687,7 @@
516
517 introspection
518 .add("mouse_inside", is_inside_)
519+ .add("always_show_menus", always_show_menus_)
520 .add("grabbed", is_grabbed_)
521 .add("active_win_maximized", is_maximized_)
522 .add("active_win_is_desktop", is_desktop_focused_)
523@@ -1695,7 +1709,7 @@
524
525 void PanelMenuView::OnSwitcherShown(GVariant* data)
526 {
527- if (!data || integrated_menus_)
528+ if (!data || integrated_menus_ || always_show_menus_)
529 return;
530
531 gboolean switcher_shown;
532@@ -1709,8 +1723,7 @@
533
534 if (!switcher_showing_)
535 {
536- auto mouse = nux::GetGraphicsDisplay()->GetMouseScreenCoord();
537- is_inside_ = GetAbsoluteGeometry().IsInside(mouse);
538+ CheckMouseInside();
539 }
540 else
541 {
542@@ -1738,9 +1751,7 @@
543 return;
544
545 launcher_keynav_ = false;
546-
547- auto mouse = nux::GetGraphicsDisplay()->GetMouseScreenCoord();
548- is_inside_ = GetAbsoluteGeometry().IsInside(mouse);
549+ CheckMouseInside();
550
551 if (Refresh())
552 QueueDraw();
553@@ -1866,8 +1877,22 @@
554 return we_control_active_;
555 }
556
557+bool PanelMenuView::CheckMouseInside()
558+{
559+ if (always_show_menus_)
560+ return is_inside_;
561+
562+ auto const& mouse = nux::GetGraphicsDisplay()->GetMouseScreenCoord();
563+ is_inside_ = GetAbsoluteGeometry().IsInside(mouse);
564+
565+ return is_inside_;
566+}
567+
568 void PanelMenuView::OnPanelViewMouseEnter(int x, int y, unsigned long mouse_button_state, unsigned long special_keys_state)
569 {
570+ if (always_show_menus_)
571+ return;
572+
573 if (!is_inside_)
574 {
575 if (is_grabbed_)
576@@ -1881,6 +1906,9 @@
577
578 void PanelMenuView::OnPanelViewMouseLeave(int x, int y, unsigned long mouse_button_state, unsigned long special_keys_state)
579 {
580+ if (always_show_menus_)
581+ return;
582+
583 if (is_inside_)
584 {
585 is_inside_ = false;
586@@ -1890,6 +1918,9 @@
587
588 void PanelMenuView::SetMousePosition(int x, int y)
589 {
590+ if (always_show_menus_)
591+ return;
592+
593 if (last_active_view_ ||
594 (x >= 0 && y >= 0 && GetAbsoluteGeometry().IsPointInside(x, y)))
595 {
596
597=== modified file 'panel/PanelMenuView.h'
598--- panel/PanelMenuView.h 2014-10-23 21:37:23 +0000
599+++ panel/PanelMenuView.h 2015-01-15 14:44:53 +0000
600@@ -91,6 +91,8 @@
601 void OnActiveAppChanged(BamfMatcher* matcher, BamfApplication* old_app, BamfApplication* new_app);
602 void OnNameChanged(BamfView* bamf_view, gchar* new_name, gchar* old_name);
603 void OnStyleChanged();
604+ void OnLIMChanged(bool);
605+ void OnAlwaysShowMenusChanged(bool);
606
607 void OnSpreadInitiate();
608 void OnSpreadTerminate();
609@@ -133,6 +135,7 @@
610 void OnLauncherSelectionChanged(GVariant* data);
611
612 void UpdateShowNow(bool ignore);
613+ bool CheckMouseInside();
614
615 bool UpdateActiveWindowPosition();
616 bool UpdateShowNowWithDelay();
617@@ -185,6 +188,7 @@
618 bool new_app_menu_shown_;
619 bool ignore_menu_visibility_;
620 bool integrated_menus_;
621+ bool always_show_menus_;
622
623 Window active_xid_;
624 nux::Geometry monitor_geo_;
625@@ -196,7 +200,6 @@
626 glib::Signal<void, BamfMatcher*, BamfApplication*, BamfApplication*> active_app_changed_signal_;
627 glib::Signal<void, BamfView*, gchar*, gchar*> view_name_changed_signal_;
628 glib::Signal<void, BamfView*, gchar*, gchar*> app_name_changed_signal_;
629- connection::Wrapper lim_changed_connection_;
630
631 UBusManager ubus_manager_;
632 glib::SourceManager sources_;
633
634=== modified file 'plugins/unityshell/src/unityshell.cpp'
635--- plugins/unityshell/src/unityshell.cpp 2014-12-20 03:12:15 +0000
636+++ plugins/unityshell/src/unityshell.cpp 2015-01-15 14:44:53 +0000
637@@ -3041,7 +3041,7 @@
638 }
639 }
640 }
641- else if (decoration::Style::Get()->integrated_menus())
642+ else if (uScreen->menus_->integrated_menus())
643 {
644 draw_panel_shadow = DrawPanelShadow::BELOW_WINDOW;
645 }
646
647=== modified file 'unity-shared/DecorationStyle.cpp'
648--- unity-shared/DecorationStyle.cpp 2014-08-07 13:15:17 +0000
649+++ unity-shared/DecorationStyle.cpp 2015-01-15 14:44:53 +0000
650@@ -157,7 +157,6 @@
651 gtk_widget_path_append_type(widget_path.get(), unity_decoration_get_type());
652 gtk_style_context_set_path(ctx_, widget_path.get());
653
654- parent_->integrated_menus = false;
655 parent_->theme = glib::String(GetSettingValue<gchar*>("gtk-theme-name")).Str();
656 parent_->font = glib::String(GetSettingValue<gchar*>("gtk-font-name")).Str();
657 parent_->font_scale = 1.0;
658
659=== modified file 'unity-shared/DecorationStyle.h'
660--- unity-shared/DecorationStyle.h 2014-04-02 17:05:04 +0000
661+++ unity-shared/DecorationStyle.h 2015-01-15 14:44:53 +0000
662@@ -118,7 +118,6 @@
663 nux::Property<std::string> theme;
664 nux::Property<std::string> font;
665 nux::Property<std::string> title_font;
666- nux::Property<bool> integrated_menus;
667 nux::Property<unsigned> grab_wait;
668 nux::Property<double> font_scale;
669
670
671=== modified file 'unity-shared/MenuManager.cpp'
672--- unity-shared/MenuManager.cpp 2014-03-05 14:17:43 +0000
673+++ unity-shared/MenuManager.cpp 2015-01-15 14:44:53 +0000
674@@ -20,6 +20,7 @@
675
676 #include <gtk/gtk.h>
677 #include <NuxCore/Logger.h>
678+#include <UnityCore/GLibSignal.h>
679 #include <UnityCore/GLibWrapper.h>
680 #include <UnityCore/DBusIndicators.h>
681 #include <unordered_map>
682@@ -30,8 +31,15 @@
683 {
684 namespace menu
685 {
686+namespace
687+{
688 DECLARE_LOGGER(logger, "unity.menu.manager");
689
690+const std::string SETTINGS_NAME = "com.canonical.Unity";
691+const std::string LIM_KEY = "integrated-menus";
692+const std::string ALWAYS_SHOW_MENUS_KEY = "always-show-menus";
693+}
694+
695 using namespace indicator;
696
697 struct Manager::Impl : sigc::trackable
698@@ -40,6 +48,7 @@
699 : parent_(parent)
700 , indicators_(indicators)
701 , key_grabber_(grabber)
702+ , settings_(g_settings_new(SETTINGS_NAME.c_str()))
703 {
704 for (auto const& indicator : indicators_->GetIndicators())
705 AddIndicator(indicator);
706@@ -49,6 +58,16 @@
707 indicators_->on_object_removed.connect(sigc::mem_fun(this, &Impl::RemoveIndicator));
708 indicators_->on_entry_activate_request.connect(sigc::mem_fun(this, &Impl::ActivateRequest));
709 indicators_->icon_paths_changed.connect(sigc::mem_fun(this, &Impl::IconPathsChanged));
710+
711+ parent_->integrated_menus = g_settings_get_boolean(settings_, LIM_KEY.c_str());
712+ parent_->always_show_menus = g_settings_get_boolean(settings_, ALWAYS_SHOW_MENUS_KEY.c_str());
713+
714+ signals_.Add<void, GSettings*, const gchar*>(settings_, "changed::" + LIM_KEY, [this] (GSettings*, const gchar*) {
715+ parent_->integrated_menus = g_settings_get_boolean(settings_, LIM_KEY.c_str());
716+ });
717+ signals_.Add<void, GSettings*, const gchar*>(settings_, "changed::" + ALWAYS_SHOW_MENUS_KEY, [this] (GSettings*, const gchar*) {
718+ parent_->always_show_menus = g_settings_get_boolean(settings_, ALWAYS_SHOW_MENUS_KEY.c_str());
719+ });
720 }
721
722 ~Impl()
723@@ -63,7 +82,7 @@
724 return;
725
726 appmenu_connections_.Clear();
727- appmenu_ = indicator;
728+ appmenu_ = std::static_pointer_cast<AppmenuIndicator>(indicator);
729
730 for (auto const& entry : appmenu_->GetEntries())
731 GrabEntryMnemonics(entry);
732@@ -149,14 +168,18 @@
733
734 Manager* parent_;
735 Indicators::Ptr indicators_;
736- Indicator::Ptr appmenu_;
737+ AppmenuIndicator::Ptr appmenu_;
738 key::Grabber::Ptr key_grabber_;
739 connection::Manager appmenu_connections_;
740+ glib::Object<GSettings> settings_;
741+ glib::SignalManager signals_;
742 std::unordered_map<std::string, std::shared_ptr<CompAction>> entry_actions_;
743 };
744
745 Manager::Manager(Indicators::Ptr const& indicators, key::Grabber::Ptr const& grabber)
746- : show_menus_wait(180)
747+ : integrated_menus(false)
748+ , show_menus_wait(180)
749+ , always_show_menus(false)
750 , fadein(100)
751 , fadeout(120)
752 , discovery(2)
753@@ -178,7 +201,7 @@
754 return impl_->indicators_;
755 }
756
757-Indicator::Ptr const& Manager::AppMenu() const
758+AppmenuIndicator::Ptr const& Manager::AppMenu() const
759 {
760 return impl_->appmenu_;
761 }
762
763=== modified file 'unity-shared/MenuManager.h'
764--- unity-shared/MenuManager.h 2014-02-13 05:47:03 +0000
765+++ unity-shared/MenuManager.h 2015-01-15 14:44:53 +0000
766@@ -22,6 +22,7 @@
767
768 #include <NuxCore/Property.h>
769 #include <UnityCore/Indicators.h>
770+#include <UnityCore/AppmenuIndicator.h>
771 #include "KeyGrabber.h"
772
773 namespace unity
774@@ -45,7 +46,10 @@
775 typedef std::shared_ptr<Manager> Ptr;
776
777 nux::Property<bool> show_menus;
778+
779+ nux::Property<bool> integrated_menus;
780 nux::Property<unsigned> show_menus_wait;
781+ nux::Property<bool> always_show_menus;
782
783 nux::Property<unsigned> fadein;
784 nux::Property<unsigned> fadeout;
785@@ -58,7 +62,7 @@
786
787 bool HasAppMenu() const;
788 indicator::Indicators::Ptr const& Indicators() const;
789- indicator::Indicator::Ptr const& AppMenu() const;
790+ indicator::AppmenuIndicator::Ptr const& AppMenu() const;
791
792 key::Grabber::Ptr const& KeyGrabber() const;
793
794
795=== modified file 'unity-shared/UScreen.cpp'
796--- unity-shared/UScreen.cpp 2014-11-28 12:56:12 +0000
797+++ unity-shared/UScreen.cpp 2015-01-15 14:44:53 +0000
798@@ -74,13 +74,10 @@
799
800 int UScreen::GetMonitorAtPosition(int x, int y) const
801 {
802- int idx = 0;
803-
804- for (auto const& monitor : monitors_)
805+ for (unsigned i = 0; i < monitors_.size(); ++i)
806 {
807- if (monitor.IsPointInside(x, y))
808- return idx;
809- ++idx;
810+ if (monitors_[i].IsPointInside(x, y))
811+ return i;
812 }
813
814 return gdk_screen_get_monitor_at_point(screen_, x, y);
815
816=== modified file 'unity-shared/UnitySettings.cpp'
817--- unity-shared/UnitySettings.cpp 2014-09-04 16:47:13 +0000
818+++ unity-shared/UnitySettings.cpp 2015-01-15 14:44:53 +0000
819@@ -38,7 +38,6 @@
820 const std::string SETTINGS_NAME = "com.canonical.Unity";
821 const std::string FORM_FACTOR = "form-factor";
822 const std::string DOUBLE_CLICK_ACTIVATE = "double-click-activate";
823-const std::string LIM_KEY = "integrated-menus";
824
825 const std::string LIM_SETTINGS = "com.canonical.Unity.IntegratedMenus";
826 const std::string CLICK_MOVEMENT_THRESHOLD = "click-movement-threshold";
827@@ -113,10 +112,6 @@
828 parent_->double_click_activate.changed.emit(cached_double_click_activate_);
829 });
830
831- signals_.Add<void, GSettings*, const gchar*>(usettings_, "changed::" + LIM_KEY, [this] (GSettings*, const gchar*) {
832- UpdateLimSetting();
833- });
834-
835 signals_.Add<void, GSettings*, const gchar*>(ubuntu_ui_settings_, "changed::" + SCALE_FACTOR, [this] (GSettings*, const gchar* t) {
836 UpdateDPI();
837 });
838@@ -190,7 +185,6 @@
839
840 void UpdateLimSetting()
841 {
842- decoration::Style::Get()->integrated_menus = g_settings_get_boolean(usettings_, LIM_KEY.c_str());
843 parent_->lim_movement_thresold = g_settings_get_uint(lim_settings_, CLICK_MOVEMENT_THRESHOLD.c_str());
844 parent_->lim_double_click_wait = g_settings_get_uint(lim_settings_, DOUBLE_CLICK_WAIT.c_str());
845 }