Merge lp:~3v1n0/unity/panel-p-cleanup into lp:unity

Proposed by Marco Trevisan (Treviño) on 2012-03-29
Status: Merged
Approved by: Didier Roche on 2012-04-06
Approved revision: 2124
Merged at revision: 2242
Proposed branch: lp:~3v1n0/unity/panel-p-cleanup
Merge into: lp:unity
Diff against target: 7874 lines (+3128/-2131)
28 files modified
UnityCore/Variant.cpp (+31/-2)
UnityCore/Variant.h (+6/-1)
plugins/unityshell/src/DashController.cpp (+5/-3)
plugins/unityshell/src/DashController.h (+1/-0)
plugins/unityshell/src/LauncherController.cpp (+51/-8)
plugins/unityshell/src/PanelController.cpp (+27/-20)
plugins/unityshell/src/PanelController.h (+2/-4)
plugins/unityshell/src/PanelIndicatorEntryView.cpp (+440/-347)
plugins/unityshell/src/PanelIndicatorEntryView.h (+69/-45)
plugins/unityshell/src/PanelIndicatorsView.cpp (+103/-42)
plugins/unityshell/src/PanelIndicatorsView.h (+27/-18)
plugins/unityshell/src/PanelMenuView.cpp (+934/-859)
plugins/unityshell/src/PanelMenuView.h (+78/-90)
plugins/unityshell/src/PanelTitlebarGrabAreaView.cpp (+125/-13)
plugins/unityshell/src/PanelTitlebarGrabAreaView.h (+27/-6)
plugins/unityshell/src/PanelTray.cpp (+92/-115)
plugins/unityshell/src/PanelTray.h (+21/-24)
plugins/unityshell/src/PanelView.cpp (+123/-149)
plugins/unityshell/src/PanelView.h (+40/-45)
plugins/unityshell/src/PluginAdapter.cpp (+158/-24)
plugins/unityshell/src/PluginAdapter.h (+12/-3)
plugins/unityshell/src/SwitcherController.cpp (+9/-2)
plugins/unityshell/src/UBusMessages.h (+1/-0)
plugins/unityshell/src/WindowButtons.cpp (+587/-220)
plugins/unityshell/src/WindowButtons.h (+33/-12)
plugins/unityshell/src/WindowManager.cpp (+38/-10)
plugins/unityshell/src/WindowManager.h (+12/-6)
plugins/unityshell/src/unityshell.cpp (+76/-63)
To merge this branch: bzr merge lp:~3v1n0/unity/panel-p-cleanup
Reviewer Review Type Date Requested Status
Tim Penhey (community) 2012-03-29 Approve on 2012-04-06
Review via email: mp+99950@code.launchpad.net

Commit message

A lot of panel fixes with code cleanup and improvements to the panel code.

This branch introduces a lot of code cleanup and improvements to the panel code.

A part the linked bugs fixed, this changes:
 - PanelStyle: used now to check all the panel related settings, including
   fonts and DPI. Emitting the changed signal when they get changed (so now
   when changing the title font, it gets updated immediately).
   Added better support for HighContrast themes and fallback buttons.
   Used ti everywhere to remove the "24" height magic number.

 - PanelIndicatorEntryView: code cleaned a lot to be more C++ conformant,
   and modified to be easily extendible in the near future. Also fixed issues
   with the indicator entries and Scale/Expo

 - PanelMenuView: the layout system has been rewritten and now it works
   natively without the workarounds we were using before,
   fixed the panel paddings to match design specs;
   Optimized the drawing operations, now the title texture is cached and
   rebuilt only if really needed.
   Fixed the panel title on Expo and Scale.
   Improved the detection of the panel used to draw the app title on
   multi-monitor (disabled otherwise), and the alt+tab/alt conflict.
   Maximized windows list is re-populated on startup or when adding a new
   screen.

 - PanelTitlebarGrabArea: rewritten to better handle the grabbing of the panel
   and clicks over it.

 - WindowButtons: rewritten using in a better way the subclass nux::Button
   features, factorizing some code for each button into WindowButtons. Also
   the handling of the controlled window is now done internally, not by the
   PanelMenuView.

Description of the change

A lot of panel fixes... Into one branch, because they should go together, but the single changes are shown on these single code reviews:

1) PanelStyle changes: http://go.3v1n0.net/Hs4YM6 [Tim: Approved]
2) Indicator Entry changes: http://go.3v1n0.net/Hp8VDp [Tim: Approved]
3) Indicators View changes: http://go.3v1n0.net/GXHKN3 [Tim: Approved]
4) Window buttons changes: http://go.3v1n0.net/GZHigm [Tim: Approved]
5) Grab area changes: http://go.3v1n0.net/H81Syb [Tim: Approved]
6) Tray changes: http://go.3v1n0.net/H6yqba [Tim: Approved]
7) Window Manager changes: http://go.3v1n0.net/H2GDwr [Tim: Approved]
8) Core changes: http://go.3v1n0.net/H1qokF [Tim: Approved]
9) Menu view changes: http://go.3v1n0.net/HwATeM [Tim: Approved]
10) Panel view changes: http://go.3v1n0.net/H8lwdB [Tim: Approved]

This branch introduces a lot of code cleanup and improvements to the panel code.

A part the linked bugs fixed, this changes:
 - PanelStyle: used now to check all the panel related settings, including
   fonts and DPI. Emitting the changed signal when they get changed (so now
   when changing the title font, it gets updated immediately).
   Added better support for HighContrast themes and fallback buttons.
   Used ti everywhere to remove the "24" height magic number.

 - PanelIndicatorEntryView: code cleaned a lot to be more C++ conformant,
   and modified to be easily extendible in the near future. Also fixed issues
   with the indicator entries and Scale/Expo

 - PanelMenuView: the layout system has been rewritten and now it works
   natively without the workarounds we were using before,
   fixed the panel paddings to match design specs;
   Optimized the drawing operations, now the title texture is cached and
   rebuilt only if really needed.
   Fixed the panel title on Expo and Scale.
   Improved the detection of the panel used to draw the app title on
   multi-monitor (disabled otherwise), and the alt+tab/alt conflict.
   Maximized windows list is re-populated on startup or when adding a new
   screen.

 - PanelTitlebarGrabArea: rewritten to better handle the grabbing of the panel
   and clicks over it.

 - WindowButtons: rewritten using in a better way the subclass nux::Button
   features, factorizing some code for each button into WindowButtons. Also
   the handling of the controlled window is now done internally, not by the
   PanelMenuView.

Testing:
 - All the panel items now are introspectable. And this allow AP testing.
 - The branch with all the brand new tests for the panel are at:
   lp:~3v1n0/unity/panel-p-tests

To post a comment you must log in.
Tim Penhey (thumper) wrote :

OMG, WTF? 7.5k lines in the last week? This had better work :-)

Tim Penhey (thumper) wrote :

Also, in the breakup way, you should be using chained merge proposals using prerequisite branches.

Tim Penhey (thumper) wrote :

Reviews in progress on the others.

review: Needs Fixing
Marco Trevisan (Treviño) (3v1n0) wrote :

> Also, in the breakup way, you should be using chained merge proposals using
> prerequisite branches.

Yes, I know, but since I've splitted it later, I didn't want to cause temporary breakage in trunk when merging just partial changes, so I want to keep this top branch updated and make it go into trunk, while the partial changes are here only for reviewing (even if they reflect the reality since I'm updating them using bzr pipeline)

Tim Penhey (thumper) wrote :

You have a lot of bugs linked to this branch. Where are the tests confirming fixes?

Marco Trevisan (Treviño) (3v1n0) wrote :

> You have a lot of bugs linked to this branch. Where are the tests confirming
> fixes?

I'm currently writing them, considering the size of this branch I want to keep the tests in another branches, while this get reviewed.

Brandon Schaefer (brandontschaefer) wrote :

** Note, I couldn't test any bug that dealt with multi monitors. **

Ok, lots of code. Confirmed this branch fixes all of these bugs:

Bug #655184: Top bar - Menus should be condensed to fit panel/overlay of appmenu
Bug #839690: Topbar - window controls for maximised windows in the top bar should conform to Fitts's law
Bug #875932: window selected via ALT+F1 doesn't get focus in unity
Bug #934680: Window management - Dragging down a maximized window from the panel has not predictable results
Bug #936425: Not minimizable windows have an enabled "minimize" button on the unity panel
Bug #939054: HUD maximize button affects Dash
Bug #962410: Menu bar not transparent when invoking dash with super key whilst HUD enabled and vice versa
Bug #963118: Windows controls lost if dash is opened after HUD
Bug #963134: Opening HUD after dash shows window title in the panel
Bug #970420: Super+Tab, super, loses focus
Bug #971947: PanelMenuView causes gtk assertion to fail
Bug #940683: Panel opacity toggle doesn't quite work

When the test are done this branch will be look good :). Awesome work!

Tim Penhey (thumper) wrote :

The test branch landing is coming next, for some reason tarmac gets itself in a twist.

review: Approve
Unity Merger (unity-merger) wrote :

No commit message specified.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'UnityCore/Variant.cpp'
2--- UnityCore/Variant.cpp 2012-03-21 12:31:11 +0000
3+++ UnityCore/Variant.cpp 2012-04-05 23:42:20 +0000
4@@ -142,15 +142,44 @@
5 return *this;
6 }
7
8-BuilderWrapper& BuilderWrapper::add(char const* name, unsigned value)
9+BuilderWrapper& BuilderWrapper::add(char const* name, long int value)
10+{
11+ g_variant_builder_add(builder_, "{sv}", name, g_variant_new_int64(value));
12+ return *this;
13+}
14+
15+BuilderWrapper& BuilderWrapper::add(char const* name, long long int value)
16+{
17+ g_variant_builder_add(builder_, "{sv}", name, g_variant_new_int64(value));
18+ return *this;
19+}
20+
21+BuilderWrapper& BuilderWrapper::add(char const* name, unsigned int value)
22 {
23 g_variant_builder_add(builder_, "{sv}", name, g_variant_new_uint32(value));
24 return *this;
25 }
26
27+BuilderWrapper& BuilderWrapper::add(char const* name, long unsigned int value)
28+{
29+ g_variant_builder_add(builder_, "{sv}", name, g_variant_new_uint64(value));
30+ return *this;
31+}
32+
33+BuilderWrapper& BuilderWrapper::add(char const* name, long long unsigned int value)
34+{
35+ g_variant_builder_add(builder_, "{sv}", name, g_variant_new_uint64(value));
36+ return *this;
37+}
38+
39 BuilderWrapper& BuilderWrapper::add(char const* name, float value)
40 {
41- // floats get promoted to doubles automatically
42+ g_variant_builder_add(builder_, "{sv}", name, g_variant_new_double(value));
43+ return *this;
44+}
45+
46+BuilderWrapper& BuilderWrapper::add(char const* name, double value)
47+{
48 g_variant_builder_add(builder_, "{sv}", name, g_variant_new_double(value));
49 return *this;
50 }
51
52=== modified file 'UnityCore/Variant.h'
53--- UnityCore/Variant.h 2012-03-21 12:31:11 +0000
54+++ UnityCore/Variant.h 2012-04-05 23:42:20 +0000
55@@ -73,8 +73,13 @@
56 BuilderWrapper& add(char const* name, char const* value);
57 BuilderWrapper& add(char const* name, std::string const& value);
58 BuilderWrapper& add(char const* name, int value);
59- BuilderWrapper& add(char const* name, unsigned value);
60+ BuilderWrapper& add(char const* name, long int value);
61+ BuilderWrapper& add(char const* name, long long int value);
62+ BuilderWrapper& add(char const* name, unsigned int value);
63+ BuilderWrapper& add(char const* name, long unsigned int value);
64+ BuilderWrapper& add(char const* name, long long unsigned int value);
65 BuilderWrapper& add(char const* name, float value);
66+ BuilderWrapper& add(char const* name, double value);
67 BuilderWrapper& add(char const* name, GVariant* value);
68 BuilderWrapper& add(nux::Rect const& value);
69
70
71=== modified file 'plugins/unityshell/src/DashController.cpp'
72--- plugins/unityshell/src/DashController.cpp 2012-03-21 12:31:11 +0000
73+++ plugins/unityshell/src/DashController.cpp 2012-04-05 23:42:20 +0000
74@@ -40,6 +40,7 @@
75 Controller::Controller()
76 : launcher_width(64)
77 , use_primary(false)
78+ , monitor_(0)
79 , window_(0)
80 , visible_(false)
81 , need_show_(false)
82@@ -126,7 +127,7 @@
83 g_variant_get(data, UBUS_OVERLAY_FORMAT_STRING, &overlay_identity, &can_maximise, &overlay_monitor);
84
85 // hide if something else is coming up
86- if (g_strcmp0(overlay_identity, "dash"))
87+ if (overlay_identity.Str() != "dash")
88 {
89 HideDash(true);
90 }
91@@ -272,7 +273,8 @@
92
93 StartShowHideTimeline();
94
95- GVariant* info = g_variant_new(UBUS_OVERLAY_FORMAT_STRING, "dash", TRUE, GetIdealMonitor());
96+ monitor_ = GetIdealMonitor();
97+ GVariant* info = g_variant_new(UBUS_OVERLAY_FORMAT_STRING, "dash", TRUE, monitor_);
98 ubus_manager_.SendMessage(UBUS_OVERLAY_SHOWN, info);
99 }
100
101@@ -298,7 +300,7 @@
102
103 StartShowHideTimeline();
104
105- GVariant* info = g_variant_new(UBUS_OVERLAY_FORMAT_STRING, "dash", TRUE, GetIdealMonitor());
106+ GVariant* info = g_variant_new(UBUS_OVERLAY_FORMAT_STRING, "dash", TRUE, monitor_);
107 ubus_manager_.SendMessage(UBUS_OVERLAY_HIDDEN, info);
108 }
109
110
111=== modified file 'plugins/unityshell/src/DashController.h'
112--- plugins/unityshell/src/DashController.h 2012-03-27 22:34:53 +0000
113+++ plugins/unityshell/src/DashController.h 2012-04-05 23:42:20 +0000
114@@ -89,6 +89,7 @@
115 private:
116 glib::SignalManager sig_manager_;
117 UBusManager ubus_manager_;
118+ int monitor_;
119
120 nux::BaseWindow* window_;
121 bool visible_;
122
123=== modified file 'plugins/unityshell/src/LauncherController.cpp'
124--- plugins/unityshell/src/LauncherController.cpp 2012-04-05 00:32:14 +0000
125+++ plugins/unityshell/src/LauncherController.cpp 2012-04-05 23:42:20 +0000
126@@ -1101,9 +1101,9 @@
127 void Controller::KeyNavGrab()
128 {
129 pimpl->ubus.SendMessage(UBUS_PLACE_VIEW_CLOSE_REQUEST);
130+ pimpl->launcher_grabbed = true;
131 KeyNavActivate();
132 pimpl->keyboard_launcher_->GrabKeyboard();
133- pimpl->launcher_grabbed = true;
134
135 pimpl->launcher_key_press_connection_ =
136 pimpl->keyboard_launcher_->key_down.connect(sigc::mem_fun(pimpl, &Controller::Impl::ReceiveLauncherKeyPress));
137@@ -1124,18 +1124,50 @@
138 pimpl->keyboard_launcher_->EnterKeyNavMode();
139 pimpl->model_->SetSelection(0);
140
141- pimpl->ubus.SendMessage(UBUS_LAUNCHER_START_KEY_SWTICHER, g_variant_new_boolean(true));
142- pimpl->ubus.SendMessage(UBUS_LAUNCHER_START_KEY_NAV, NULL);
143+ if (pimpl->launcher_grabbed)
144+ {
145+ pimpl->ubus.SendMessage(UBUS_LAUNCHER_START_KEY_NAV,
146+ g_variant_new_int32(pimpl->keyboard_launcher_->monitor));
147+ }
148+ else
149+ {
150+ pimpl->ubus.SendMessage(UBUS_LAUNCHER_START_KEY_SWTICHER,
151+ g_variant_new_int32(pimpl->keyboard_launcher_->monitor));
152+ }
153+
154+ AbstractLauncherIcon::Ptr const& selected = pimpl->model_->Selection();
155+
156+ if (selected)
157+ {
158+ pimpl->ubus.SendMessage(UBUS_LAUNCHER_SELECTION_CHANGED,
159+ g_variant_new_string(selected->tooltip_text().c_str()));
160+ }
161 }
162
163 void Controller::KeyNavNext()
164 {
165 pimpl->model_->SelectNext();
166+
167+ AbstractLauncherIcon::Ptr const& selected = pimpl->model_->Selection();
168+
169+ if (selected)
170+ {
171+ pimpl->ubus.SendMessage(UBUS_LAUNCHER_SELECTION_CHANGED,
172+ g_variant_new_string(selected->tooltip_text().c_str()));
173+ }
174 }
175
176 void Controller::KeyNavPrevious()
177 {
178 pimpl->model_->SelectPrevious();
179+
180+ AbstractLauncherIcon::Ptr const& selected = pimpl->model_->Selection();
181+
182+ if (selected)
183+ {
184+ pimpl->ubus.SendMessage(UBUS_LAUNCHER_SELECTION_CHANGED,
185+ g_variant_new_string(selected->tooltip_text().c_str()));
186+ }
187 }
188
189 void Controller::KeyNavTerminate(bool activate)
190@@ -1143,13 +1175,28 @@
191 if (!pimpl->launcher_keynav)
192 return;
193
194+ if (activate && pimpl->keynav_restore_window_)
195+ {
196+ /* If the selected icon is running, we must not restore the input to the old */
197+ AbstractLauncherIcon::Ptr const& icon = pimpl->model_->Selection();
198+ pimpl->keynav_restore_window_ = !icon->GetQuirk(AbstractLauncherIcon::QUIRK_RUNNING);
199+ }
200+
201 pimpl->keyboard_launcher_->ExitKeyNavMode();
202+
203 if (pimpl->launcher_grabbed)
204 {
205 pimpl->keyboard_launcher_->UnGrabKeyboard();
206 pimpl->launcher_key_press_connection_.disconnect();
207 pimpl->launcher_event_outside_connection_.disconnect();
208 pimpl->launcher_grabbed = false;
209+ pimpl->ubus.SendMessage(UBUS_LAUNCHER_END_KEY_NAV,
210+ g_variant_new_boolean(pimpl->keynav_restore_window_));
211+ }
212+ else
213+ {
214+ pimpl->ubus.SendMessage(UBUS_LAUNCHER_END_KEY_SWTICHER,
215+ g_variant_new_boolean(pimpl->keynav_restore_window_));
216 }
217
218 if (activate)
219@@ -1158,9 +1205,6 @@
220 pimpl->launcher_keynav = false;
221 if (!pimpl->launcher_open)
222 pimpl->keyboard_launcher_.Release();
223-
224- pimpl->ubus.SendMessage(UBUS_LAUNCHER_END_KEY_SWTICHER, g_variant_new_boolean(true));
225- pimpl->ubus.SendMessage(UBUS_LAUNCHER_END_KEY_NAV, g_variant_new_boolean(pimpl->keynav_restore_window_));
226 }
227
228 bool Controller::KeyNavIsActive() const
229@@ -1260,8 +1304,7 @@
230 // <RETURN> (start/activate currently selected icon)
231 case NUX_VK_ENTER:
232 case NUX_KP_ENTER:
233- model_->Selection()->Activate(ActionArg(ActionArg::LAUNCHER, 0));
234- parent_->KeyNavTerminate(false);
235+ parent_->KeyNavTerminate(true);
236 break;
237
238 default:
239
240=== modified file 'plugins/unityshell/src/PanelController.cpp'
241--- plugins/unityshell/src/PanelController.cpp 2012-03-22 19:33:10 +0000
242+++ plugins/unityshell/src/PanelController.cpp 2012-04-05 23:42:20 +0000
243@@ -26,6 +26,7 @@
244
245 #include "UScreen.h"
246 #include "PanelView.h"
247+#include "PanelStyle.h"
248
249 namespace unity
250 {
251@@ -46,8 +47,8 @@
252 void FirstMenuShow();
253 void QueueRedraw();
254
255- unsigned int GetTrayXid();
256- std::list <nux::Geometry> GetGeometries();
257+ std::vector<Window> GetTrayXids() const;
258+ std::vector<nux::Geometry> GetGeometries() const;
259
260 // NOTE: nux::Property maybe?
261 void SetOpacity(float opacity);
262@@ -60,7 +61,7 @@
263
264 void OnScreenChanged(int primary_monitor, std::vector<nux::Geometry>& monitors, Introspectable *iobj);
265 private:
266- unity::PanelView* ViewForWindow(nux::BaseWindow* window);
267+ unity::PanelView* ViewForWindow(nux::BaseWindow* window) const;
268
269 static void WindowConfigureCallback(int window_width,
270 int window_height,
271@@ -98,17 +99,21 @@
272 }
273 }
274
275-unsigned int Controller::Impl::GetTrayXid()
276+std::vector<Window> Controller::Impl::GetTrayXids() const
277 {
278- if (!windows_.empty())
279- return ViewForWindow(windows_.front())->GetTrayXid();
280- else
281- return 0;
282+ std::vector<Window> xids;
283+
284+ for (auto window: windows_)
285+ {
286+ xids.push_back(ViewForWindow(window)->GetTrayXid());
287+ }
288+
289+ return xids;
290 }
291
292-std::list<nux::Geometry> Controller::Impl::GetGeometries()
293+std::vector<nux::Geometry> Controller::Impl::GetGeometries() const
294 {
295- std::list<nux::Geometry> geometries;
296+ std::vector<nux::Geometry> geometries;
297
298 for (auto window : windows_)
299 {
300@@ -171,7 +176,7 @@
301 }
302 }
303
304-PanelView* Controller::Impl::ViewForWindow(nux::BaseWindow* window)
305+PanelView* Controller::Impl::ViewForWindow(nux::BaseWindow* window) const
306 {
307 nux::Layout* layout = window->GetLayout();
308 std::list<nux::Area*>::iterator it = layout->GetChildren().begin();
309@@ -198,8 +203,9 @@
310 (*it)->InputWindowEnableStruts(false);
311
312 nux::Geometry geo = monitors[i];
313- geo.height = 24;
314+ geo.height = panel::Style::Instance().panel_height;
315 (*it)->SetGeometry(geo);
316+ (*it)->SetMinMaxSize(geo.width, geo.height);
317
318 view = ViewForWindow(*it);
319 view->SetPrimary(i == primary_monitor);
320@@ -224,7 +230,7 @@
321 nux::HLayout* layout = new nux::HLayout(NUX_TRACKER_LOCATION);
322
323 PanelView* view = new PanelView();
324- view->SetMaximumHeight(24);
325+ view->SetMaximumHeight(panel::Style::Instance().panel_height);
326 view->SetOpacity(opacity_);
327 view->SetOpacityMaximizedToggle(opacity_maximized_toggle_);
328 view->SetMenuShowTimings(menus_fadein_, menus_fadeout_, menus_discovery_,
329@@ -238,17 +244,18 @@
330 layout->SetHorizontalExternalMargin(0);
331
332 nux::BaseWindow* window = new nux::BaseWindow("");
333+ nux::Geometry geo = monitors[i];
334+ geo.height = panel::Style::Instance().panel_height;
335+
336 window->SinkReference();
337 window->SetConfigureNotifyCallback(&Impl::WindowConfigureCallback, window);
338- window->SetLayout(layout);
339 window->SetBackgroundColor(nux::Color(0.0f, 0.0f, 0.0f, 0.0f));
340 window->ShowWindow(true);
341 window->EnableInputWindow(true, "panel", false, false);
342 window->InputWindowEnableStruts(true);
343-
344- nux::Geometry geo = monitors[i];
345- geo.height = 24;
346 window->SetGeometry(geo);
347+ window->SetMinMaxSize(geo.width, geo.height);
348+ window->SetLayout(layout);
349
350 windows_.push_back(window);
351
352@@ -325,12 +332,12 @@
353 pimpl->QueueRedraw();
354 }
355
356-unsigned int Controller::GetTrayXid()
357+std::vector<Window> Controller::GetTrayXids() const
358 {
359- return pimpl->GetTrayXid();
360+ return pimpl->GetTrayXids();
361 }
362
363-std::list<nux::Geometry> Controller::GetGeometries()
364+std::vector<nux::Geometry> Controller::GetGeometries() const
365 {
366 return pimpl->GetGeometries();
367 }
368
369=== modified file 'plugins/unityshell/src/PanelController.h'
370--- plugins/unityshell/src/PanelController.h 2012-03-22 19:33:10 +0000
371+++ plugins/unityshell/src/PanelController.h 2012-04-05 23:42:20 +0000
372@@ -20,9 +20,7 @@
373 #ifndef _PANEL_CONTROLLER_H_
374 #define _PANEL_CONTROLLER_H_
375
376-#include <list>
377 #include <memory>
378-
379 #include <Nux/Nux.h>
380
381 #include "Introspectable.h"
382@@ -42,8 +40,8 @@
383 void FirstMenuShow();
384 void QueueRedraw();
385
386- unsigned int GetTrayXid ();
387- std::list<nux::Geometry> GetGeometries ();
388+ std::vector<Window> GetTrayXids() const;
389+ std::vector<nux::Geometry> GetGeometries() const;
390
391 // NOTE: nux::Property maybe?
392 void SetOpacity(float opacity);
393
394=== modified file 'plugins/unityshell/src/PanelIndicatorEntryView.cpp'
395--- plugins/unityshell/src/PanelIndicatorEntryView.cpp 2012-04-03 03:40:06 +0000
396+++ plugins/unityshell/src/PanelIndicatorEntryView.cpp 2012-04-05 23:42:20 +0000
397@@ -1,6 +1,6 @@
398 // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
399 /*
400- * Copyright (C) 2010 Canonical Ltd
401+ * Copyright (C) 2010-2012 Canonical Ltd
402 *
403 * This program is free software: you can redistribute it and/or modify
404 * it under the terms of the GNU General Public License version 3 as
405@@ -15,6 +15,7 @@
406 * along with this program. If not, see <http://www.gnu.org/licenses/>.
407 *
408 * Authored by: Neil Jagdish Patel <neil.patel@canonical.com>
409+ * Marco Trevisan (Treviño) <3v1n0@ubuntu.com>
410 */
411
412 #include <Nux/Nux.h>
413@@ -24,22 +25,18 @@
414 #include <NuxGraphics/GLThread.h>
415 #include <Nux/BaseWindow.h>
416 #include <Nux/WindowCompositor.h>
417-
418-#include <boost/algorithm/string.hpp>
419+#include <UnityCore/Variant.h>
420
421 #include <glib.h>
422-#include <pango/pangocairo.h>
423 #include <gdk-pixbuf/gdk-pixbuf.h>
424 #include <gtk/gtk.h>
425 #include <time.h>
426+#include <boost/algorithm/string.hpp>
427
428 #include "CairoTexture.h"
429-// TODO: this include should be at the top, but it fails :(
430 #include "PanelIndicatorEntryView.h"
431-
432 #include "PanelStyle.h"
433-#include <UnityCore/GLibWrapper.h>
434-#include <UnityCore/Variant.h>
435+#include "WindowManager.h"
436
437
438 namespace unity
439@@ -47,52 +44,45 @@
440
441 namespace
442 {
443-void draw_menu_bg(cairo_t* cr, int width, int height);
444-GdkPixbuf* make_pixbuf(int image_type, std::string const& image_data, bool dash_showing);
445-const int PANEL_HEIGHT = 24;
446-const int SPACING = 3;
447+const int DEFAULT_SPACING = 3;
448 }
449
450+using namespace indicator;
451
452-PanelIndicatorEntryView::PanelIndicatorEntryView(
453- indicator::Entry::Ptr const& proxy,
454- int padding,
455- IndicatorEntryType type)
456+PanelIndicatorEntryView::PanelIndicatorEntryView(Entry::Ptr const& proxy, int padding,
457+ IndicatorEntryType type)
458 : TextureArea(NUX_TRACKER_LOCATION)
459 , proxy_(proxy)
460+ , spacing_(DEFAULT_SPACING)
461+ , left_padding_(padding < 0 ? 0 : padding)
462+ , right_padding_(left_padding_)
463 , type_(type)
464- , util_cg_(CAIRO_FORMAT_ARGB32, 1, 1)
465- , texture_layer_(NULL)
466- , padding_(padding < 0 ? 0 : padding)
467+ , entry_texture_(nullptr)
468 , opacity_(1.0f)
469 , draw_active_(false)
470- , dash_showing_(false)
471+ , overlay_showing_(false)
472 , disabled_(false)
473+ , focused_(true)
474 {
475- on_indicator_activate_changed_connection_ = proxy_->active_changed.connect(sigc::mem_fun(this, &PanelIndicatorEntryView::OnActiveChanged));
476- on_indicator_updated_connection_ = proxy_->updated.connect(sigc::mem_fun(this, &PanelIndicatorEntryView::Refresh));
477-
478- on_font_changed_connection_ = g_signal_connect(gtk_settings_get_default(), "notify::gtk-font-name", (GCallback) &PanelIndicatorEntryView::OnFontChanged, this);
479+ proxy_->active_changed.connect(sigc::mem_fun(this, &PanelIndicatorEntryView::OnActiveChanged));
480+ proxy_->updated.connect(sigc::mem_fun(this, &PanelIndicatorEntryView::Refresh));
481
482 InputArea::mouse_down.connect(sigc::mem_fun(this, &PanelIndicatorEntryView::OnMouseDown));
483 InputArea::mouse_up.connect(sigc::mem_fun(this, &PanelIndicatorEntryView::OnMouseUp));
484
485 InputArea::SetAcceptMouseWheelEvent(true);
486+
487 if (type_ != MENU)
488 InputArea::mouse_wheel.connect(sigc::mem_fun(this, &PanelIndicatorEntryView::OnMouseWheel));
489
490- on_panelstyle_changed_connection_ = panel::Style::Instance().changed.connect(sigc::mem_fun(this, &PanelIndicatorEntryView::Refresh));
491+ panel::Style::Instance().changed.connect(sigc::mem_fun(this, &PanelIndicatorEntryView::Refresh));
492+
493 Refresh();
494 }
495
496 PanelIndicatorEntryView::~PanelIndicatorEntryView()
497 {
498- on_indicator_activate_changed_connection_.disconnect();
499- on_indicator_updated_connection_.disconnect();
500- on_panelstyle_changed_connection_.disconnect();
501- g_signal_handler_disconnect(gtk_settings_get_default(), on_font_changed_connection_);
502- if (texture_layer_)
503- delete texture_layer_;
504+ // Nothing to do...
505 }
506
507 void PanelIndicatorEntryView::OnActiveChanged(bool is_active)
508@@ -108,10 +98,15 @@
509
510 void PanelIndicatorEntryView::ShowMenu(int button)
511 {
512- proxy_->ShowMenu(GetAbsoluteX(),
513- GetAbsoluteY() + PANEL_HEIGHT,
514- button,
515- time(NULL));
516+ auto wm = WindowManager::Default();
517+
518+ if (!wm->IsExpoActive() && !wm->IsScaleActive())
519+ {
520+ proxy_->ShowMenu(GetAbsoluteX(),
521+ GetAbsoluteY() + panel::Style::Instance().panel_height,
522+ button,
523+ time(nullptr));
524+ }
525 }
526
527 void PanelIndicatorEntryView::OnMouseDown(int x, int y, long button_flags, long key_flags)
528@@ -119,8 +114,8 @@
529 if (proxy_->active() || IsDisabled())
530 return;
531
532- if (((proxy_->label_visible() && proxy_->label_sensitive()) ||
533- (proxy_->image_visible() && proxy_->image_sensitive())))
534+ if (((IsLabelVisible() && IsLabelSensitive()) ||
535+ (IsIconVisible() && IsIconSensitive())))
536 {
537 int button = nux::GetEventButton(button_flags);
538
539@@ -144,12 +139,12 @@
540 int px = geo.x + x;
541 int py = geo.y + y;
542
543- if (((proxy_->label_visible() && proxy_->label_sensitive()) ||
544- (proxy_->image_visible() && proxy_->image_sensitive())) &&
545- button == 2 && type_ == INDICATOR)
546+ if (((IsLabelVisible() && IsLabelSensitive()) ||
547+ (IsIconVisible() && IsIconSensitive())) &&
548+ button == 2 && type_ == INDICATOR)
549 {
550 if (geo.IsPointInside(px, py))
551- proxy_->SecondaryActivate(time(NULL));
552+ proxy_->SecondaryActivate(time(nullptr));
553
554 SetOpacity(1.0f);
555 }
556@@ -187,78 +182,290 @@
557 }
558 }
559
560+glib::Object<GdkPixbuf> PanelIndicatorEntryView::MakePixbuf()
561+{
562+ glib::Object<GdkPixbuf> pixbuf;
563+ GtkIconTheme* theme = gtk_icon_theme_get_default();
564+ int image_type = proxy_->image_type();
565+
566+ if (image_type == GTK_IMAGE_PIXBUF)
567+ {
568+ gsize len = 0;
569+ guchar* decoded = g_base64_decode(proxy_->image_data().c_str(), &len);
570+
571+ glib::Object<GInputStream> stream(g_memory_input_stream_new_from_data(decoded,
572+ len,
573+ nullptr));
574+
575+ pixbuf = gdk_pixbuf_new_from_stream(stream, nullptr, nullptr);
576+
577+ g_free(decoded);
578+ g_input_stream_close(stream, nullptr, nullptr);
579+ }
580+ else if (image_type == GTK_IMAGE_STOCK ||
581+ image_type == GTK_IMAGE_ICON_NAME)
582+ {
583+ pixbuf = gtk_icon_theme_load_icon(theme, proxy_->image_data().c_str(), 22,
584+ (GtkIconLookupFlags)0, nullptr);
585+ }
586+ else if (image_type == GTK_IMAGE_GICON)
587+ {
588+ glib::Object<GIcon> icon(g_icon_new_for_string(proxy_->image_data().c_str(), nullptr));
589+
590+ GtkIconInfo* info = gtk_icon_theme_lookup_by_gicon(theme, icon, 22,
591+ (GtkIconLookupFlags)0);
592+ if (info)
593+ {
594+ pixbuf = gtk_icon_info_load_icon(info, nullptr);
595+ gtk_icon_info_free(info);
596+ }
597+ }
598+
599+ return pixbuf;
600+}
601+
602+void PanelIndicatorEntryView::DrawEntryPrelight(cairo_t* cr, unsigned int width, unsigned int height)
603+{
604+ GtkStyleContext* style_context = panel::Style::Instance().GetStyleContext();
605+
606+ gtk_style_context_save(style_context);
607+
608+ GtkWidgetPath* widget_path = gtk_widget_path_new();
609+ gtk_widget_path_append_type(widget_path, GTK_TYPE_MENU_BAR);
610+ gtk_widget_path_append_type(widget_path, GTK_TYPE_MENU_ITEM);
611+ gtk_widget_path_iter_set_name(widget_path, -1 , "UnityPanelWidget");
612+
613+ gtk_style_context_set_path(style_context, widget_path);
614+ gtk_style_context_add_class(style_context, GTK_STYLE_CLASS_MENUBAR);
615+ gtk_style_context_add_class(style_context, GTK_STYLE_CLASS_MENUITEM);
616+ gtk_style_context_set_state(style_context, GTK_STATE_FLAG_PRELIGHT);
617+
618+ gtk_render_background(style_context, cr, 0, 0, width, height);
619+ gtk_render_frame(style_context, cr, 0, 0, width, height);
620+
621+ gtk_widget_path_free(widget_path);
622+
623+ gtk_style_context_restore(style_context);
624+}
625+
626+void PanelIndicatorEntryView::DrawEntryContent(cairo_t *cr, unsigned int width, unsigned int height, glib::Object<GdkPixbuf> const& pixbuf, glib::Object<PangoLayout> const& layout)
627+{
628+ int x = left_padding_;
629+
630+ if (IsActive())
631+ DrawEntryPrelight(cr, width, height);
632+
633+ if (pixbuf && IsIconVisible())
634+ {
635+ GtkStyleContext* style_context = panel::Style::Instance().GetStyleContext();
636+ unsigned int icon_width = gdk_pixbuf_get_width(pixbuf);
637+
638+ gtk_style_context_save(style_context);
639+
640+ GtkWidgetPath* widget_path = gtk_widget_path_new();
641+ gint pos = gtk_widget_path_append_type(widget_path, GTK_TYPE_MENU_BAR);
642+ pos = gtk_widget_path_append_type(widget_path, GTK_TYPE_MENU_ITEM);
643+ gtk_widget_path_iter_set_name(widget_path, pos, "UnityPanelWidget");
644+
645+ gtk_style_context_set_path(style_context, widget_path);
646+ gtk_style_context_add_class(style_context, GTK_STYLE_CLASS_MENUBAR);
647+ gtk_style_context_add_class(style_context, GTK_STYLE_CLASS_MENUITEM);
648+
649+ if (!IsFocused())
650+ {
651+ gtk_style_context_set_state(style_context, GTK_STATE_FLAG_BACKDROP);
652+ }
653+ else if (IsActive())
654+ {
655+ gtk_style_context_set_state(style_context, GTK_STATE_FLAG_PRELIGHT);
656+ }
657+
658+ int y = (int)((height - gdk_pixbuf_get_height(pixbuf)) / 2);
659+ if (overlay_showing_ && !IsActive())
660+ {
661+ /* Most of the images we get are straight pixbufs (annoyingly), so when
662+ * the Overlay opens, we use the pixbuf as a mask to punch out an icon from
663+ * a white square. It works surprisingly well for most symbolic-type
664+ * icon themes/icons.
665+ */
666+ cairo_save(cr);
667+
668+ cairo_push_group(cr);
669+ gdk_cairo_set_source_pixbuf(cr, pixbuf, x, y);
670+ cairo_paint_with_alpha(cr, (IsIconSensitive() && IsFocused()) ? 1.0 : 0.5);
671+
672+ cairo_pattern_t* pat = cairo_pop_group(cr);
673+
674+ cairo_set_source_rgba(cr, 1.0f, 1.0f, 1.0f, 1.0f);
675+ cairo_rectangle(cr, x, y, width, height);
676+ cairo_mask(cr, pat);
677+
678+ cairo_pattern_destroy(pat);
679+ cairo_restore(cr);
680+ }
681+ else
682+ {
683+ cairo_push_group(cr);
684+ gtk_render_icon(style_context, cr, pixbuf, x, y);
685+ cairo_pop_group_to_source(cr);
686+ cairo_paint_with_alpha(cr, (IsIconSensitive() && IsFocused()) ? 1.0 : 0.5);
687+ }
688+
689+ gtk_widget_path_free(widget_path);
690+
691+ gtk_style_context_restore(style_context);
692+
693+ x += icon_width + spacing_;
694+ }
695+
696+ if (layout)
697+ {
698+ PangoRectangle log_rect;
699+ pango_layout_get_extents(layout, nullptr, &log_rect);
700+ unsigned int text_height = log_rect.height / PANGO_SCALE;
701+ unsigned int text_width = log_rect.width / PANGO_SCALE;
702+
703+ pango_cairo_update_layout(cr, layout);
704+
705+ GtkStyleContext* style_context = panel::Style::Instance().GetStyleContext();
706+
707+ gtk_style_context_save(style_context);
708+
709+ GtkWidgetPath* widget_path = gtk_widget_path_new();
710+ gint pos = gtk_widget_path_append_type(widget_path, GTK_TYPE_MENU_BAR);
711+ pos = gtk_widget_path_append_type(widget_path, GTK_TYPE_MENU_ITEM);
712+ gtk_widget_path_iter_set_name(widget_path, pos, "UnityPanelWidget");
713+
714+ gtk_style_context_set_path(style_context, widget_path);
715+ gtk_style_context_add_class(style_context, GTK_STYLE_CLASS_MENUBAR);
716+ gtk_style_context_add_class(style_context, GTK_STYLE_CLASS_MENUITEM);
717+
718+ if (!IsFocused())
719+ {
720+ gtk_style_context_set_state(style_context, GTK_STATE_FLAG_BACKDROP);
721+ }
722+ else if (IsActive())
723+ {
724+ gtk_style_context_set_state(style_context, GTK_STATE_FLAG_PRELIGHT);
725+ }
726+
727+ int y = (height - text_height) / 2;
728+
729+
730+ unsigned int text_space = GetMaximumWidth() - x - right_padding_;
731+
732+ if (text_width > text_space)
733+ {
734+ cairo_pattern_t* linpat;
735+ int out_pixels = text_width - text_space;
736+ const int fading_pixels = 15;
737+
738+ int fading_width = out_pixels < fading_pixels ? out_pixels : fading_pixels;
739+
740+ cairo_push_group(cr);
741+ if (overlay_showing_)
742+ {
743+ cairo_move_to(cr, x, y);
744+ cairo_set_source_rgb(cr, 1.0f, 1.0f, 1.0f);
745+ pango_cairo_show_layout(cr, layout);
746+ }
747+ else
748+ {
749+ gtk_render_layout(style_context, cr, x, y, layout);
750+ }
751+ cairo_pop_group_to_source(cr);
752+
753+ int right_margin = width - right_padding_;
754+ linpat = cairo_pattern_create_linear(right_margin - fading_width, y, right_margin, y);
755+ cairo_pattern_add_color_stop_rgba(linpat, 0, 0, 0, 0, 1);
756+ cairo_pattern_add_color_stop_rgba(linpat, 1, 0, 0, 0, 0);
757+ cairo_mask(cr, linpat);
758+ cairo_pattern_destroy(linpat);
759+ }
760+ else
761+ {
762+ if (overlay_showing_)
763+ {
764+ cairo_move_to(cr, x, y);
765+ cairo_set_source_rgb(cr, 1.0f, 1.0f, 1.0f);
766+ pango_cairo_show_layout(cr, layout);
767+ }
768+ else
769+ {
770+ gtk_render_layout(style_context, cr, x, y, layout);
771+ }
772+ }
773+
774+ gtk_widget_path_free(widget_path);
775+ gtk_style_context_restore(style_context);
776+ }
777+}
778+
779 // We need to do a couple of things here:
780 // 1. Figure out our width
781 // 2. Figure out if we're active
782 // 3. Paint something
783 void PanelIndicatorEntryView::Refresh()
784 {
785- if (!IsVisible())
786+ if (!proxy_->visible())
787 {
788 SetVisible(false);
789+ // This will destroy the object texture. No need to manually delete the pointer
790+ entry_texture_ = nullptr;
791+ SetColor(nux::color::Transparent);
792+
793+ QueueDraw();
794+ refreshed.emit(this);
795+
796 return;
797 }
798
799- SetVisible(true);
800-
801- PangoLayout* layout = NULL;
802- PangoFontDescription* desc = NULL;
803- PangoAttrList* attrs = NULL;
804- GtkSettings* settings = gtk_settings_get_default();
805- cairo_t* cr;
806- char* font_description = NULL;
807- GdkScreen* screen = gdk_screen_get_default();
808- int dpi = 0;
809-
810- std::string label = proxy_->label();
811- glib::Object<GdkPixbuf> pixbuf(make_pixbuf(proxy_->image_type(),
812- proxy_->image_data(),
813- dash_showing_));
814-
815-
816- int x = 0;
817- int width = 0;
818- int height = PANEL_HEIGHT;
819- int icon_width = 0;
820- int text_width = 0;
821- int text_height = 0;
822-
823- if (proxy_->show_now())
824- {
825- if (!pango_parse_markup(label.c_str(),
826- -1,
827- '_',
828- &attrs,
829- NULL,
830- NULL,
831- NULL))
832- {
833- g_debug("pango_parse_markup failed");
834- }
835- }
836- boost::erase_all(label, "_");
837+ glib::Object<PangoLayout> layout;
838+ cairo_t* cr;
839+
840+ std::string label = GetLabel();
841+ glib::Object<GdkPixbuf> const& pixbuf = MakePixbuf();
842+
843+ unsigned int width = 0;
844+ unsigned int icon_width = 0;
845+ unsigned int height = panel::Style::Instance().panel_height;
846+ unsigned int text_width = 0;
847
848 // First lets figure out our size
849- if (pixbuf && proxy_->image_visible())
850+ if (pixbuf && IsIconVisible())
851 {
852 width = gdk_pixbuf_get_width(pixbuf);
853 icon_width = width;
854 }
855
856- if (!label.empty() && proxy_->label_visible())
857+ if (!label.empty() && IsLabelVisible())
858 {
859+ using namespace panel;
860 PangoContext* cxt;
861+ PangoAttrList* attrs = nullptr;
862 PangoRectangle log_rect;
863-
864- cr = util_cg_.GetContext();
865-
866- g_object_get(settings,
867- "gtk-font-name", &font_description,
868- "gtk-xft-dpi", &dpi,
869- NULL);
870- desc = pango_font_description_from_string(font_description);
871+ GdkScreen* screen = gdk_screen_get_default();
872+ PangoFontDescription* desc = nullptr;
873+ PanelItem panel_item = (type_ == MENU) ? PanelItem::MENU : PanelItem::INDICATOR;
874+
875+ Style& panel_style = Style::Instance();
876+ std::string const& font_description = panel_style.GetFontDescription(panel_item);
877+ int dpi = panel_style.GetTextDPI();
878+
879+ if (proxy_->show_now())
880+ {
881+ if (!pango_parse_markup(label.c_str(), -1, '_', &attrs, nullptr, nullptr, nullptr))
882+ {
883+ g_debug("pango_parse_markup failed");
884+ }
885+ }
886+
887+ desc = pango_font_description_from_string(font_description.c_str());
888 pango_font_description_set_weight(desc, PANGO_WEIGHT_NORMAL);
889
890+ nux::CairoGraphics cairo_graphics(CAIRO_FORMAT_ARGB32, 1, 1);
891+ cr = cairo_graphics.GetContext();
892+
893 layout = pango_cairo_create_layout(cr);
894 if (attrs)
895 {
896@@ -267,198 +474,90 @@
897 }
898
899 pango_layout_set_font_description(layout, desc);
900+
901+ boost::erase_all(label, "_");
902 pango_layout_set_text(layout, label.c_str(), -1);
903
904 cxt = pango_layout_get_context(layout);
905 pango_cairo_context_set_font_options(cxt, gdk_screen_get_font_options(screen));
906- pango_cairo_context_set_resolution(cxt, (float)dpi / (float)PANGO_SCALE);
907+ pango_cairo_context_set_resolution(cxt, dpi / static_cast<float>(PANGO_SCALE));
908 pango_layout_context_changed(layout);
909
910- pango_layout_get_extents(layout, NULL, &log_rect);
911+ pango_layout_get_extents(layout, nullptr, &log_rect);
912 text_width = log_rect.width / PANGO_SCALE;
913- text_height = log_rect.height / PANGO_SCALE;
914
915 if (icon_width)
916- width += SPACING;
917+ width += spacing_;
918 width += text_width;
919
920 pango_font_description_free(desc);
921- g_free(font_description);
922 cairo_destroy(cr);
923 }
924
925 if (width)
926- width += padding_ * 2;
927+ width += left_padding_ + right_padding_;
928
929+ width = std::min<int>(width, GetMaximumWidth());
930 SetMinimumWidth(width);
931
932- nux::CairoGraphics cairo_graphics(CAIRO_FORMAT_ARGB32, width, height);
933- cr = cairo_graphics.GetContext();
934+ nux::CairoGraphics cg(CAIRO_FORMAT_ARGB32, width, height);
935+ cr = cg.GetContext();
936 cairo_set_line_width(cr, 1);
937-
938 cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);
939 cairo_paint(cr);
940
941 cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
942-
943- if (IsActive())
944- draw_menu_bg(cr, width, height);
945-
946- x = padding_;
947-
948- if (pixbuf && proxy_->image_visible())
949- {
950- GtkStyleContext* style_context = panel::Style::Instance().GetStyleContext();
951-
952- gtk_style_context_save(style_context);
953-
954- GtkWidgetPath* widget_path = gtk_widget_path_new();
955- gint pos = gtk_widget_path_append_type(widget_path, GTK_TYPE_MENU_BAR);
956- pos = gtk_widget_path_append_type(widget_path, GTK_TYPE_MENU_ITEM);
957- gtk_widget_path_iter_set_name(widget_path, pos, "UnityPanelWidget");
958-
959- gtk_style_context_set_path(style_context, widget_path);
960- gtk_style_context_add_class(style_context, GTK_STYLE_CLASS_MENUBAR);
961- gtk_style_context_add_class(style_context, GTK_STYLE_CLASS_MENUITEM);
962-
963- if (IsActive())
964- gtk_style_context_set_state(style_context, GTK_STATE_FLAG_PRELIGHT);
965-
966- int y = (int)((height - gdk_pixbuf_get_height(pixbuf)) / 2);
967- if (dash_showing_ && !IsActive())
968- {
969- /* Most of the images we get are straight pixbufs (annoyingly), so when
970- * the Dash opens, we use the pixbuf as a mask to punch out an icon from
971- * a white square. It works surprisingly well for most symbolic-type
972- * icon themes/icons.
973- */
974- cairo_save(cr);
975-
976- cairo_push_group(cr);
977- gdk_cairo_set_source_pixbuf(cr, pixbuf, x, y);
978- cairo_paint_with_alpha(cr, proxy_->image_sensitive() ? 1.0 : 0.5);
979-
980- cairo_pattern_t* pat = cairo_pop_group(cr);
981-
982- cairo_set_source_rgba(cr, 1.0f, 1.0f, 1.0f, 1.0f);
983- cairo_rectangle(cr, x, y, width, height);
984- cairo_mask(cr, pat);
985-
986- cairo_pattern_destroy(pat);
987- cairo_restore(cr);
988- }
989- else
990- {
991- cairo_push_group(cr);
992- gtk_render_icon(style_context, cr, pixbuf, x, y);
993- cairo_pop_group_to_source(cr);
994- cairo_paint_with_alpha(cr, proxy_->image_sensitive() ? 1.0 : 0.5);
995- }
996-
997- gtk_widget_path_free(widget_path);
998-
999- gtk_style_context_restore(style_context);
1000-
1001- x += icon_width + SPACING;
1002- }
1003-
1004- if (!label.empty() && proxy_->label_visible())
1005- {
1006- pango_cairo_update_layout(cr, layout);
1007-
1008- GtkStyleContext* style_context = panel::Style::Instance().GetStyleContext();
1009-
1010- gtk_style_context_save(style_context);
1011-
1012- GtkWidgetPath* widget_path = gtk_widget_path_new();
1013- gint pos = gtk_widget_path_append_type(widget_path, GTK_TYPE_MENU_BAR);
1014- pos = gtk_widget_path_append_type(widget_path, GTK_TYPE_MENU_ITEM);
1015- gtk_widget_path_iter_set_name(widget_path, pos, "UnityPanelWidget");
1016-
1017- gtk_style_context_set_path(style_context, widget_path);
1018- gtk_style_context_add_class(style_context, GTK_STYLE_CLASS_MENUBAR);
1019- gtk_style_context_add_class(style_context, GTK_STYLE_CLASS_MENUITEM);
1020-
1021- if (IsActive())
1022- gtk_style_context_set_state(style_context, GTK_STATE_FLAG_PRELIGHT);
1023-
1024- int y = (int)((height - text_height) / 2);
1025- if (dash_showing_)
1026- {
1027- cairo_move_to(cr, x, y);
1028- cairo_set_source_rgb(cr, 1.0f, 1.0f, 1.0f);
1029- pango_cairo_show_layout(cr, layout);
1030- }
1031- else
1032- {
1033- gtk_render_layout(style_context, cr, x, y, layout);
1034- }
1035-
1036- gtk_widget_path_free(widget_path);
1037-
1038- gtk_style_context_restore(style_context);
1039- }
1040-
1041+ DrawEntryContent(cr, width, height, pixbuf, layout);
1042+
1043+ entry_texture_ = texture_from_cairo_graphics(cg);
1044+ SetTexture(entry_texture_);
1045 cairo_destroy(cr);
1046- if (layout)
1047- g_object_unref(layout);
1048-
1049- nux::BaseTexture* texture2D = texture_from_cairo_graphics(cairo_graphics);
1050-
1051- nux::TexCoordXForm texxform;
1052- texxform.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD);
1053- texxform.SetWrap(nux::TEXWRAP_REPEAT, nux::TEXWRAP_REPEAT);
1054-
1055- nux::ROPConfig rop;
1056- rop.Blend = true;
1057- rop.SrcBlend = GL_ONE;
1058- rop.DstBlend = GL_ONE_MINUS_SRC_ALPHA;
1059-
1060- if (texture_layer_)
1061- delete texture_layer_;
1062-
1063- texture_layer_ = new nux::TextureLayer(texture2D->GetDeviceTexture(), texxform,
1064- nux::color::White, true, rop);
1065- SetPaintLayer(texture_layer_);
1066-
1067- texture2D->UnReference();
1068-
1069- NeedRedraw();
1070-
1071+
1072+ SetVisible(true);
1073 refreshed.emit(this);
1074+ QueueDraw();
1075 }
1076
1077 void PanelIndicatorEntryView::Draw(nux::GraphicsEngine& GfxContext, bool force_draw)
1078 {
1079- if (opacity_ == 1.0f)
1080- {
1081- TextureArea::Draw(GfxContext, force_draw);
1082- return;
1083- }
1084-
1085- auto geo = GetGeometry();
1086+ nux::Geometry const& geo = GetGeometry();
1087 GfxContext.PushClippingRectangle(geo);
1088
1089- if (texture_layer_)
1090- {
1091+ if (cached_geo_ != geo)
1092+ {
1093+ Refresh();
1094+ cached_geo_ = geo;
1095+ }
1096+
1097+ if (entry_texture_ && opacity_ > 0.0f)
1098+ {
1099+ /* "Clear" out the background */
1100+ nux::ROPConfig rop;
1101+ rop.Blend = true;
1102+ rop.SrcBlend = GL_ONE;
1103+ rop.DstBlend = GL_ONE_MINUS_SRC_ALPHA;
1104+
1105+ nux::ColorLayer layer(nux::color::Transparent, true, rop);
1106+ nux::GetPainter().PushDrawLayer(GfxContext, geo, &layer);
1107+
1108 nux::TexCoordXForm texxform;
1109 GfxContext.QRP_1Tex(geo.x, geo.y, geo.width, geo.height,
1110- texture_layer_->GetDeviceTexture(), texxform,
1111+ entry_texture_->GetDeviceTexture(), texxform,
1112 nux::color::White * opacity_);
1113 }
1114
1115 GfxContext.PopClippingRectangle();
1116 }
1117
1118-void PanelIndicatorEntryView::DashShown()
1119+void PanelIndicatorEntryView::OverlayShown()
1120 {
1121- dash_showing_ = true;
1122+ overlay_showing_ = true;
1123 Refresh();
1124 }
1125
1126-void PanelIndicatorEntryView::DashHidden()
1127+void PanelIndicatorEntryView::OverlayHidden()
1128 {
1129- dash_showing_ = false;
1130+ overlay_showing_ = false;
1131 Refresh();
1132 }
1133
1134@@ -478,60 +577,131 @@
1135 return opacity_;
1136 }
1137
1138+PanelIndicatorEntryView::IndicatorEntryType PanelIndicatorEntryView::GetType() const
1139+{
1140+ return type_;
1141+}
1142+
1143+std::string PanelIndicatorEntryView::GetLabel() const
1144+{
1145+ if (proxy_.get())
1146+ {
1147+ return proxy_->label();
1148+ }
1149+
1150+ return "";
1151+}
1152+
1153+bool PanelIndicatorEntryView::IsLabelVisible() const
1154+{
1155+ if (proxy_.get())
1156+ {
1157+ return proxy_->label_visible();
1158+ }
1159+
1160+ return false;
1161+}
1162+
1163+bool PanelIndicatorEntryView::IsLabelSensitive() const
1164+{
1165+ if (proxy_.get())
1166+ {
1167+ return proxy_->label_sensitive();
1168+ }
1169+
1170+ return false;
1171+}
1172+
1173+bool PanelIndicatorEntryView::IsIconVisible() const
1174+{
1175+ if (proxy_.get())
1176+ {
1177+ return proxy_->image_visible();
1178+ }
1179+
1180+ return false;
1181+}
1182+
1183+bool PanelIndicatorEntryView::IsIconSensitive() const
1184+{
1185+ if (proxy_.get())
1186+ {
1187+ return proxy_->image_sensitive();
1188+ }
1189+
1190+ return false;
1191+}
1192+
1193 std::string PanelIndicatorEntryView::GetName() const
1194 {
1195- return proxy_->id();
1196+ return "IndicatorEntry";
1197 }
1198
1199 void PanelIndicatorEntryView::AddProperties(GVariantBuilder* builder)
1200 {
1201 variant::BuilderWrapper(builder)
1202 .add(GetGeometry())
1203- .add("label", proxy_->label())
1204- .add("label_sensitive", proxy_->label_sensitive())
1205- .add("label_visible", proxy_->label_visible())
1206- .add("icon_sensitive", proxy_->image_sensitive())
1207- .add("icon_visible", proxy_->image_visible())
1208+ .add("id", GetEntryID())
1209+ .add("name_hint", proxy_->name_hint())
1210+ .add("type", GetType())
1211+ .add("label", GetLabel())
1212+ .add("label_sensitive", IsLabelSensitive())
1213+ .add("label_visible", IsLabelVisible())
1214+ .add("icon_sensitive", IsIconSensitive())
1215+ .add("icon_visible", IsIconVisible())
1216+ .add("entry_visible", IsVisible())
1217 .add("active", proxy_->active())
1218- .add("priority", proxy_->priority());
1219+ .add("priority", proxy_->priority())
1220+ .add("focused", IsFocused());
1221 }
1222
1223-bool PanelIndicatorEntryView::GetShowNow()
1224+bool PanelIndicatorEntryView::GetShowNow() const
1225 {
1226 return proxy_.get() ? proxy_->show_now() : false;
1227 }
1228
1229-void PanelIndicatorEntryView::GetGeometryForSync(indicator::EntryLocationMap& locations)
1230+void PanelIndicatorEntryView::GetGeometryForSync(EntryLocationMap& locations)
1231 {
1232 if (!IsVisible())
1233 return;
1234
1235- locations[proxy_->id()] = GetAbsoluteGeometry();
1236-}
1237-
1238-bool PanelIndicatorEntryView::IsEntryValid() const
1239-{
1240- if (proxy_.get())
1241- {
1242- return proxy_->image_visible() || proxy_->label_visible();
1243- }
1244- return false;
1245+ locations[GetEntryID()] = GetAbsoluteGeometry();
1246 }
1247
1248 bool PanelIndicatorEntryView::IsSensitive() const
1249 {
1250 if (proxy_.get())
1251 {
1252- return proxy_->image_sensitive() || proxy_->label_sensitive();
1253+ return IsIconSensitive() || IsLabelSensitive();
1254 }
1255 return false;
1256 }
1257
1258+bool PanelIndicatorEntryView::IsVisible()
1259+{
1260+ if (proxy_.get())
1261+ {
1262+ return TextureArea::IsVisible() && proxy_->visible();
1263+ }
1264+
1265+ return TextureArea::IsVisible();
1266+}
1267+
1268 bool PanelIndicatorEntryView::IsActive() const
1269 {
1270 return draw_active_;
1271 }
1272
1273+std::string PanelIndicatorEntryView::GetEntryID() const
1274+{
1275+ if (proxy_.get())
1276+ {
1277+ return proxy_->id();
1278+ }
1279+
1280+ return "";
1281+}
1282+
1283 int PanelIndicatorEntryView::GetEntryPriority() const
1284 {
1285 if (proxy_.get())
1286@@ -551,95 +721,18 @@
1287 return (disabled_ || !proxy_.get() || !IsSensitive());
1288 }
1289
1290-bool PanelIndicatorEntryView::IsVisible()
1291-{
1292- if (proxy_.get())
1293- {
1294- return proxy_->visible();
1295- }
1296- return false;
1297-}
1298-
1299-void PanelIndicatorEntryView::OnFontChanged(GObject* gobject, GParamSpec* pspec,
1300- gpointer data)
1301-{
1302- PanelIndicatorEntryView* self = reinterpret_cast<PanelIndicatorEntryView*>(data);
1303- self->Refresh();
1304-}
1305-
1306-namespace
1307-{
1308-
1309-void draw_menu_bg(cairo_t* cr, int width, int height)
1310-{
1311- GtkStyleContext* style_context = panel::Style::Instance().GetStyleContext();
1312-
1313- gtk_style_context_save(style_context);
1314-
1315- GtkWidgetPath* widget_path = gtk_widget_path_new();
1316- gint pos = gtk_widget_path_append_type(widget_path, GTK_TYPE_WINDOW);
1317- gtk_widget_path_iter_set_name(widget_path, pos, "UnityPanelWidget");
1318- gtk_widget_path_append_type(widget_path, GTK_TYPE_MENU_BAR);
1319- gtk_widget_path_append_type(widget_path, GTK_TYPE_MENU_ITEM);
1320-
1321- gtk_style_context_set_path(style_context, widget_path);
1322- gtk_style_context_add_class(style_context, GTK_STYLE_CLASS_MENUBAR);
1323- gtk_style_context_add_class(style_context, GTK_STYLE_CLASS_MENUITEM);
1324- gtk_style_context_set_state(style_context, GTK_STATE_FLAG_PRELIGHT);
1325-
1326- gtk_render_background(style_context, cr, 0, 0, width, height);
1327- gtk_render_frame(style_context, cr, 0, 0, width, height);
1328-
1329- gtk_widget_path_free(widget_path);
1330-
1331- gtk_style_context_restore(style_context);
1332-}
1333-
1334-GdkPixbuf* make_pixbuf(int image_type, std::string const& image_data, bool dash_showing)
1335-{
1336- GdkPixbuf* ret = NULL;
1337- GtkIconTheme* theme = gtk_icon_theme_get_default();
1338-
1339- if (image_type == GTK_IMAGE_PIXBUF)
1340- {
1341- gsize len = 0;
1342- guchar* decoded = g_base64_decode(image_data.c_str(), &len);
1343-
1344- GInputStream* stream = g_memory_input_stream_new_from_data(decoded,
1345- len, NULL);
1346-
1347- ret = gdk_pixbuf_new_from_stream(stream, NULL, NULL);
1348-
1349- g_free(decoded);
1350- g_input_stream_close(stream, NULL, NULL);
1351- g_object_unref(stream);
1352- }
1353- else if (image_type == GTK_IMAGE_STOCK ||
1354- image_type == GTK_IMAGE_ICON_NAME)
1355- {
1356- ret = gtk_icon_theme_load_icon(theme,
1357- image_data.c_str(),
1358- 22,
1359- (GtkIconLookupFlags)0,
1360- NULL);
1361- }
1362- else if (image_type == GTK_IMAGE_GICON)
1363- {
1364- glib::Object<GIcon> icon(g_icon_new_for_string(image_data.c_str(), NULL));
1365-
1366- GtkIconInfo* info = gtk_icon_theme_lookup_by_gicon(
1367- theme, icon, 22, (GtkIconLookupFlags)0);
1368- if (info)
1369- {
1370- ret = gtk_icon_info_load_icon(info, NULL);
1371- gtk_icon_info_free(info);
1372- }
1373- }
1374-
1375- return ret;
1376-}
1377-
1378-} // anon namespace
1379-
1380+void PanelIndicatorEntryView::SetFocusedState(bool focused)
1381+{
1382+ if (focused_ != focused)
1383+ {
1384+ focused_ = focused;
1385+ Refresh();
1386+ }
1387+}
1388+
1389+bool PanelIndicatorEntryView::IsFocused() const
1390+{
1391+ return focused_;
1392+}
1393
1394 } // namespace unity
1395
1396=== modified file 'plugins/unityshell/src/PanelIndicatorEntryView.h'
1397--- plugins/unityshell/src/PanelIndicatorEntryView.h 2012-03-21 12:31:11 +0000
1398+++ plugins/unityshell/src/PanelIndicatorEntryView.h 2012-04-05 23:42:20 +0000
1399@@ -1,6 +1,6 @@
1400 // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
1401 /*
1402- * Copyright (C) 2010 Canonical Ltd
1403+ * Copyright (C) 2010-2012 Canonical Ltd
1404 *
1405 * This program is free software: you can redistribute it and/or modify
1406 * it under the terms of the GNU General Public License version 3 as
1407@@ -15,6 +15,7 @@
1408 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1409 *
1410 * Authored by: Neil Jagdish Patel <neil.patel@canonical.com>
1411+ * Marco Trevisan (Treviño) <3v1n0@ubuntu.com>
1412 */
1413
1414 #ifndef PANEL_INDICATOR_OBJECT_ENTRY_VIEW_H
1415@@ -26,78 +27,101 @@
1416 #include <NuxGraphics/GraphicsEngine.h>
1417
1418 #include <UnityCore/IndicatorEntry.h>
1419+#include <UnityCore/GLibWrapper.h>
1420+#include <UnityCore/GLibSignal.h>
1421+
1422+#include <gtk/gtk.h>
1423
1424 #include "Introspectable.h"
1425
1426
1427 namespace unity
1428 {
1429-
1430-class PanelIndicatorEntryView : public nux::TextureArea, public unity::debug::Introspectable
1431+class PanelIndicatorEntryView : public nux::TextureArea, public debug::Introspectable
1432 {
1433 public:
1434- typedef enum {
1435+ enum IndicatorEntryType {
1436 INDICATOR,
1437 MENU,
1438 OTHER
1439- } IndicatorEntryType;
1440+ };
1441
1442 PanelIndicatorEntryView(indicator::Entry::Ptr const& proxy, int padding = 5,
1443 IndicatorEntryType type = INDICATOR);
1444- ~PanelIndicatorEntryView();
1445-
1446- void Refresh();
1447-
1448- void Activate(int button = 1);
1449- void Unactivate();
1450- bool GetShowNow();
1451+
1452+ virtual ~PanelIndicatorEntryView();
1453+
1454+ IndicatorEntryType GetType() const;
1455+ std::string GetEntryID() const;
1456+ int GetEntryPriority() const;
1457+
1458+ virtual std::string GetLabel() const;
1459+ virtual bool IsLabelVisible() const;
1460+ virtual bool IsLabelSensitive() const;
1461+
1462+ virtual bool IsIconVisible() const;
1463+ virtual bool IsIconSensitive() const;
1464+
1465+ virtual void Activate(int button = 1);
1466+ virtual void Unactivate();
1467+
1468+ virtual void GetGeometryForSync(indicator::EntryLocationMap& locations);
1469+
1470+ bool GetShowNow() const;
1471+ bool IsSensitive() const;
1472+ bool IsActive() const;
1473+ bool IsVisible();
1474+
1475 void SetDisabled(bool disabled);
1476 bool IsDisabled();
1477+
1478 void SetOpacity(double alpha);
1479 double GetOpacity();
1480
1481- void GetGeometryForSync(indicator::EntryLocationMap& locations);
1482- bool IsEntryValid() const;
1483- bool IsSensitive() const;
1484- bool IsActive() const;
1485- bool IsVisible();
1486- int GetEntryPriority() const;
1487-
1488- void DashShown();
1489- void DashHidden();
1490-
1491+ void SetFocusedState(bool focused);
1492+ bool IsFocused() const;
1493+
1494+ void OverlayShown();
1495+ void OverlayHidden();
1496+
1497+ sigc::signal<void, PanelIndicatorEntryView*, bool> active_changed;
1498+ sigc::signal<void, PanelIndicatorEntryView*> refreshed;
1499+
1500+protected:
1501 std::string GetName() const;
1502- void AddProperties(GVariantBuilder* builder);
1503+ void AddProperties(GVariantBuilder* builder);
1504
1505 virtual void Draw(nux::GraphicsEngine& GfxContext, bool force_draw);
1506-
1507- sigc::signal<void, PanelIndicatorEntryView*, bool> active_changed;
1508- sigc::signal<void, PanelIndicatorEntryView*> refreshed;
1509+ virtual void DrawEntryPrelight(cairo_t* cr, unsigned int w, unsigned int h);
1510+ virtual void DrawEntryContent(cairo_t* cr, unsigned int width, unsigned int height,
1511+ glib::Object<GdkPixbuf> const& pixbuf,
1512+ glib::Object<PangoLayout> const& layout);
1513+
1514+ void Refresh();
1515+ void SetActiveState(bool active, int button);
1516+ virtual void ShowMenu(int button = 1);
1517+
1518+ indicator::Entry::Ptr proxy_;
1519+ unsigned int spacing_;
1520+ unsigned int left_padding_;
1521+ unsigned int right_padding_;
1522
1523 private:
1524- unity::indicator::Entry::Ptr proxy_;
1525+ void OnMouseDown(int x, int y, long button_flags, long key_flags);
1526+ void OnMouseUp(int x, int y, long button_flags, long key_flags);
1527+ void OnMouseWheel(int x, int y, int delta, unsigned long mouse_state, unsigned long key_state);
1528+ void OnActiveChanged(bool is_active);
1529+
1530+ glib::Object<GdkPixbuf> MakePixbuf();
1531+
1532 IndicatorEntryType type_;
1533- nux::CairoGraphics util_cg_;
1534- nux::TextureLayer* texture_layer_;
1535- int padding_;
1536+ nux::BaseTexture* entry_texture_;
1537+ nux::Geometry cached_geo_;
1538 double opacity_;
1539 bool draw_active_;
1540- bool dash_showing_;
1541+ bool overlay_showing_;
1542 bool disabled_;
1543- gulong on_font_changed_connection_;
1544-
1545- static void OnFontChanged(GObject* gobject, GParamSpec* pspec, gpointer data);
1546- void OnMouseDown(int x, int y, long button_flags, long key_flags);
1547- void OnMouseUp(int x, int y, long button_flags, long key_flags);
1548- void OnMouseWheel(int x, int y, int delta, unsigned long mouse_state, unsigned long key_state);
1549- void OnActiveChanged(bool is_active);
1550-
1551- void SetActiveState(bool active, int button);
1552- void ShowMenu(int button);
1553-
1554- sigc::connection on_indicator_activate_changed_connection_;
1555- sigc::connection on_indicator_updated_connection_;
1556- sigc::connection on_panelstyle_changed_connection_;
1557+ bool focused_;
1558 };
1559
1560 }
1561
1562=== modified file 'plugins/unityshell/src/PanelIndicatorsView.cpp'
1563--- plugins/unityshell/src/PanelIndicatorsView.cpp 2012-03-21 12:31:11 +0000
1564+++ plugins/unityshell/src/PanelIndicatorsView.cpp 2012-04-05 23:42:20 +0000
1565@@ -1,6 +1,6 @@
1566 // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
1567 /*
1568- * Copyright (C) 2011 Canonical Ltd
1569+ * Copyright (C) 2011-2012 Canonical Ltd
1570 *
1571 * This program is free software: you can redistribute it and/or modify
1572 * it under the terms of the GNU General Public License version 3 as
1573@@ -14,7 +14,7 @@
1574 * You should have received a copy of the GNU General Public License
1575 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1576 *
1577- * Authored by: Marco Trevisan (Treviño) <mail@3v1n0.net>
1578+ * Authored by: Marco Trevisan (Treviño) <3v1n0@ubuntu.com>
1579 * Neil Jagdish Patel <neil.patel@canonical.com>
1580 */
1581
1582@@ -36,6 +36,8 @@
1583
1584 namespace unity
1585 {
1586+using namespace indicator;
1587+
1588 NUX_IMPLEMENT_OBJECT_TYPE(PanelIndicatorsView);
1589
1590 PanelIndicatorsView::PanelIndicatorsView()
1591@@ -45,8 +47,9 @@
1592 {
1593 LOG_DEBUG(logger) << "Indicators View Added: ";
1594 layout_ = new nux::HLayout("", NUX_TRACKER_LOCATION);
1595+ layout_->SetContentDistribution(nux::eStackRight);
1596
1597- SetCompositionLayout(layout_);
1598+ SetLayout(layout_);
1599 }
1600
1601 PanelIndicatorsView::~PanelIndicatorsView()
1602@@ -59,7 +62,7 @@
1603 }
1604
1605 void
1606-PanelIndicatorsView::AddIndicator(indicator::Indicator::Ptr const& indicator)
1607+PanelIndicatorsView::AddIndicator(Indicator::Ptr const& indicator)
1608 {
1609 LOG_DEBUG(logger) << "IndicatorAdded: " << indicator->name();
1610 indicators_.push_back(indicator);
1611@@ -76,7 +79,7 @@
1612 }
1613
1614 void
1615-PanelIndicatorsView::RemoveIndicator(indicator::Indicator::Ptr const& indicator)
1616+PanelIndicatorsView::RemoveIndicator(Indicator::Ptr const& indicator)
1617 {
1618 auto connections = indicators_connections_.find(indicator);
1619
1620@@ -88,7 +91,7 @@
1621 }
1622
1623 for (auto entry : indicator->GetEntries())
1624- OnEntryRemoved (entry->id());
1625+ OnEntryRemoved(entry->id());
1626
1627 for (auto i = indicators_.begin(); i != indicators_.end(); i++)
1628 {
1629@@ -102,6 +105,12 @@
1630 LOG_DEBUG(logger) << "IndicatorRemoved: " << indicator->name();
1631 }
1632
1633+PanelIndicatorsView::Indicators
1634+PanelIndicatorsView::GetIndicators()
1635+{
1636+ return indicators_;
1637+}
1638+
1639 void
1640 PanelIndicatorsView::Draw(nux::GraphicsEngine& GfxContext, bool force_draw)
1641 {
1642@@ -121,16 +130,45 @@
1643 entry.second->QueueDraw();
1644 }
1645
1646+void
1647+PanelIndicatorsView::SetMaximumEntriesWidth(int max_width)
1648+{
1649+ unsigned int n_entries = 0;
1650+
1651+ for (auto entry : entries_)
1652+ if (entry.second->IsVisible())
1653+ n_entries++;
1654+
1655+ if (n_entries > 0)
1656+ {
1657+ for (auto entry : entries_)
1658+ {
1659+ if (entry.second->IsVisible() && n_entries > 0)
1660+ {
1661+ int max_entry_width = max_width / n_entries;
1662+
1663+ if (entry.second->GetBaseWidth() > max_entry_width)
1664+ entry.second->SetMaximumWidth(max_entry_width);
1665+
1666+ max_width -= entry.second->GetBaseWidth();
1667+ --n_entries;
1668+ }
1669+ }
1670+ }
1671+}
1672+
1673 PanelIndicatorEntryView*
1674-PanelIndicatorsView::ActivateEntry(std::string const& entry_id)
1675+PanelIndicatorsView::ActivateEntry(std::string const& entry_id, int button)
1676 {
1677 auto entry = entries_.find(entry_id);
1678
1679- if (entry != entries_.end() && entry->second->IsEntryValid())
1680+ if (entry != entries_.end())
1681 {
1682 PanelIndicatorEntryView* view = entry->second;
1683- LOG_DEBUG(logger) << "Activating: " << entry_id;
1684- view->Activate();
1685+
1686+ if (view->IsSensitive() && view->IsVisible())
1687+ view->Activate(button);
1688+
1689 return view;
1690 }
1691
1692@@ -148,24 +186,27 @@
1693 for (auto entry : sorted_entries)
1694 {
1695 PanelIndicatorEntryView* view = entry.second;
1696- if (view->IsSensitive())
1697+
1698+ if (view->IsSensitive() && view->IsVisible() && view->IsFocused())
1699 {
1700- view->Activate();
1701+ /* Use the 0 button, it means it's a keyboard activation */
1702+ view->Activate(0);
1703 return true;
1704 }
1705 }
1706+
1707 return false;
1708 }
1709
1710 void
1711-PanelIndicatorsView::GetGeometryForSync(indicator::EntryLocationMap& locations)
1712+PanelIndicatorsView::GetGeometryForSync(EntryLocationMap& locations)
1713 {
1714 for (auto entry : entries_)
1715 entry.second->GetGeometryForSync(locations);
1716 }
1717
1718 PanelIndicatorEntryView*
1719-PanelIndicatorsView::ActivateEntryAt(int x, int y)
1720+PanelIndicatorsView::ActivateEntryAt(int x, int y, int button)
1721 {
1722 PanelIndicatorEntryView* target = nullptr;
1723 bool found_old_active = false;
1724@@ -180,9 +221,10 @@
1725 {
1726 PanelIndicatorEntryView* view = entry.second;
1727
1728- if (!target && view->IsVisible() && view->GetAbsoluteGeometry().IsPointInside(x, y))
1729+ if (!target && view->IsVisible() && view->IsFocused() &&
1730+ view->GetAbsoluteGeometry().IsPointInside(x, y))
1731 {
1732- view->Activate(0);
1733+ view->Activate(button);
1734 target = view;
1735 break;
1736 }
1737@@ -219,11 +261,13 @@
1738 GfxContext.PopClippingRectangle();
1739 }
1740
1741-PanelIndicatorEntryView *
1742-PanelIndicatorsView::AddEntry(indicator::Entry::Ptr const& entry, int padding,
1743- IndicatorEntryPosition pos, IndicatorEntryType type)
1744+void
1745+PanelIndicatorsView::AddEntryView(PanelIndicatorEntryView* view,
1746+ IndicatorEntryPosition pos)
1747 {
1748- auto view = new PanelIndicatorEntryView(entry, padding, type);
1749+ if (!view)
1750+ return;
1751+
1752 int entry_pos = pos;
1753
1754 view->SetOpacity(opacity_);
1755@@ -233,7 +277,7 @@
1756 {
1757 entry_pos = nux::NUX_LAYOUT_BEGIN;
1758
1759- if (entry->priority() > -1)
1760+ if (view->GetEntryPriority() > -1)
1761 {
1762 for (auto area : layout_->GetChildren())
1763 {
1764@@ -241,7 +285,7 @@
1765
1766 if (en)
1767 {
1768- if (en && entry->priority() <= en->GetEntryPriority())
1769+ if (en && view->GetEntryPriority() <= en->GetEntryPriority())
1770 break;
1771
1772 entry_pos++;
1773@@ -251,20 +295,28 @@
1774 }
1775
1776 layout_->AddView(view, 0, nux::eCenter, nux::eFull, 1.0, (nux::LayoutPosition) entry_pos);
1777- layout_->SetContentDistribution(nux::eStackRight);
1778- entries_[entry->id()] = view;
1779+
1780+ entries_[view->GetEntryID()] = view;
1781
1782 AddChild(view);
1783 QueueRelayout();
1784 QueueDraw();
1785
1786 on_indicator_updated.emit(view);
1787+}
1788+
1789+PanelIndicatorEntryView *
1790+PanelIndicatorsView::AddEntry(Entry::Ptr const& entry, int padding,
1791+ IndicatorEntryPosition pos, IndicatorEntryType type)
1792+{
1793+ auto view = new PanelIndicatorEntryView(entry, padding, type);
1794+ AddEntryView(view, pos);
1795
1796 return view;
1797 }
1798
1799 void
1800-PanelIndicatorsView::OnEntryAdded(indicator::Entry::Ptr const& entry)
1801+PanelIndicatorsView::OnEntryAdded(Entry::Ptr const& entry)
1802 {
1803 AddEntry(entry);
1804 }
1805@@ -279,19 +331,25 @@
1806 }
1807
1808 void
1809+PanelIndicatorsView::RemoveEntryView(PanelIndicatorEntryView* view)
1810+{
1811+ if (!view)
1812+ return;
1813+
1814+ std::string const& entry_id = view->GetEntryID();
1815+ RemoveChild(view);
1816+ on_indicator_updated.emit(view);
1817+ entries_.erase(entry_id);
1818+ layout_->RemoveChildObject(view);
1819+
1820+ QueueRelayout();
1821+ QueueDraw();
1822+}
1823+
1824+void
1825 PanelIndicatorsView::RemoveEntry(std::string const& entry_id)
1826 {
1827- PanelIndicatorEntryView* view = entries_[entry_id];
1828-
1829- if (view)
1830- {
1831- layout_->RemoveChildObject(view);
1832- entries_.erase(entry_id);
1833- on_indicator_updated.emit(view);
1834-
1835- QueueRelayout();
1836- QueueDraw();
1837- }
1838+ RemoveEntryView(entries_[entry_id]);
1839 }
1840
1841 void
1842@@ -301,17 +359,17 @@
1843 }
1844
1845 void
1846-PanelIndicatorsView::DashShown()
1847+PanelIndicatorsView::OverlayShown()
1848 {
1849 for (auto entry: entries_)
1850- entry.second->DashShown();
1851+ entry.second->OverlayShown();
1852 }
1853
1854 void
1855-PanelIndicatorsView::DashHidden()
1856+PanelIndicatorsView::OverlayHidden()
1857 {
1858 for (auto entry: entries_)
1859- entry.second->DashHidden();
1860+ entry.second->OverlayHidden();
1861 }
1862
1863 double
1864@@ -337,13 +395,16 @@
1865
1866 std::string PanelIndicatorsView::GetName() const
1867 {
1868- return "IndicatorsView";
1869+ return "Indicators";
1870 }
1871
1872 void
1873 PanelIndicatorsView::AddProperties(GVariantBuilder* builder)
1874 {
1875- variant::BuilderWrapper(builder).add(GetGeometry());
1876+ variant::BuilderWrapper(builder)
1877+ .add(GetGeometry())
1878+ .add("entries", entries_.size())
1879+ .add("opacity", opacity_);
1880 }
1881
1882 } // namespace unity
1883
1884=== modified file 'plugins/unityshell/src/PanelIndicatorsView.h'
1885--- plugins/unityshell/src/PanelIndicatorsView.h 2012-03-21 12:31:11 +0000
1886+++ plugins/unityshell/src/PanelIndicatorsView.h 2012-04-05 23:42:20 +0000
1887@@ -42,11 +42,11 @@
1888 void AddIndicator(indicator::Indicator::Ptr const& indicator);
1889 void RemoveIndicator(indicator::Indicator::Ptr const& indicator);
1890
1891- typedef enum {
1892+ enum IndicatorEntryPosition {
1893 AUTO = -1,
1894 START = nux::NUX_LAYOUT_BEGIN,
1895 END = nux::NUX_LAYOUT_END,
1896- } IndicatorEntryPosition;
1897+ };
1898
1899 typedef PanelIndicatorEntryView::IndicatorEntryType IndicatorEntryType;
1900
1901@@ -56,37 +56,46 @@
1902 IndicatorEntryType type = IndicatorEntryType::INDICATOR);
1903 void RemoveEntry(std::string const& entry_id);
1904
1905- PanelIndicatorEntryView* ActivateEntryAt(int x, int y);
1906- PanelIndicatorEntryView* ActivateEntry(std::string const& entry_id);
1907+ PanelIndicatorEntryView* ActivateEntryAt(int x, int y, int button = 1);
1908+ PanelIndicatorEntryView* ActivateEntry(std::string const& entry_id, int button = 1);
1909 bool ActivateIfSensitive();
1910+
1911+ virtual void OverlayShown();
1912+ virtual void OverlayHidden();
1913+
1914+ void SetOpacity(double opacity);
1915+ double GetOpacity();
1916+
1917+ void SetMaximumEntriesWidth(int max_width);
1918 void GetGeometryForSync(indicator::EntryLocationMap& locations);
1919
1920+ virtual void QueueDraw();
1921+
1922+ sigc::signal<void, PanelIndicatorEntryView*> on_indicator_updated;
1923+
1924+protected:
1925+ std::string GetName() const;
1926+ void AddProperties(GVariantBuilder* builder);
1927+
1928+ typedef std::vector<indicator::Indicator::Ptr> Indicators;
1929+ Indicators GetIndicators();
1930+
1931 virtual void Draw(nux::GraphicsEngine& GfxContext, bool force_draw);
1932 virtual void DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw);
1933- virtual void QueueDraw();
1934
1935 virtual void OnEntryAdded(indicator::Entry::Ptr const& entry);
1936 virtual void OnEntryRefreshed(PanelIndicatorEntryView* view);
1937 virtual void OnEntryRemoved(std::string const& entry_id);
1938
1939- void DashShown();
1940- void DashHidden();
1941-
1942- void SetOpacity(double opacity);
1943- double GetOpacity();
1944-
1945- sigc::signal<void, PanelIndicatorEntryView*> on_indicator_updated;
1946-
1947-protected:
1948+ virtual void AddEntryView(PanelIndicatorEntryView* view,
1949+ IndicatorEntryPosition pos = AUTO);
1950+ virtual void RemoveEntryView(PanelIndicatorEntryView* view);
1951+
1952 nux::HLayout* layout_;
1953 typedef std::map<std::string, PanelIndicatorEntryView*> Entries;
1954 Entries entries_;
1955
1956- std::string GetName() const;
1957- void AddProperties(GVariantBuilder* builder);
1958-
1959 private:
1960- typedef std::vector<indicator::Indicator::Ptr> Indicators;
1961 Indicators indicators_;
1962 double opacity_;
1963
1964
1965=== modified file 'plugins/unityshell/src/PanelMenuView.cpp'
1966--- plugins/unityshell/src/PanelMenuView.cpp 2012-04-03 03:36:34 +0000
1967+++ plugins/unityshell/src/PanelMenuView.cpp 2012-04-05 23:42:20 +0000
1968@@ -1,6 +1,6 @@
1969 // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
1970 /*
1971- * Copyright (C) 2010 Canonical Ltd
1972+ * Copyright (C) 2010-2012 Canonical Ltd
1973 *
1974 * This program is free software: you can redistribute it and/or modify
1975 * it under the terms of the GNU General Public License version 3 as
1976@@ -15,61 +15,52 @@
1977 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1978 *
1979 * Authored by: Neil Jagdish Patel <neil.patel@canonical.com>
1980- * Marco Trevisan <mail@3v1n0.net>
1981+ * Marco Trevisan <3v1n0@ubuntu.com>
1982 */
1983-#include <glib.h>
1984-#include <pango/pangocairo.h>
1985-#include <gtk/gtk.h>
1986
1987 #include <Nux/Nux.h>
1988-#include <Nux/HLayout.h>
1989-#include <Nux/VLayout.h>
1990-#include <Nux/TextureArea.h>
1991-
1992-#include <NuxGraphics/GLThread.h>
1993-#include <NuxGraphics/XInputWindow.h>
1994-#include <Nux/BaseWindow.h>
1995+#include <NuxCore/Logger.h>
1996
1997 #include "CairoTexture.h"
1998 #include "PanelMenuView.h"
1999 #include "PanelStyle.h"
2000-#include <UnityCore/Variant.h>
2001-
2002-#include <gio/gdesktopappinfo.h>
2003-#include <gconf/gconf-client.h>
2004-
2005-#include <glib.h>
2006-#include <glib/gi18n-lib.h>
2007-
2008 #include "DashSettings.h"
2009-#include "ubus-server.h"
2010 #include "UBusMessages.h"
2011-
2012 #include "UScreen.h"
2013
2014+#include <UnityCore/Variant.h>
2015+
2016+#include <glib/gi18n-lib.h>
2017+
2018 namespace unity
2019 {
2020
2021 namespace
2022 {
2023- const std::string WINDOW_TITLE_FONT_KEY = "/apps/metacity/general/titlebar_font";
2024+ nux::logging::Logger logger("unity.panel.menu");
2025+ const int MAIN_LEFT_PADDING = 4;
2026+ const int TITLE_PADDING = 2;
2027+ const int MENUBAR_PADDING = 4;
2028+ const int MENU_ENTRIES_PADDING = 6;
2029+ const int DEFAULT_MENUS_FADEIN = 100;
2030+ const int DEFAULT_MENUS_FADEOUT = 120;
2031+ const int DEFAULT_MENUS_DISCOVERY = 2;
2032+ const int DEFAULT_DISCOVERY_FADEIN = 200;
2033+ const int DEFAULT_DISCOVERY_FADEOUT = 300;
2034+
2035+ const std::string DESKTOP_NAME(_("Ubuntu Desktop"));
2036 }
2037
2038-PanelMenuView::PanelMenuView(int padding)
2039+PanelMenuView::PanelMenuView()
2040 : _matcher(bamf_matcher_get_default()),
2041- _title_layer(nullptr),
2042- _util_cg(CAIRO_FORMAT_ARGB32, 1, 1),
2043- _gradient_texture(nullptr),
2044 _is_inside(false),
2045 _is_grabbed(false),
2046 _is_maximized(false),
2047- _is_own_window(false),
2048 _last_active_view(nullptr),
2049 _new_application(nullptr),
2050- _last_width(0),
2051- _last_height(0),
2052- _places_showing(false),
2053+ _overlay_showing(false),
2054 _switcher_showing(false),
2055+ _launcher_keynav(false),
2056 _show_now_activated(false),
2057 _we_control_active(false),
2058 _new_app_menu_shown(false),
2059@@ -79,26 +70,19 @@
2060 _update_show_now_id(0),
2061 _new_app_show_id(0),
2062 _new_app_hide_id(0),
2063- _menus_fadein(100),
2064- _menus_fadeout(120),
2065- _menus_discovery(2),
2066- _menus_discovery_fadein(200),
2067- _menus_discovery_fadeout(300),
2068- _panel_title(nullptr),
2069- _fade_in_animator(nullptr),
2070- _fade_out_animator(nullptr)
2071+ _menus_fadein(DEFAULT_MENUS_FADEIN),
2072+ _menus_fadeout(DEFAULT_MENUS_FADEOUT),
2073+ _menus_discovery(DEFAULT_MENUS_DISCOVERY),
2074+ _menus_discovery_fadein(DEFAULT_DISCOVERY_FADEIN),
2075+ _menus_discovery_fadeout(DEFAULT_DISCOVERY_FADEOUT),
2076+ _fade_in_animator(_menus_fadein),
2077+ _fade_out_animator(_menus_fadeout)
2078 {
2079- WindowManager* win_manager;
2080-
2081- // TODO: kill _menu_layout - should just use the _layout defined
2082- // in the base class.
2083- _menu_layout = new nux::HLayout("", NUX_TRACKER_LOCATION);
2084- _menu_layout->SetParentObject(this);
2085-
2086- /* This is for our parent and for PanelView to read indicator entries, we
2087- * shouldn't touch this again
2088- */
2089- layout_ = _menu_layout;
2090+ layout_->SetContentDistribution(nux::eStackLeft);
2091+
2092+ BamfWindow* active_win = bamf_matcher_get_active_window(_matcher);
2093+ if (BAMF_IS_WINDOW(active_win))
2094+ _active_xid = bamf_window_get_xid(active_win);
2095
2096 _view_opened_signal.Connect(_matcher, "view-opened",
2097 sigc::mem_fun(this, &PanelMenuView::OnViewOpened));
2098@@ -109,35 +93,35 @@
2099 _active_app_changed_signal.Connect(_matcher, "active-application-changed",
2100 sigc::mem_fun(this, &PanelMenuView::OnActiveAppChanged));
2101
2102- _padding = padding;
2103-
2104 _window_buttons = new WindowButtons();
2105+ _window_buttons->SetMonitor(_monitor);
2106+ _window_buttons->SetControlledWindow(_active_xid);
2107 _window_buttons->SetParentObject(this);
2108- _window_buttons->NeedRedraw();
2109+ _window_buttons->SetLeftAndRightPadding(MAIN_LEFT_PADDING, MENUBAR_PADDING);
2110+ _window_buttons->SetMaximumHeight(panel::Style::Instance().panel_height);
2111+ _window_buttons->ComputeContentSize();
2112
2113- _window_buttons->close_clicked.connect(sigc::mem_fun(this, &PanelMenuView::OnCloseClicked));
2114- _window_buttons->minimize_clicked.connect(sigc::mem_fun(this, &PanelMenuView::OnMinimizeClicked));
2115- _window_buttons->restore_clicked.connect(sigc::mem_fun(this, &PanelMenuView::OnRestoreClicked));
2116 _window_buttons->mouse_enter.connect(sigc::mem_fun(this, &PanelMenuView::OnPanelViewMouseEnter));
2117 _window_buttons->mouse_leave.connect(sigc::mem_fun(this, &PanelMenuView::OnPanelViewMouseLeave));
2118 //_window_buttons->mouse_move.connect(sigc::mem_fun(this, &PanelMenuView::OnPanelViewMouseMove));
2119-
2120- _panel_titlebar_grab_area = new PanelTitlebarGrabArea();
2121- _panel_titlebar_grab_area->SetParentObject(this);
2122- _panel_titlebar_grab_area->mouse_down.connect(sigc::mem_fun(this, &PanelMenuView::OnMouseClicked));
2123- _panel_titlebar_grab_area->mouse_down.connect(sigc::mem_fun(this, &PanelMenuView::OnMouseMiddleClicked));
2124- _panel_titlebar_grab_area->mouse_down.connect(sigc::mem_fun(this, &PanelMenuView::OnMaximizedGrabStart));
2125- _panel_titlebar_grab_area->mouse_drag.connect(sigc::mem_fun(this, &PanelMenuView::OnMaximizedGrabMove));
2126- _panel_titlebar_grab_area->mouse_up.connect(sigc::mem_fun(this, &PanelMenuView::OnMaximizedGrabEnd));
2127- _panel_titlebar_grab_area->mouse_double_click.connect(sigc::mem_fun(this, &PanelMenuView::OnMouseDoubleClicked));
2128-
2129- win_manager = WindowManager::Default();
2130-
2131+ AddChild(_window_buttons);
2132+
2133+ layout_->SetLeftAndRightPadding(_window_buttons->GetContentWidth(), 0);
2134+ layout_->SetBaseHeight(panel::Style::Instance().panel_height);
2135+
2136+ _titlebar_grab_area = new PanelTitlebarGrabArea();
2137+ _titlebar_grab_area->SetParentObject(this);
2138+ _titlebar_grab_area->activate_request.connect(sigc::mem_fun(this, &PanelMenuView::OnMaximizedActivate));
2139+ _titlebar_grab_area->restore_request.connect(sigc::mem_fun(this, &PanelMenuView::OnMaximizedRestore));
2140+ _titlebar_grab_area->lower_request.connect(sigc::mem_fun(this, &PanelMenuView::OnMaximizedLower));
2141+ _titlebar_grab_area->grab_started.connect(sigc::mem_fun(this, &PanelMenuView::OnMaximizedGrabStart));
2142+ _titlebar_grab_area->grab_move.connect(sigc::mem_fun(this, &PanelMenuView::OnMaximizedGrabMove));
2143+ _titlebar_grab_area->grab_end.connect(sigc::mem_fun(this, &PanelMenuView::OnMaximizedGrabEnd));
2144+ AddChild(_titlebar_grab_area);
2145+
2146+ WindowManager* win_manager = WindowManager::Default();
2147 win_manager->window_minimized.connect(sigc::mem_fun(this, &PanelMenuView::OnWindowMinimized));
2148 win_manager->window_unminimized.connect(sigc::mem_fun(this, &PanelMenuView::OnWindowUnminimized));
2149- //win_manager->initiate_spread.connect(sigc::mem_fun(this, &PanelMenuView::OnSpreadInitiate));
2150- //win_manager->terminate_spread.connect(sigc::mem_fun(this, &PanelMenuView::OnSpreadTerminate));
2151-
2152 win_manager->window_maximized.connect(sigc::mem_fun(this, &PanelMenuView::OnWindowMaximized));
2153 win_manager->window_restored.connect(sigc::mem_fun(this, &PanelMenuView::OnWindowRestored));
2154 win_manager->window_unmapped.connect(sigc::mem_fun(this, &PanelMenuView::OnWindowUnmapped));
2155@@ -146,39 +130,40 @@
2156 win_manager->window_resized.connect(sigc::mem_fun(this, &PanelMenuView::OnWindowMoved));
2157 win_manager->window_decorated.connect(sigc::mem_fun(this, &PanelMenuView::OnWindowDecorated));
2158 win_manager->window_undecorated.connect(sigc::mem_fun(this, &PanelMenuView::OnWindowUndecorated));
2159-
2160- panel::Style::Instance().changed.connect(sigc::mem_fun(this, &PanelMenuView::Refresh));
2161+ win_manager->initiate_spread.connect(sigc::mem_fun(this, &PanelMenuView::OnSpreadInitiate));
2162+ win_manager->terminate_spread.connect(sigc::mem_fun(this, &PanelMenuView::OnSpreadTerminate));
2163+ win_manager->initiate_expo.connect(sigc::mem_fun(this, &PanelMenuView::OnExpoInitiate));
2164+ win_manager->terminate_expo.connect(sigc::mem_fun(this, &PanelMenuView::OnExpoTerminate));
2165+ win_manager->compiz_screen_viewport_switch_ended.connect(sigc::mem_fun(this, &PanelMenuView::OnExpoTerminate));
2166+
2167+ _style_changed_connection = panel::Style::Instance().changed.connect([&] {
2168+ _window_buttons->ComputeContentSize();
2169+ layout_->SetLeftAndRightPadding(_window_buttons->GetContentWidth(), 0);
2170+
2171+ Refresh(true);
2172+ FullRedraw();
2173+ });
2174
2175 mouse_enter.connect(sigc::mem_fun(this, &PanelMenuView::OnPanelViewMouseEnter));
2176 mouse_leave.connect(sigc::mem_fun(this, &PanelMenuView::OnPanelViewMouseLeave));
2177 //mouse_move.connect(sigc::mem_fun(this, &PanelMenuView::OnPanelViewMouseMove));
2178
2179- _panel_titlebar_grab_area->mouse_enter.connect(sigc::mem_fun(this, &PanelMenuView::OnPanelViewMouseEnter));
2180- _panel_titlebar_grab_area->mouse_leave.connect(sigc::mem_fun(this, &PanelMenuView::OnPanelViewMouseLeave));
2181-
2182- // Register for all the interesting events
2183- UBusServer* ubus = ubus_server_get_default();
2184- _ubus_interests.push_back(ubus_server_register_interest(ubus, UBUS_OVERLAY_SHOWN,
2185- (UBusCallback)PanelMenuView::OnPlaceViewShown,
2186- this));
2187- _ubus_interests.push_back(ubus_server_register_interest(ubus, UBUS_OVERLAY_HIDDEN,
2188- (UBusCallback)PanelMenuView::OnPlaceViewHidden,
2189- this));
2190-
2191- _ubus_interests.push_back(ubus_server_register_interest(ubus, UBUS_SWITCHER_SHOWN,
2192- (UBusCallback)PanelMenuView::OnSwitcherShown,
2193- this));
2194- _ubus_interests.push_back(ubus_server_register_interest(ubus, UBUS_SWITCHER_SELECTION_CHANGED,
2195- (UBusCallback)PanelMenuView::OnSwitcherSelectionChanged,
2196- this));
2197-
2198- _fade_in_animator = new Animator(_menus_fadein);
2199- _fade_out_animator = new Animator(_menus_fadeout);
2200-
2201- _fade_in_animator->animation_updated.connect(sigc::mem_fun(this, &PanelMenuView::OnFadeInChanged));
2202- _fade_in_animator->animation_ended.connect(sigc::mem_fun(this, &PanelMenuView::FullRedraw));
2203- _fade_out_animator->animation_updated.connect(sigc::mem_fun(this, &PanelMenuView::OnFadeOutChanged));
2204- _fade_out_animator->animation_ended.connect(sigc::mem_fun(this, &PanelMenuView::FullRedraw));
2205+ _titlebar_grab_area->mouse_enter.connect(sigc::mem_fun(this, &PanelMenuView::OnPanelViewMouseEnter));
2206+ _titlebar_grab_area->mouse_leave.connect(sigc::mem_fun(this, &PanelMenuView::OnPanelViewMouseLeave));
2207+
2208+ _ubus_manager.RegisterInterest(UBUS_SWITCHER_SHOWN, sigc::mem_fun(this, &PanelMenuView::OnSwitcherShown));
2209+ _ubus_manager.RegisterInterest(UBUS_SWITCHER_SELECTION_CHANGED, sigc::mem_fun(this, &PanelMenuView::OnSwitcherSelectionChanged));
2210+
2211+ _ubus_manager.RegisterInterest(UBUS_LAUNCHER_START_KEY_NAV, sigc::mem_fun(this, &PanelMenuView::OnLauncherKeyNavStarted));
2212+ _ubus_manager.RegisterInterest(UBUS_LAUNCHER_END_KEY_NAV, sigc::mem_fun(this, &PanelMenuView::OnLauncherKeyNavEnded));
2213+ _ubus_manager.RegisterInterest(UBUS_LAUNCHER_START_KEY_SWTICHER, sigc::mem_fun(this, &PanelMenuView::OnLauncherKeyNavStarted));
2214+ _ubus_manager.RegisterInterest(UBUS_LAUNCHER_END_KEY_SWTICHER, sigc::mem_fun(this, &PanelMenuView::OnLauncherKeyNavEnded));
2215+ _ubus_manager.RegisterInterest(UBUS_LAUNCHER_SELECTION_CHANGED, sigc::mem_fun(this, &PanelMenuView::OnLauncherSelectionChanged));
2216+
2217+ _fade_in_animator.animation_updated.connect(sigc::mem_fun(this, &PanelMenuView::OnFadeInChanged));
2218+ _fade_in_animator.animation_ended.connect(sigc::mem_fun(this, &PanelMenuView::FullRedraw));
2219+ _fade_out_animator.animation_updated.connect(sigc::mem_fun(this, &PanelMenuView::OnFadeOutChanged));
2220+ _fade_out_animator.animation_ended.connect(sigc::mem_fun(this, &PanelMenuView::FullRedraw));
2221
2222 SetOpacity(0.0f);
2223 _window_buttons->SetOpacity(0.0f);
2224@@ -198,41 +183,48 @@
2225 if (_new_app_hide_id)
2226 g_source_remove(_new_app_hide_id);
2227
2228- if (_title_layer)
2229- delete _title_layer;
2230-
2231- if (_fade_in_animator)
2232- delete _fade_in_animator;
2233-
2234- if (_fade_out_animator)
2235- delete _fade_out_animator;
2236-
2237- _menu_layout->UnReference();
2238 _window_buttons->UnReference();
2239- _panel_titlebar_grab_area->UnReference();
2240-
2241- UBusServer* ubus = ubus_server_get_default();
2242- for (auto interest : _ubus_interests)
2243+ _titlebar_grab_area->UnReference();
2244+
2245+ _style_changed_connection.disconnect();
2246+}
2247+
2248+void PanelMenuView::OverlayShown()
2249+{
2250+ _overlay_showing = true;
2251+ QueueDraw();
2252+}
2253+
2254+void PanelMenuView::OverlayHidden()
2255+{
2256+ _overlay_showing = false;
2257+ QueueDraw();
2258+}
2259+
2260+void PanelMenuView::AddIndicator(indicator::Indicator::Ptr const& indicator)
2261+{
2262+ if (!GetIndicators().empty())
2263 {
2264- if (interest != 0)
2265- ubus_server_unregister_interest(ubus, interest);
2266+ LOG_ERROR(logger) << "PanelMenuView has already an indicator!";
2267+ return;
2268 }
2269+
2270+ PanelIndicatorsView::AddIndicator(indicator);
2271 }
2272
2273-void
2274-PanelMenuView::SetMenuShowTimings(int fadein, int fadeout, int discovery,
2275- int discovery_fadein, int discovery_fadeout)
2276+void PanelMenuView::SetMenuShowTimings(int fadein, int fadeout, int discovery,
2277+ int discovery_fadein, int discovery_fadeout)
2278 {
2279 if (fadein > -1)
2280 {
2281 _menus_fadein = fadein;
2282- _fade_in_animator->SetDuration(_menus_fadein);
2283+ _fade_in_animator.SetDuration(_menus_fadein);
2284 }
2285
2286 if (fadeout > -1)
2287 {
2288 _menus_fadeout = fadeout;
2289- _fade_out_animator->SetDuration(_menus_fadeout);
2290+ _fade_out_animator.SetDuration(_menus_fadeout);
2291 }
2292
2293 if (discovery > -1)
2294@@ -245,16 +237,13 @@
2295 _menus_discovery_fadeout = discovery_fadeout;
2296 }
2297
2298-void
2299-PanelMenuView::FullRedraw()
2300+void PanelMenuView::FullRedraw()
2301 {
2302- _menu_layout->NeedRedraw();
2303- _window_buttons->NeedRedraw();
2304- NeedRedraw();
2305+ QueueDraw();
2306+ _window_buttons->QueueDraw();
2307 }
2308
2309-nux::Area*
2310-PanelMenuView::FindAreaUnderMouse(const nux::Point& mouse_position, nux::NuxEventType event_type)
2311+nux::Area* PanelMenuView::FindAreaUnderMouse(const nux::Point& mouse_position, nux::NuxEventType event_type)
2312 {
2313 bool mouse_inside = TestMousePointerInclusionFilterMouseWheel(mouse_position, event_type);
2314
2315@@ -262,80 +251,59 @@
2316 return nullptr;
2317
2318 Area* found_area = nullptr;
2319+
2320+ if (_overlay_showing)
2321+ {
2322+ if (_window_buttons)
2323+ return _window_buttons->FindAreaUnderMouse(mouse_position, event_type);
2324+ }
2325+
2326 if (!_we_control_active)
2327 {
2328- found_area = _panel_titlebar_grab_area->FindAreaUnderMouse(mouse_position, event_type);
2329- NUX_RETURN_VALUE_IF_NOTNULL(found_area, found_area);
2330+ /* When the current panel is not active, it all behaves like a grab-area */
2331+ if (GetAbsoluteGeometry().IsInside(mouse_position))
2332+ return _titlebar_grab_area;
2333 }
2334
2335- if (_is_maximized || _places_showing)
2336+ if (_is_maximized)
2337 {
2338 if (_window_buttons)
2339 {
2340 found_area = _window_buttons->FindAreaUnderMouse(mouse_position, event_type);
2341 NUX_RETURN_VALUE_IF_NOTNULL(found_area, found_area);
2342 }
2343-
2344- if (_panel_titlebar_grab_area)
2345- {
2346- found_area = _panel_titlebar_grab_area->FindAreaUnderMouse(mouse_position, event_type);
2347- NUX_RETURN_VALUE_IF_NOTNULL(found_area, found_area);
2348- }
2349- }
2350-
2351- if (_panel_titlebar_grab_area)
2352- {
2353- found_area = _panel_titlebar_grab_area->FindAreaUnderMouse(mouse_position, event_type);
2354- NUX_RETURN_VALUE_IF_NOTNULL(found_area, found_area);
2355- }
2356-
2357- if (!_is_own_window)
2358- {
2359- found_area = _menu_layout->FindAreaUnderMouse(mouse_position, event_type);
2360- NUX_RETURN_VALUE_IF_NOTNULL(found_area, found_area);
2361- }
2362-
2363- return View::FindAreaUnderMouse(mouse_position, event_type);
2364+ }
2365+
2366+ if (_titlebar_grab_area && !_overlay_showing)
2367+ {
2368+ found_area = _titlebar_grab_area->FindAreaUnderMouse(mouse_position, event_type);
2369+ NUX_RETURN_VALUE_IF_NOTNULL(found_area, found_area);
2370+ }
2371+
2372+ return PanelIndicatorsView::FindAreaUnderMouse(mouse_position, event_type);
2373 }
2374
2375-long PanelMenuView::PostLayoutManagement(long LayoutResult)
2376+void PanelMenuView::PreLayoutManagement()
2377 {
2378- long res = View::PostLayoutManagement(LayoutResult);
2379- int old_window_buttons_w, new_window_buttons_w;
2380- int old_menu_area_w, new_menu_area_w;
2381-
2382- nux::Geometry geo = GetGeometry();
2383-
2384- int h_padding = _padding - 2;
2385- int v_padding = 1;
2386-
2387- old_window_buttons_w = _window_buttons->GetContentWidth();
2388- _window_buttons->SetGeometry(geo.x + h_padding, geo.y + v_padding, old_window_buttons_w, geo.height);
2389+ PanelIndicatorsView::PreLayoutManagement();
2390+ nux::Geometry const& geo = GetGeometry();
2391+
2392 _window_buttons->ComputeContentSize();
2393- new_window_buttons_w = _window_buttons->GetContentWidth();
2394-
2395- /* Explicitly set the size and position of the widgets */
2396- geo.x += h_padding + new_window_buttons_w + h_padding;
2397- geo.width -= h_padding + new_window_buttons_w + h_padding;
2398-
2399- old_menu_area_w = _menu_layout->GetContentWidth();
2400- _menu_layout->SetGeometry(geo.x, geo.y, old_menu_area_w, geo.height);
2401- _menu_layout->ComputeContentSize();
2402- new_menu_area_w = _menu_layout->GetContentWidth();
2403-
2404- geo.x += new_menu_area_w;
2405- geo.width -= new_menu_area_w;
2406-
2407- _panel_titlebar_grab_area->SetGeometry(geo.x, geo.y, geo.width, geo.height);
2408-
2409- if (_is_inside)
2410- NeedRedraw();
2411-
2412- return res;
2413+ int buttons_diff = geo.height - _window_buttons->GetContentHeight();
2414+ _window_buttons->SetBaseY(buttons_diff > 0 ? std::ceil(buttons_diff/2.0f) : 0);
2415+
2416+ layout_->ComputeContentSize();
2417+ int layout_width = layout_->GetContentWidth();
2418+
2419+ _titlebar_grab_area->SetBaseX(layout_width);
2420+ _titlebar_grab_area->SetBaseHeight(geo.height);
2421+ _titlebar_grab_area->SetMinimumWidth(geo.width - layout_width);
2422+ _titlebar_grab_area->SetMaximumWidth(geo.width - layout_width);
2423+
2424+ SetMaximumEntriesWidth(geo.width - _window_buttons->GetContentWidth());
2425 }
2426
2427-void
2428-PanelMenuView::OnFadeInChanged(double opacity)
2429+void PanelMenuView::OnFadeInChanged(double opacity)
2430 {
2431 if (DrawMenus() && GetOpacity() != 1.0f)
2432 SetOpacity(opacity);
2433@@ -343,11 +311,10 @@
2434 if (DrawWindowButtons() && _window_buttons->GetOpacity() != 1.0f)
2435 _window_buttons->SetOpacity(opacity);
2436
2437- NeedRedraw();
2438+ QueueDraw();
2439 }
2440
2441-void
2442-PanelMenuView::OnFadeOutChanged(double progress)
2443+void PanelMenuView::OnFadeOutChanged(double progress)
2444 {
2445 double opacity = CLAMP(1.0f - progress, 0.0f, 1.0f);
2446
2447@@ -357,13 +324,16 @@
2448 if (!DrawWindowButtons() && _window_buttons->GetOpacity() != 0.0f)
2449 _window_buttons->SetOpacity(opacity);
2450
2451- NeedRedraw();
2452+ QueueDraw();
2453 }
2454
2455-bool
2456-PanelMenuView::DrawMenus()
2457+bool PanelMenuView::DrawMenus() const
2458 {
2459- if (!_is_own_window && !_places_showing && _we_control_active && !_switcher_showing)
2460+ auto wm = WindowManager::Default();
2461+ bool screen_grabbed = (wm->IsExpoActive() || wm->IsScaleActive());
2462+
2463+ if (_we_control_active && !_overlay_showing && !screen_grabbed &&
2464+ !_switcher_showing && !_launcher_keynav)
2465 {
2466 if (_is_inside || _last_active_view || _show_now_activated || _new_application)
2467 {
2468@@ -374,13 +344,16 @@
2469 return false;
2470 }
2471
2472-bool
2473-PanelMenuView::DrawWindowButtons()
2474+bool PanelMenuView::DrawWindowButtons() const
2475 {
2476- if (_places_showing)
2477+ auto wm = WindowManager::Default();
2478+ bool screen_grabbed = (wm->IsExpoActive() || wm->IsScaleActive());
2479+
2480+ if (_overlay_showing)
2481 return true;
2482
2483- if (!_is_own_window && _we_control_active && _is_maximized && !_switcher_showing)
2484+ if (_we_control_active && _is_maximized && !screen_grabbed &&
2485+ !_launcher_keynav && !_switcher_showing)
2486 {
2487 if (_is_inside || _show_now_activated || _new_application)
2488 {
2489@@ -391,19 +364,18 @@
2490 return false;
2491 }
2492
2493-void
2494-PanelMenuView::Draw(nux::GraphicsEngine& GfxContext, bool force_draw)
2495+void PanelMenuView::Draw(nux::GraphicsEngine& GfxContext, bool force_draw)
2496 {
2497- nux::Geometry geo = GetGeometry();
2498- int button_width = _padding + _window_buttons->GetContentWidth() + _padding;
2499- float factor = 4;
2500+ nux::Geometry const& geo = GetGeometry();
2501+ int button_width = _window_buttons->GetContentWidth();
2502+ const float factor = 4;
2503 button_width /= factor;
2504
2505- if (geo.width != _last_width || geo.height != _last_height)
2506+ if (geo != _last_geo)
2507 {
2508- _last_width = geo.width;
2509- _last_height = geo.height;
2510- Refresh();
2511+ _last_geo = geo;
2512+ QueueRelayout();
2513+ Refresh(true);
2514 }
2515
2516 GfxContext.PushClippingRectangle(geo);
2517@@ -417,7 +389,7 @@
2518 nux::ColorLayer layer(nux::Color(0x00000000), true, rop);
2519 nux::GetPainter().PushDrawLayer(GfxContext, GetGeometry(), &layer);
2520
2521- if (_title_layer && !_is_own_window)
2522+ if (_title_texture)
2523 {
2524 guint blend_alpha = 0, blend_src = 0, blend_dest = 0;
2525 bool draw_menus = DrawMenus();
2526@@ -429,7 +401,7 @@
2527
2528 for (auto entry : entries_)
2529 {
2530- if (entry.second->IsEntryValid())
2531+ if (entry.second->IsVisible())
2532 {
2533 has_menu = true;
2534 break;
2535@@ -542,20 +514,22 @@
2536 geo.width, geo.height,
2537 _gradient_texture, texxform0,
2538 nux::color::White,
2539- _title_layer->GetDeviceTexture(),
2540+ _title_texture->GetDeviceTexture(),
2541 texxform1,
2542 nux::color::White);
2543 }
2544- else if (!_places_showing)
2545+ else if (!_overlay_showing)
2546 {
2547+ double title_opacity = 0.0f;
2548+
2549 if (_we_control_active && _window_buttons->GetOpacity() == 0.0 &&
2550 (!has_menu || (has_menu && GetOpacity() == 0.0)))
2551 {
2552- nux::GetPainter().PushDrawLayer(GfxContext, geo, _title_layer);
2553+ title_opacity = 1.0f;
2554 }
2555 else
2556 {
2557- double title_opacity = 1.0f;
2558+ title_opacity = 1.0f;
2559
2560 if (has_menu)
2561 title_opacity -= MAX(GetOpacity(), _window_buttons->GetOpacity());
2562@@ -572,10 +546,13 @@
2563 // If we're fading-in the buttons/menus, let's fade-out quickly the title
2564 title_opacity = CLAMP(title_opacity - 0.2f, 0.0f, 1.0f);
2565 }
2566+ }
2567
2568+ if (title_opacity > 0.0f)
2569+ {
2570 nux::TexCoordXForm texxform;
2571 GfxContext.QRP_1Tex(geo.x, geo.y, geo.width, geo.height,
2572- _title_layer->GetDeviceTexture(), texxform,
2573+ _title_texture->GetDeviceTexture(), texxform,
2574 nux::color::White * title_opacity);
2575 }
2576 }
2577@@ -588,10 +565,9 @@
2578 GfxContext.PopClippingRectangle();
2579 }
2580
2581-void
2582-PanelMenuView::DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw)
2583+void PanelMenuView::DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw)
2584 {
2585- nux::Geometry geo = GetGeometry();
2586+ nux::Geometry const& geo = GetGeometry();
2587 bool draw_menus = DrawMenus();
2588 bool draw_buttons = DrawWindowButtons();
2589
2590@@ -602,17 +578,17 @@
2591 for (auto entry : entries_)
2592 entry.second->SetDisabled(false);
2593
2594- _menu_layout->ProcessDraw(GfxContext, true);
2595+ layout_->ProcessDraw(GfxContext, true);
2596
2597- _fade_out_animator->Stop();
2598+ _fade_out_animator.Stop();
2599
2600 if (_new_application && !_is_inside)
2601 {
2602- _fade_in_animator->Start(_menus_discovery_fadein, GetOpacity());
2603+ _fade_in_animator.Start(_menus_discovery_fadein, GetOpacity());
2604 }
2605 else
2606 {
2607- _fade_in_animator->Start(GetOpacity());
2608+ _fade_in_animator.Start(GetOpacity());
2609 _new_app_menu_shown = false;
2610 }
2611 }
2612@@ -622,19 +598,19 @@
2613 entry.second->SetDisabled(true);
2614 }
2615
2616- if (GetOpacity() != 0.0f && !draw_menus)
2617+ if (GetOpacity() != 0.0f && !draw_menus && !_overlay_showing)
2618 {
2619- _menu_layout->ProcessDraw(GfxContext, true);
2620+ layout_->ProcessDraw(GfxContext, true);
2621
2622- _fade_in_animator->Stop();
2623+ _fade_in_animator.Stop();
2624
2625 if (!_new_app_menu_shown)
2626 {
2627- _fade_out_animator->Start(1.0f - GetOpacity());
2628+ _fade_out_animator.Start(1.0f - GetOpacity());
2629 }
2630 else
2631 {
2632- _fade_out_animator->Start(_menus_discovery_fadeout, 1.0f - GetOpacity());
2633+ _fade_out_animator.Start(_menus_discovery_fadeout, 1.0f - GetOpacity());
2634 }
2635 }
2636
2637@@ -642,299 +618,260 @@
2638 {
2639 _window_buttons->ProcessDraw(GfxContext, true);
2640
2641- _fade_out_animator->Stop();
2642- _fade_in_animator->Start(_window_buttons->GetOpacity());
2643+ if (_window_buttons->GetOpacity() != 1.0f)
2644+ {
2645+ _fade_out_animator.Stop();
2646+ _fade_in_animator.Start(_window_buttons->GetOpacity());
2647+ }
2648 }
2649
2650 if (_window_buttons->GetOpacity() != 0.0f && !draw_buttons)
2651 {
2652 _window_buttons->ProcessDraw(GfxContext, true);
2653- _fade_in_animator->Stop();
2654+ _fade_in_animator.Stop();
2655
2656 /* If we try to hide only the buttons, then use a faster fadeout */
2657- if (!_fade_out_animator->IsRunning())
2658+ if (!_fade_out_animator.IsRunning())
2659 {
2660- _fade_out_animator->Start(_menus_fadeout/3, 1.0f - _window_buttons->GetOpacity());
2661+ _fade_out_animator.Start(_menus_fadeout/3, 1.0f - _window_buttons->GetOpacity());
2662 }
2663 }
2664
2665 GfxContext.PopClippingRectangle();
2666 }
2667
2668-gchar*
2669-PanelMenuView::GetActiveViewName()
2670+std::string PanelMenuView::GetActiveViewName(bool use_appname) const
2671 {
2672- gchar* label = nullptr;
2673- BamfWindow* window;
2674-
2675- _is_own_window = false;
2676+ std::string label;
2677+ BamfWindow* window;
2678
2679 window = bamf_matcher_get_active_window(_matcher);
2680+
2681 if (BAMF_IS_WINDOW(window))
2682 {
2683+ BamfView *view = reinterpret_cast<BamfView*>(window);
2684 std::vector<Window> const& our_xids = nux::XInputWindow::NativeHandleList();
2685- guint32 window_xid = bamf_window_get_xid(BAMF_WINDOW(window));
2686+ Window window_xid = bamf_window_get_xid(window);
2687
2688 if (std::find(our_xids.begin(), our_xids.end(), window_xid) != our_xids.end())
2689 {
2690- _is_own_window = true;
2691- return g_strdup("");
2692- }
2693-
2694- if (BAMF_IS_WINDOW(window) &&
2695- bamf_window_get_window_type(window) == BAMF_WINDOW_DESKTOP)
2696- {
2697- label = g_strdup(_("Ubuntu Desktop"));
2698- }
2699- else if (!WindowManager::Default()->IsWindowOnCurrentDesktop(window_xid) ||
2700- WindowManager::Default()->IsWindowObscured(window_xid))
2701- {
2702- return g_strdup("");
2703- }
2704-
2705- if (_is_maximized)
2706- label = bamf_view_get_name(BAMF_VIEW(window));
2707- }
2708-
2709- if (!label)
2710- {
2711- BamfApplication* app = bamf_matcher_get_active_application(_matcher);
2712- if (BAMF_IS_APPLICATION(app))
2713- {
2714- const gchar* filename;
2715-
2716- filename = bamf_application_get_desktop_file(app);
2717-
2718- if (filename && g_strcmp0(filename, "") != 0)
2719- {
2720- GDesktopAppInfo* info;
2721-
2722- info = g_desktop_app_info_new_from_filename(bamf_application_get_desktop_file(app));
2723-
2724- if (info)
2725- {
2726- label = g_strdup(g_app_info_get_display_name(G_APP_INFO(info)));
2727- g_object_unref(info);
2728- }
2729- else
2730- {
2731- g_warning("Unable to get GDesktopAppInfo for %s",
2732- bamf_application_get_desktop_file(app));
2733- }
2734- }
2735-
2736- if (label == nullptr)
2737- {
2738- BamfView* active_view;
2739-
2740- active_view = (BamfView*)bamf_matcher_get_active_window(_matcher);
2741- if (BAMF_IS_VIEW(active_view))
2742- label = bamf_view_get_name(active_view);
2743- else
2744- label = g_strdup("");
2745- }
2746- }
2747- else
2748- {
2749- label = g_strdup(" ");
2750- }
2751- }
2752-
2753- char *escaped = g_markup_escape_text(label, -1);
2754- g_free(label);
2755- label = g_strdup_printf("<b>%s</b>", escaped);
2756- g_free(escaped);
2757+ /* If the active window is an unity window, we need to fallback to the
2758+ * top one, anyway we should always avoid to focus unity internal windows */
2759+ BamfWindow* top_win = GetBamfWindowForXid(GetTopWindow());
2760+
2761+ if (top_win && top_win != window)
2762+ {
2763+ window = top_win;
2764+ }
2765+ else
2766+ {
2767+ return "";
2768+ }
2769+ }
2770+
2771+ if (bamf_window_get_window_type(window) == BAMF_WINDOW_DESKTOP)
2772+ {
2773+ label = DESKTOP_NAME;
2774+ }
2775+ else if (!IsValidWindow(window_xid))
2776+ {
2777+ return "";
2778+ }
2779+
2780+ if (WindowManager::Default()->IsWindowMaximized(window_xid) && !use_appname)
2781+ {
2782+ label = glib::String(bamf_view_get_name(view)).Str();
2783+ }
2784+
2785+ if (label.empty())
2786+ {
2787+ BamfApplication* app;
2788+ app = bamf_matcher_get_application_for_window(_matcher, window);
2789+
2790+ if (BAMF_IS_APPLICATION(app))
2791+ {
2792+ view = reinterpret_cast<BamfView*>(app);
2793+ label = glib::String(bamf_view_get_name(view)).Str();
2794+ }
2795+ }
2796+
2797+ if (label.empty())
2798+ {
2799+ view = reinterpret_cast<BamfView*>(window);
2800+ label = glib::String(bamf_view_get_name(view)).Str();
2801+ }
2802+ }
2803
2804 return label;
2805 }
2806
2807-void PanelMenuView::DrawText(cairo_t *cr_real,
2808- int &x, int y, int width, int height,
2809- const char* font_desc,
2810- const char* label,
2811- int increase_size
2812- )
2813+void PanelMenuView::DrawTitle(cairo_t *cr_real, nux::Geometry const& geo, std::string const& label) const
2814 {
2815- PangoLayout* layout = nullptr;
2816- PangoFontDescription* desc = nullptr;
2817- GtkSettings* settings = gtk_settings_get_default();
2818- cairo_t* cr;
2819- cairo_pattern_t* linpat;
2820- GdkScreen* screen = gdk_screen_get_default();
2821- int dpi = 0;
2822- const int fading_pixels = 35;
2823- char *font_description = g_strdup(font_desc);
2824-
2825- int text_width = 0;
2826- int text_height = 0;
2827- int text_space = 0;
2828-
2829- { // Find out dimensions first
2830- GConfClient* client = gconf_client_get_default();
2831- PangoContext* cxt;
2832- PangoRectangle log_rect;
2833-
2834- cr = _util_cg.GetContext();
2835-
2836- g_object_get(settings, "gtk-xft-dpi", &dpi, nullptr);
2837-
2838- font_description = gconf_client_get_string(client, WINDOW_TITLE_FONT_KEY.c_str(), nullptr);
2839- desc = pango_font_description_from_string(font_description);
2840-
2841- if (font_desc)
2842- {
2843- int size = pango_font_description_get_size(desc);
2844- size /= pango_font_description_get_size_is_absolute(desc) ? 1 : PANGO_SCALE;
2845-
2846- // Adjust y depending on size of the font
2847- y -= ((unsigned int)(size - 9)) / 2;
2848-
2849- size += increase_size;
2850-
2851- char* description = g_strdup_printf("%s %d", font_desc, size);
2852- pango_font_description_free(desc);
2853- desc = pango_font_description_from_string(description);
2854- g_free(description);
2855- }
2856-
2857- layout = pango_cairo_create_layout(cr);
2858- pango_layout_set_font_description(layout, desc);
2859- pango_layout_set_markup(layout, label, -1);
2860-
2861- cxt = pango_layout_get_context(layout);
2862- pango_cairo_context_set_font_options(cxt, gdk_screen_get_font_options(screen));
2863- pango_cairo_context_set_resolution(cxt, (float)dpi / (float)PANGO_SCALE);
2864- pango_layout_context_changed(layout);
2865-
2866- pango_layout_get_extents(layout, nullptr, &log_rect);
2867- text_width = log_rect.width / PANGO_SCALE;
2868- text_height = log_rect.height / PANGO_SCALE;
2869-
2870- pango_font_description_free(desc);
2871- g_free(font_description);
2872- cairo_destroy(cr);
2873- g_object_unref(client);
2874- }
2875-
2876- { // Draw the text
2877- GtkStyleContext* style_context = panel::Style::Instance().GetStyleContext();
2878- text_space = width - x;
2879- cr = cr_real;
2880-
2881- gtk_style_context_save(style_context);
2882-
2883- GtkWidgetPath* widget_path = gtk_widget_path_new();
2884- gint pos = gtk_widget_path_append_type(widget_path, GTK_TYPE_WINDOW);
2885- gtk_widget_path_iter_set_name(widget_path, pos, "UnityPanelWidget");
2886- gtk_widget_path_append_type(widget_path, GTK_TYPE_MENU_BAR);
2887- gtk_widget_path_append_type(widget_path, GTK_TYPE_MENU_ITEM);
2888-
2889- gtk_style_context_set_path(style_context, widget_path);
2890- gtk_style_context_add_class(style_context, GTK_STYLE_CLASS_MENUBAR);
2891- gtk_style_context_add_class(style_context, GTK_STYLE_CLASS_MENUITEM);
2892-
2893- y += (height - text_height) / 2;
2894-
2895- pango_cairo_update_layout(cr, layout);
2896-
2897- if (text_width > text_space)
2898- {
2899- int out_pixels = text_width - text_space;
2900- int fading_width = out_pixels < fading_pixels ? out_pixels : fading_pixels;
2901-
2902- cairo_push_group(cr);
2903- gtk_render_layout(style_context, cr, x, y, layout);
2904- cairo_pop_group_to_source(cr);
2905-
2906- linpat = cairo_pattern_create_linear(width - fading_width, y, width, y);
2907- cairo_pattern_add_color_stop_rgba(linpat, 0, 0, 0, 0, 1);
2908- cairo_pattern_add_color_stop_rgba(linpat, 1, 0, 0, 0, 0);
2909- cairo_mask(cr, linpat);
2910-
2911- cairo_pattern_destroy(linpat);
2912- }
2913- else
2914- {
2915- gtk_render_layout(style_context, cr, x, y, layout);
2916- }
2917-
2918- x += text_width;
2919-
2920- gtk_widget_path_free(widget_path);
2921- gtk_style_context_restore(style_context);
2922- }
2923-
2924- if (layout)
2925- g_object_unref(layout);
2926+ using namespace panel;
2927+ cairo_t* cr;
2928+ cairo_pattern_t* linpat;
2929+ const int fading_pixels = 35;
2930+ int x = MAIN_LEFT_PADDING + TITLE_PADDING + geo.x;
2931+ int y = geo.y;
2932+
2933+ int text_width = 0;
2934+ int text_height = 0;
2935+ int text_space = 0;
2936+
2937+ // Find out dimensions first
2938+ GdkScreen* screen = gdk_screen_get_default();
2939+ PangoContext* cxt;
2940+ PangoRectangle log_rect;
2941+ PangoFontDescription* desc;
2942+
2943+ nux::CairoGraphics util_cg(CAIRO_FORMAT_ARGB32, 1, 1);
2944+ cr = util_cg.GetContext();
2945+
2946+ int dpi = Style::Instance().GetTextDPI();
2947+
2948+ std::string font_description(Style::Instance().GetFontDescription(PanelItem::TITLE));
2949+ desc = pango_font_description_from_string(font_description.c_str());
2950+
2951+ glib::Object<PangoLayout> layout(pango_cairo_create_layout(cr));
2952+ pango_layout_set_font_description(layout, desc);
2953+ pango_layout_set_markup(layout, label.c_str(), -1);
2954+
2955+ cxt = pango_layout_get_context(layout);
2956+ pango_cairo_context_set_font_options(cxt, gdk_screen_get_font_options(screen));
2957+ pango_cairo_context_set_resolution(cxt, dpi / static_cast<float>(PANGO_SCALE));
2958+ pango_layout_context_changed(layout);
2959+
2960+ pango_layout_get_extents(layout, nullptr, &log_rect);
2961+ text_width = log_rect.width / PANGO_SCALE;
2962+ text_height = log_rect.height / PANGO_SCALE;
2963+
2964+ pango_font_description_free(desc);
2965+ cairo_destroy(cr);
2966+
2967+ // Draw the text
2968+ GtkStyleContext* style_context = Style::Instance().GetStyleContext();
2969+ text_space = geo.width - x;
2970+ cr = cr_real;
2971+ cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
2972+
2973+ gtk_style_context_save(style_context);
2974+
2975+ GtkWidgetPath* widget_path = gtk_widget_path_new();
2976+ gtk_widget_path_append_type(widget_path, GTK_TYPE_MENU_BAR);
2977+ gtk_widget_path_append_type(widget_path, GTK_TYPE_MENU_ITEM);
2978+ gtk_widget_path_iter_set_name(widget_path, -1 , "UnityPanelWidget");
2979+
2980+ gtk_style_context_set_path(style_context, widget_path);
2981+ gtk_style_context_add_class(style_context, GTK_STYLE_CLASS_MENUBAR);
2982+ gtk_style_context_add_class(style_context, GTK_STYLE_CLASS_MENUITEM);
2983+
2984+ y += (geo.height - text_height) / 2;
2985+
2986+ pango_cairo_update_layout(cr, layout);
2987+
2988+ if (text_width > text_space)
2989+ {
2990+ int out_pixels = text_width - text_space;
2991+ int fading_width = out_pixels < fading_pixels ? out_pixels : fading_pixels;
2992+
2993+ cairo_push_group(cr);
2994+ gtk_render_layout(style_context, cr, x, y, layout);
2995+ cairo_pop_group_to_source(cr);
2996+
2997+ linpat = cairo_pattern_create_linear(geo.width - fading_width, y, geo.width, y);
2998+ cairo_pattern_add_color_stop_rgba(linpat, 0, 0, 0, 0, 1);
2999+ cairo_pattern_add_color_stop_rgba(linpat, 1, 0, 0, 0, 0);
3000+ cairo_mask(cr, linpat);
3001+
3002+ cairo_pattern_destroy(linpat);
3003+ }
3004+ else
3005+ {
3006+ gtk_render_layout(style_context, cr, x, y, layout);
3007+ }
3008+
3009+ x += text_width;
3010+
3011+ gtk_widget_path_free(widget_path);
3012+ gtk_style_context_restore(style_context);
3013 }
3014
3015-void
3016-PanelMenuView::Refresh()
3017+void PanelMenuView::Refresh(bool force)
3018 {
3019- nux::Geometry geo = GetGeometry();
3020+ nux::Geometry const& geo = GetGeometry();
3021
3022 // We can get into a race that causes the geometry to be wrong as there hasn't been a
3023 // layout cycle before the first callback. This is to protect from that.
3024 if (geo.width > _monitor_geo.width)
3025 return;
3026
3027- int x = 0;
3028- int y = 0;
3029- int width = geo.width;
3030- int height = geo.height;
3031-
3032- nux::CairoGraphics cairo_graphics(CAIRO_FORMAT_ARGB32, width, height);
3033+ auto win_manager = WindowManager::Default();
3034+ std::string new_title;
3035+
3036+ if (win_manager->IsScaleActive())
3037+ {
3038+ if (win_manager->IsScaleActiveForGroup())
3039+ new_title = GetActiveViewName(true);
3040+ else if (_we_control_active)
3041+ new_title = DESKTOP_NAME;
3042+ }
3043+ else if (win_manager->IsExpoActive())
3044+ {
3045+ new_title = DESKTOP_NAME;
3046+ }
3047+ else if (!_we_control_active)
3048+ {
3049+ new_title = "";
3050+ }
3051+ else if (!_switcher_showing && !_launcher_keynav)
3052+ {
3053+ new_title = GetActiveViewName();
3054+ _window_buttons->SetControlledWindow(_active_xid);
3055+ }
3056+
3057+ if (!_switcher_showing && !_launcher_keynav)
3058+ {
3059+ if (_panel_title != new_title)
3060+ {
3061+ _panel_title = new_title;
3062+ }
3063+ else if (!force && _last_geo == geo && _title_texture)
3064+ {
3065+ // No need to redraw the title, let's save some CPU time!
3066+ return;
3067+ }
3068+ }
3069+
3070+ if (_panel_title.empty())
3071+ {
3072+ _title_texture = nullptr;
3073+ return;
3074+ }
3075+
3076+ nux::CairoGraphics cairo_graphics(CAIRO_FORMAT_ARGB32, geo.width, geo.height);
3077 cairo_t* cr = cairo_graphics.GetContext();
3078- cairo_set_line_width(cr, 1);
3079
3080 cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);
3081 cairo_paint(cr);
3082
3083- cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
3084-
3085- x = _padding;
3086- y = 0;
3087-
3088- if (_panel_title)
3089- {
3090- DrawText(cr, x, y, width, height, nullptr, _panel_title);
3091- }
3092- else
3093- {
3094- char* title = GetActiveViewName();
3095- DrawText(cr, x, y, width, height, nullptr, title);
3096- g_free(title);
3097- }
3098+ glib::String escaped(g_markup_escape_text(_panel_title.c_str(), -1));
3099+
3100+ std::ostringstream bold_label;
3101+ bold_label << "<b>" << escaped.Str() << "</b>";
3102+
3103+ DrawTitle(cr, geo, bold_label.str());
3104
3105 cairo_destroy(cr);
3106
3107- nux::BaseTexture* texture2D = texture_from_cairo_graphics(cairo_graphics);
3108-
3109- if (_title_layer)
3110- delete _title_layer;
3111-
3112- nux::TexCoordXForm texxform;
3113- texxform.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD);
3114- texxform.SetWrap(nux::TEXWRAP_REPEAT, nux::TEXWRAP_REPEAT);
3115-
3116- nux::ROPConfig rop;
3117- rop.Blend = true;
3118- rop.SrcBlend = GL_ONE;
3119- rop.DstBlend = GL_ONE_MINUS_SRC_ALPHA;
3120- _title_layer = new nux::TextureLayer(texture2D->GetDeviceTexture(),
3121- texxform,
3122- nux::color::White,
3123- true,
3124- rop);
3125- texture2D->UnReference();
3126+ _title_texture = texture_ptr_from_cairo_graphics(cairo_graphics);
3127 }
3128
3129-void
3130-PanelMenuView::OnActiveChanged(PanelIndicatorEntryView* view,
3131- bool is_active)
3132+void PanelMenuView::OnActiveChanged(PanelIndicatorEntryView* view, bool is_active)
3133 {
3134 if (is_active)
3135+ {
3136 _last_active_view = view;
3137+ }
3138 else
3139 {
3140 if (_last_active_view == view)
3141@@ -947,37 +884,36 @@
3142 FullRedraw();
3143 }
3144
3145-void
3146-PanelMenuView::OnEntryAdded(unity::indicator::Entry::Ptr const& entry)
3147+void PanelMenuView::OnEntryAdded(indicator::Entry::Ptr const& entry)
3148 {
3149- auto view = AddEntry(entry, 6, IndicatorEntryPosition::END, IndicatorEntryType::MENU);
3150+ PanelIndicatorEntryView* view;
3151+
3152+ view = new PanelIndicatorEntryView(entry, MENU_ENTRIES_PADDING, IndicatorEntryType::MENU);
3153+ view->mouse_enter.connect(sigc::mem_fun(this, &PanelMenuView::OnPanelViewMouseEnter));
3154+ view->mouse_leave.connect(sigc::mem_fun(this, &PanelMenuView::OnPanelViewMouseLeave));
3155
3156 entry->show_now_changed.connect(sigc::mem_fun(this, &PanelMenuView::UpdateShowNow));
3157-
3158 view->active_changed.connect(sigc::mem_fun(this, &PanelMenuView::OnActiveChanged));
3159- view->mouse_enter.connect(sigc::mem_fun(this, &PanelMenuView::OnPanelViewMouseEnter));
3160- view->mouse_leave.connect(sigc::mem_fun(this, &PanelMenuView::OnPanelViewMouseLeave));
3161+
3162+ AddEntryView(view, IndicatorEntryPosition::END);
3163 }
3164
3165-void
3166-PanelMenuView::AllMenusClosed()
3167+void PanelMenuView::NotifyAllMenusClosed()
3168 {
3169- auto mouse = nux::GetGraphicsDisplay()->GetMouseScreenCoord();
3170- _is_inside = GetAbsoluteGeometry().IsPointInside(mouse.x, mouse.y);
3171 _last_active_view = nullptr;
3172
3173+ auto mouse = nux::GetGraphicsDisplay()->GetMouseScreenCoord();
3174+ _is_inside = GetAbsoluteGeometry().IsInside(mouse);
3175 FullRedraw();
3176 }
3177
3178-void
3179-PanelMenuView::OnNameChanged(BamfView* bamf_view, gchar* new_name, gchar* old_name)
3180+void PanelMenuView::OnNameChanged(BamfView* bamf_view, gchar* new_name, gchar* old_name)
3181 {
3182 Refresh();
3183 FullRedraw();
3184 }
3185
3186-gboolean
3187-PanelMenuView::OnNewAppShow(PanelMenuView* self)
3188+gboolean PanelMenuView::OnNewAppShow(PanelMenuView* self)
3189 {
3190 BamfApplication* active_app = bamf_matcher_get_active_application(self->_matcher);
3191 self->_new_application = glib::Object<BamfApplication>(active_app, glib::AddRef());
3192@@ -998,10 +934,9 @@
3193 return FALSE;
3194 }
3195
3196-gboolean
3197-PanelMenuView::OnNewAppHide(PanelMenuView* self)
3198+gboolean PanelMenuView::OnNewAppHide(PanelMenuView* self)
3199 {
3200- self->OnViewClosed(self->_matcher, BAMF_VIEW(self->_new_application.RawPtr()));
3201+ self->OnApplicationClosed(self->_new_application);
3202 self->_new_app_hide_id = 0;
3203 self->_new_app_menu_shown = true;
3204 self->QueueDraw();
3205@@ -1009,8 +944,7 @@
3206 return FALSE;
3207 }
3208
3209-void
3210-PanelMenuView::OnViewOpened(BamfMatcher *matcher, BamfView *view)
3211+void PanelMenuView::OnViewOpened(BamfMatcher *matcher, BamfView *view)
3212 {
3213 /* FIXME: here we should also check for if the view is also user_visible
3214 * but it seems that BAMF doesn't handle this correctly after some
3215@@ -1021,27 +955,48 @@
3216 _new_apps.push_front(glib::Object<BamfApplication>(BAMF_APPLICATION(view), glib::AddRef()));
3217 }
3218
3219-void
3220-PanelMenuView::OnViewClosed(BamfMatcher *matcher, BamfView *view)
3221+void PanelMenuView::OnApplicationClosed(BamfApplication* app)
3222 {
3223- if (!BAMF_IS_APPLICATION(view))
3224- return;
3225-
3226- BamfApplication* app = BAMF_APPLICATION(view);
3227-
3228- if (std::find(_new_apps.begin(), _new_apps.end(), app) != _new_apps.end())
3229+ if (BAMF_IS_APPLICATION(app))
3230 {
3231- _new_apps.remove(glib::Object<BamfApplication>(app, glib::AddRef()));
3232-
3233- if (_new_application == app || _new_apps.empty())
3234+ if (std::find(_new_apps.begin(), _new_apps.end(), app) != _new_apps.end())
3235+ {
3236+ _new_apps.remove(glib::Object<BamfApplication>(app, glib::AddRef()));
3237+ }
3238+ else if (_new_apps.empty())
3239+ {
3240 _new_application = nullptr;
3241- }
3242-}
3243-
3244-void
3245-PanelMenuView::OnActiveAppChanged(BamfMatcher *matcher,
3246- BamfApplication* old_app,
3247- BamfApplication* new_app)
3248+ }
3249+ }
3250+
3251+ if (app == _new_application)
3252+ {
3253+ _new_application = nullptr;
3254+ }
3255+}
3256+
3257+void PanelMenuView::OnViewClosed(BamfMatcher *matcher, BamfView *view)
3258+{
3259+ if (BAMF_IS_APPLICATION(view))
3260+ {
3261+ OnApplicationClosed(reinterpret_cast<BamfApplication*>(view));
3262+ }
3263+ else if (reinterpret_cast<BamfApplication*>(view) == _new_application)
3264+ {
3265+ _new_application = nullptr;
3266+ }
3267+ else if (BAMF_IS_WINDOW(view))
3268+ {
3269+ /* FIXME, this can be removed when window_unmapped WindowManager signal
3270+ * will emit the proper xid */
3271+ Window xid = bamf_window_get_xid(reinterpret_cast<BamfWindow*>(view));
3272+ OnWindowUnmapped(xid);
3273+ }
3274+}
3275+
3276+void PanelMenuView::OnActiveAppChanged(BamfMatcher *matcher,
3277+ BamfApplication* old_app,
3278+ BamfApplication* new_app)
3279 {
3280 if (BAMF_IS_APPLICATION(new_app))
3281 {
3282@@ -1078,15 +1033,14 @@
3283 }
3284
3285 if (_new_application)
3286- OnViewClosed(matcher, BAMF_VIEW(_new_application.RawPtr()));
3287+ OnApplicationClosed(_new_application);
3288 }
3289 }
3290 }
3291
3292-void
3293-PanelMenuView::OnActiveWindowChanged(BamfMatcher *matcher,
3294- BamfView* old_view,
3295- BamfView* new_view)
3296+void PanelMenuView::OnActiveWindowChanged(BamfMatcher *matcher,
3297+ BamfView* old_view,
3298+ BamfView* new_view)
3299 {
3300 _show_now_activated = false;
3301 _is_maximized = false;
3302@@ -1100,15 +1054,16 @@
3303
3304 if (BAMF_IS_WINDOW(new_view))
3305 {
3306- BamfWindow* window = BAMF_WINDOW(new_view);
3307- guint32 xid = _active_xid = bamf_window_get_xid(window);
3308- _is_maximized = WindowManager::Default()->IsWindowMaximized(xid);
3309- nux::Geometry geo = WindowManager::Default()->GetWindowGeometry(xid);
3310+ WindowManager *wm = WindowManager::Default();
3311+ BamfWindow* window = reinterpret_cast<BamfWindow*>(new_view);
3312+ guint32 xid = bamf_window_get_xid(window);
3313+ _active_xid = xid;
3314+ _is_maximized = wm->IsWindowMaximized(xid);
3315
3316 if (bamf_window_get_window_type(window) == BAMF_WINDOW_DESKTOP)
3317 _we_control_active = true;
3318 else
3319- _we_control_active = UScreen::GetDefault()->GetMonitorGeometry(_monitor).IsPointInside(geo.x + (geo.width / 2), geo.y);
3320+ _we_control_active = IsWindowUnderOurControl(xid);
3321
3322 if (_decor_map.find(xid) == _decor_map.end())
3323 {
3324@@ -1117,9 +1072,9 @@
3325 // if we've just started tracking this window and it is maximized, let's
3326 // make sure it's undecorated just in case it slipped by us earlier
3327 // (I'm looking at you, Chromium!)
3328- if (_is_maximized && WindowManager::Default ()->IsWindowDecorated(xid))
3329+ if (_is_maximized && wm->IsWindowDecorated(xid))
3330 {
3331- WindowManager::Default()->Undecorate(xid);
3332+ wm->Undecorate(xid);
3333 _maximized_set.insert(xid);
3334 }
3335 }
3336@@ -1130,103 +1085,128 @@
3337 // register callback for new view
3338 _view_name_changed_signal.Connect(new_view, "name-changed",
3339 sigc::mem_fun(this, &PanelMenuView::OnNameChanged));
3340+
3341+ _window_buttons->SetControlledWindow(_is_maximized ? _active_xid : 0);
3342 }
3343
3344 Refresh();
3345 FullRedraw();
3346 }
3347
3348-void
3349-PanelMenuView::OnSpreadInitiate()
3350-{
3351- /*foreach (guint32 &xid, windows)
3352- {
3353- if (WindowManager::Default ()->IsWindowMaximized (xid))
3354- WindowManager::Default ()->Decorate (xid);
3355- }*/
3356-}
3357-
3358-void
3359-PanelMenuView::OnSpreadTerminate()
3360-{
3361- /*foreach (guint32 &xid, windows)
3362- {
3363- if (WindowManager::Default ()->IsWindowMaximized (xid))
3364- WindowManager::Default ()->Undecorate (xid);
3365- }*/
3366-}
3367-
3368-void
3369-PanelMenuView::OnWindowMinimized(guint32 xid)
3370-{
3371- if (WindowManager::Default()->IsWindowMaximized(xid))
3372- {
3373- WindowManager::Default()->Decorate(xid);
3374- _maximized_set.erase(xid);
3375- }
3376-}
3377-
3378-void
3379-PanelMenuView::OnWindowUnminimized(guint32 xid)
3380-{
3381- if (WindowManager::Default()->IsWindowMaximized(xid))
3382- {
3383- WindowManager::Default()->Undecorate(xid);
3384- _maximized_set.insert(xid);
3385- }
3386-}
3387-
3388-void
3389-PanelMenuView::OnWindowUnmapped(guint32 xid)
3390-{
3391- if (WindowManager::Default()->IsWindowMaximized(xid))
3392- {
3393- WindowManager::Default()->Decorate(xid);
3394- _maximized_set.erase(xid);
3395- }
3396-}
3397-
3398-void
3399-PanelMenuView::OnWindowMapped(guint32 xid)
3400-{
3401- if (WindowManager::Default()->IsWindowMaximized(xid))
3402- {
3403- WindowManager::Default()->Undecorate(xid);
3404- _maximized_set.insert(xid);
3405- }
3406-}
3407-
3408-void
3409-PanelMenuView::OnWindowDecorated(guint32 xid)
3410+void PanelMenuView::OnSpreadInitiate()
3411+{
3412+ /*foreach (guint32 &xid, windows)
3413+ {
3414+ if (WindowManager::Default()->IsWindowMaximized(xid))
3415+ WindowManager::Default()->Decorate(xid);
3416+ }*/
3417+
3418+ Refresh();
3419+ QueueDraw();
3420+}
3421+
3422+void PanelMenuView::OnSpreadTerminate()
3423+{
3424+ /*foreach (guint32 &xid, windows)
3425+ {
3426+ if (WindowManager::Default()->IsWindowMaximized(xid))
3427+ WindowManager::Default()->Undecorate(xid);
3428+ }*/
3429+
3430+ Refresh();
3431+ QueueDraw();
3432+}
3433+
3434+void PanelMenuView::OnExpoInitiate()
3435+{
3436+ Refresh();
3437+ QueueDraw();
3438+}
3439+
3440+void PanelMenuView::OnExpoTerminate()
3441+{
3442+ Refresh();
3443+ QueueDraw();
3444+}
3445+
3446+void PanelMenuView::OnWindowMinimized(guint32 xid)
3447+{
3448+ if (WindowManager::Default()->IsWindowMaximized(xid))
3449+ {
3450+ WindowManager::Default()->Decorate(xid);
3451+ _maximized_set.erase(xid);
3452+
3453+ Refresh();
3454+ QueueDraw();
3455+ }
3456+}
3457+
3458+void PanelMenuView::OnWindowUnminimized(guint32 xid)
3459+{
3460+ if (WindowManager::Default()->IsWindowMaximized(xid))
3461+ {
3462+ WindowManager::Default()->Undecorate(xid);
3463+ _maximized_set.insert(xid);
3464+
3465+ Refresh();
3466+ QueueDraw();
3467+ }
3468+}
3469+
3470+void PanelMenuView::OnWindowUnmapped(guint32 xid)
3471+{
3472+ // FIXME: compiz doesn't give us a valid xid (is always 0 on unmap)
3473+ // we need to do this again on BamfView closed signal.
3474+ if (_maximized_set.find(xid) != _maximized_set.end())
3475+ {
3476+ WindowManager::Default()->Decorate(xid);
3477+ _maximized_set.erase(xid);
3478+ _decor_map.erase(xid);
3479+
3480+ Refresh();
3481+ QueueDraw();
3482+ }
3483+}
3484+
3485+void PanelMenuView::OnWindowMapped(guint32 xid)
3486+{
3487+ if (WindowManager::Default()->IsWindowMaximized(xid))
3488+ {
3489+ WindowManager::Default()->Undecorate(xid);
3490+ _maximized_set.insert(xid);
3491+
3492+ Refresh();
3493+ QueueDraw();
3494+ }
3495+}
3496+
3497+void PanelMenuView::OnWindowDecorated(guint32 xid)
3498 {
3499 _decor_map[xid] = true;
3500
3501 if (_maximized_set.find(xid) != _maximized_set.end ())
3502 {
3503- WindowManager::Default ()->Undecorate(xid);
3504+ WindowManager::Default()->Undecorate(xid);
3505 }
3506 }
3507
3508-void
3509-PanelMenuView::OnWindowUndecorated(guint32 xid)
3510+void PanelMenuView::OnWindowUndecorated(guint32 xid)
3511 {
3512 _decor_map[xid] = false;
3513 }
3514
3515-void
3516-PanelMenuView::OnWindowMaximized(guint xid)
3517+void PanelMenuView::OnWindowMaximized(guint xid)
3518 {
3519- BamfWindow* window;
3520 bool updated = false;
3521+ bool is_active = (_active_xid == xid);
3522
3523- window = bamf_matcher_get_active_window(_matcher);
3524- if (BAMF_IS_WINDOW(window) && bamf_window_get_xid(window) == xid)
3525+ if (is_active)
3526 {
3527+ // We need to update the _is_inside state in the case of maximization by grab
3528+ auto mouse = nux::GetGraphicsDisplay()->GetMouseScreenCoord();
3529+ _is_inside = GetAbsoluteGeometry().IsInside(mouse);
3530+
3531 _is_maximized = true;
3532-
3533- // We need to update the _is_inside state in the case of maximization by grab
3534- auto mouse = nux::GetGraphicsDisplay()->GetMouseScreenCoord();
3535- _is_inside = GetAbsoluteGeometry().IsPointInside(mouse.x, mouse.y);
3536 updated = true;
3537 }
3538
3539@@ -1245,16 +1225,12 @@
3540 }
3541 }
3542
3543-void
3544-PanelMenuView::OnWindowRestored(guint xid)
3545+void PanelMenuView::OnWindowRestored(guint xid)
3546 {
3547- BamfWindow* window;
3548-
3549 if (_maximized_set.find(xid) == _maximized_set.end())
3550 return;
3551
3552- window = bamf_matcher_get_active_window(_matcher);
3553- if (BAMF_IS_WINDOW(window) && bamf_window_get_xid(window) == xid)
3554+ if (_active_xid == xid)
3555 {
3556 _is_maximized = false;
3557 _is_grabbed = false;
3558@@ -1269,193 +1245,272 @@
3559 FullRedraw();
3560 }
3561
3562-gboolean
3563-PanelMenuView::UpdateActiveWindowPosition(PanelMenuView* self)
3564+gboolean PanelMenuView::UpdateActiveWindowPosition(PanelMenuView* self)
3565 {
3566- auto window_geo = WindowManager::Default()->GetWindowGeometry(self->_active_xid);
3567- auto monitor_geo = UScreen::GetDefault()->GetMonitorGeometry(self->_monitor);
3568- auto intersect = monitor_geo.Intersect(window_geo);
3569-
3570- self->_we_control_active = (intersect.width > window_geo.width/4 &&
3571- intersect.height > window_geo.height/4);
3572+ bool we_control_window = self->IsWindowUnderOurControl(self->_active_xid);
3573+
3574+ if (we_control_window != self->_we_control_active)
3575+ {
3576+ self->_we_control_active = we_control_window;
3577+
3578+ self->Refresh();
3579+ self->QueueDraw();
3580+ }
3581
3582 self->_active_moved_id = 0;
3583- self->QueueDraw();
3584
3585 return FALSE;
3586 }
3587
3588-void
3589-PanelMenuView::OnWindowMoved(guint xid)
3590+void PanelMenuView::OnWindowMoved(guint xid)
3591 {
3592 if (_active_xid == xid)
3593 {
3594- if (_active_moved_id)
3595- g_source_remove(_active_moved_id);
3596-
3597- if (!_we_control_active)
3598- UpdateActiveWindowPosition(this);
3599- else
3600- _active_moved_id = g_timeout_add(250, (GSourceFunc)PanelMenuView::UpdateActiveWindowPosition, this);
3601- }
3602-}
3603-
3604-void
3605-PanelMenuView::OnCloseClicked()
3606-{
3607- if (_places_showing)
3608- {
3609- ubus_server_send_message(ubus_server_get_default(), UBUS_PLACE_VIEW_CLOSE_REQUEST, nullptr);
3610- }
3611- else
3612- {
3613- BamfWindow* window;
3614-
3615- window = bamf_matcher_get_active_window(_matcher);
3616- if (BAMF_IS_WINDOW(window))
3617- {
3618- WindowManager::Default()->Close(bamf_window_get_xid(window));
3619- NeedRedraw();
3620- }
3621- }
3622-}
3623-
3624-void
3625-PanelMenuView::OnMinimizeClicked()
3626-{
3627- if (_places_showing)
3628- {
3629- // no action when dash is opened, LP bug #838875
3630- return;
3631- }
3632- else
3633- {
3634- BamfWindow* window;
3635-
3636- window = bamf_matcher_get_active_window(_matcher);
3637- if (BAMF_IS_WINDOW(window))
3638- {
3639- WindowManager::Default()->Minimize(bamf_window_get_xid(window));
3640- NeedRedraw();
3641- }
3642- }
3643-}
3644-
3645-void
3646-PanelMenuView::OnRestoreClicked()
3647-{
3648- if (_places_showing)
3649- {
3650- if (dash::Settings::Instance().GetFormFactor() == dash::FormFactor::DESKTOP)
3651- dash::Settings::Instance().SetFormFactor(dash::FormFactor::NETBOOK);
3652- else
3653- dash::Settings::Instance().SetFormFactor(dash::FormFactor::DESKTOP);
3654- }
3655- else
3656- {
3657- BamfWindow* window;
3658-
3659- window = bamf_matcher_get_active_window(_matcher);
3660- if (BAMF_IS_WINDOW(window))
3661- {
3662- WindowManager::Default()->Restore(bamf_window_get_xid(window));
3663- NeedRedraw();
3664- }
3665- }
3666-}
3667-
3668-guint32
3669-PanelMenuView::GetMaximizedWindow()
3670-{
3671- guint32 window_xid = 0;
3672- nux::Geometry monitor = UScreen::GetDefault()->GetMonitorGeometry(_monitor);
3673+ /* When moving the active window, if the current panel is controlling
3674+ * the active window, then we postpone the timeout function every movement
3675+ * that we have, setting a longer timeout.
3676+ * Otherwise, if the moved window is not controlled by the current panel
3677+ * every few millisecond we check the new window position */
3678+
3679+ unsigned int timeout = 250;
3680+
3681+ if (_we_control_active)
3682+ {
3683+ if (_active_moved_id)
3684+ g_source_remove(_active_moved_id);
3685+ }
3686+ else
3687+ {
3688+ timeout = 60;
3689+
3690+ if (_active_moved_id)
3691+ return;
3692+ }
3693+
3694+ _active_moved_id = g_timeout_add(timeout, (GSourceFunc)UpdateActiveWindowPosition, this);
3695+ }
3696+}
3697+
3698+bool PanelMenuView::IsWindowUnderOurControl(Window xid) const
3699+{
3700+ if (UScreen::GetDefault()->GetMonitors().size() > 1)
3701+ {
3702+ auto wm = WindowManager::Default();
3703+ nux::Geometry const& window_geo = wm->GetWindowGeometry(xid);
3704+ nux::Geometry const& intersect = _monitor_geo.Intersect(window_geo);
3705+
3706+ /* We only care of the horizontal window portion */
3707+ return (intersect.width > window_geo.width/2 && intersect.height > 0);
3708+ }
3709+
3710+ return true;
3711+}
3712+
3713+bool PanelMenuView::IsValidWindow(Window xid) const
3714+{
3715+ auto wm = WindowManager::Default();
3716+ std::vector<Window> const& our_xids = nux::XInputWindow::NativeHandleList();
3717+
3718+ if (wm->IsWindowOnCurrentDesktop(xid) && !wm->IsWindowObscured(xid) &&
3719+ wm->IsWindowVisible(xid) && IsWindowUnderOurControl(xid) &&
3720+ std::find(our_xids.begin(), our_xids.end(), xid) == our_xids.end())
3721+ {
3722+ return true;
3723+ }
3724+
3725+ return false;
3726+}
3727+
3728+Window PanelMenuView::GetMaximizedWindow() const
3729+{
3730+ Window window_xid = 0;
3731
3732 // Find the front-most of the maximized windows we are controlling
3733 for (auto xid : _maximized_set)
3734 {
3735 // We can safely assume only the front-most is visible
3736- if (WindowManager::Default()->IsWindowOnCurrentDesktop(xid)
3737- && !WindowManager::Default()->IsWindowObscured(xid))
3738- {
3739- nux::Geometry geo = WindowManager::Default()->GetWindowGeometry(xid);
3740- if (monitor.IsPointInside(geo.x + (geo.width / 2), geo.y))
3741+ if (IsValidWindow(xid))
3742+ {
3743+ window_xid = xid;
3744+ break;
3745+ }
3746+ }
3747+
3748+ return window_xid;
3749+}
3750+
3751+Window PanelMenuView::GetTopWindow() const
3752+{
3753+ Window window_xid = 0;
3754+ GList* windows = bamf_matcher_get_window_stack_for_monitor(_matcher, _monitor);
3755+
3756+ for (GList* l = windows; l; l = l->next)
3757+ {
3758+ if (!BAMF_IS_WINDOW(l->data))
3759+ continue;
3760+
3761+ Window xid = bamf_window_get_xid(static_cast<BamfWindow*>(l->data));
3762+ bool visible = bamf_view_user_visible(static_cast<BamfView*>(l->data));
3763+
3764+ if (visible && IsValidWindow(xid))
3765+ {
3766+ window_xid = xid;
3767+ }
3768+ }
3769+
3770+ g_list_free(windows);
3771+
3772+ return window_xid;
3773+}
3774+
3775+BamfWindow* PanelMenuView::GetBamfWindowForXid(Window xid) const
3776+{
3777+ BamfWindow* window = nullptr;
3778+
3779+ if (xid != 0)
3780+ {
3781+ GList* windows = bamf_matcher_get_windows(_matcher);
3782+
3783+ for (GList* l = windows; l; l = l->next)
3784+ {
3785+ if (!BAMF_IS_WINDOW(l->data))
3786+ continue;
3787+
3788+ auto win = static_cast<BamfWindow*>(l->data);
3789+
3790+ if (bamf_window_get_xid(win) == xid)
3791 {
3792- window_xid = xid;
3793+ window = win;
3794 break;
3795 }
3796 }
3797- }
3798- return window_xid;
3799-}
3800-
3801-void
3802-PanelMenuView::OnMaximizedGrabStart(int x, int y, unsigned long button_flags, unsigned long)
3803-{
3804- Window maximized_win;
3805- if (nux::GetEventButton(button_flags) != 1 || _places_showing)
3806- return;
3807-
3808- // When Start dragging the panelmenu of a maximized window, change cursor
3809- // to simulate the dragging, waiting to go out of the panel area.
3810- //
3811- // This is a workaround to avoid that the grid plugin would be fired
3812- // showing the window shape preview effect. See bug #838923
3813-
3814- maximized_win = GetMaximizedWindow ();
3815-
3816- if (maximized_win != 0)
3817+
3818+ g_list_free(windows);
3819+ }
3820+
3821+ return window;
3822+}
3823+
3824+void PanelMenuView::OnMaximizedActivate(int x, int y)
3825+{
3826+ Window maximized = GetMaximizedWindow();
3827+
3828+ if (maximized != 0)
3829+ {
3830+ WindowManager::Default()->Activate(maximized);
3831+ }
3832+}
3833+
3834+void PanelMenuView::OnMaximizedRestore(int x, int y)
3835+{
3836+ if (_overlay_showing)
3837+ return;
3838+
3839+ Window maximized = GetMaximizedWindow();
3840+
3841+ if (maximized != 0)
3842+ {
3843+ WindowManager::Default()->Restore(maximized);
3844+ _is_inside = true;
3845+ }
3846+}
3847+
3848+void PanelMenuView::OnMaximizedLower(int x, int y)
3849+{
3850+ if (_overlay_showing)
3851+ return;
3852+
3853+ Window maximized = GetMaximizedWindow();
3854+
3855+ if (maximized != 0)
3856+ {
3857+ WindowManager::Default()->Lower(maximized);
3858+ }
3859+}
3860+
3861+void PanelMenuView::OnMaximizedGrabStart(int x, int y)
3862+{
3863+ /* When Start dragging the panelmenu of a maximized window, change cursor
3864+ * to simulate the dragging, waiting to go out of the panel area.
3865+ *
3866+ * This is a workaround to avoid that the grid plugin would be fired
3867+ * showing the window shape preview effect. See bug #838923 */
3868+
3869+ Window maximized = GetMaximizedWindow();
3870+
3871+ if (maximized != 0)
3872 {
3873 /* Always activate the window in case it is on another monitor */
3874- WindowManager::Default ()->Activate (maximized_win);
3875- _panel_titlebar_grab_area->SetGrabbed(true);
3876+ WindowManager::Default()->Activate(maximized);
3877+ _titlebar_grab_area->SetGrabbed(true);
3878 }
3879 }
3880
3881-void
3882-PanelMenuView::OnMaximizedGrabMove(int x, int y, int, int, unsigned long button_flags, unsigned long)
3883+void PanelMenuView::OnMaximizedGrabMove(int x, int y)
3884 {
3885-// FIXME nux doesn't export it with drag event.
3886-// if (nux::GetEventButton(button_flags) != 1)
3887-// return;
3888-
3889- // We use this, due to the problem above
3890- if (!_panel_titlebar_grab_area->IsGrabbed())
3891- return;
3892-
3893 auto panel = static_cast<nux::BaseWindow*>(GetTopLevelViewWindow());
3894
3895 if (!panel)
3896 return;
3897
3898- x += _panel_titlebar_grab_area->GetAbsoluteX();
3899- y += _panel_titlebar_grab_area->GetAbsoluteY();
3900-
3901- guint32 window_xid = GetMaximizedWindow();
3902-
3903- // When the drag goes out from the Panel, start the real movement.
3904- //
3905- // This is a workaround to avoid that the grid plugin would be fired
3906- // showing the window shape preview effect. See bug #838923
3907- if (window_xid != 0 && panel && !panel->GetAbsoluteGeometry().IsPointInside(x, y))
3908+ /* Adjusting the x, y coordinates to get the absolute values */
3909+ x += _titlebar_grab_area->GetAbsoluteX();
3910+ y += _titlebar_grab_area->GetAbsoluteY();
3911+
3912+ Window maximized = GetMaximizedWindow();
3913+
3914+ /* When the drag goes out from the Panel, start the real movement.
3915+ *
3916+ * This is a workaround to avoid that the grid plugin would be fired
3917+ * showing the window shape preview effect. See bug #838923 */
3918+ if (maximized != 0 && panel)
3919 {
3920- _panel_titlebar_grab_area->SetGrabbed(false);
3921-
3922- WindowManager::Default()->Activate(window_xid);
3923- _is_inside = true;
3924- _is_grabbed = true;
3925- Refresh();
3926- FullRedraw();
3927- WindowManager::Default()->StartMove(window_xid, x, y);
3928+ nux::Geometry const& panel_geo = panel->GetAbsoluteGeometry();
3929+
3930+ if (!panel_geo.IsPointInside(x, y))
3931+ {
3932+ auto wm = WindowManager::Default();
3933+ nux::Geometry const& restored_geo = wm->GetWindowSavedGeometry(maximized);
3934+ nux::Geometry const& workarea_geo = wm->GetWorkAreaGeometry(maximized);
3935+
3936+ /* By default try to restore the window horizontally-centered respect to the
3937+ * pointer position, if it doesn't fit on that area try to keep it into the
3938+ * current workarea as much as possible, but giving priority to the left border
3939+ * that shouldn't be never put out of the workarea */
3940+ int restore_x = x - (restored_geo.width * x / panel_geo.width);
3941+ int restore_y = y;
3942+
3943+ if (restore_x + restored_geo.width > workarea_geo.x + workarea_geo.width)
3944+ {
3945+ restore_x = workarea_geo.x + workarea_geo.width - restored_geo.width;
3946+ }
3947+
3948+ if (restore_x < workarea_geo.x)
3949+ {
3950+ restore_x = workarea_geo.x;
3951+ }
3952+
3953+ wm->Activate(maximized);
3954+ wm->RestoreAt(maximized, restore_x, restore_y);
3955+
3956+ _is_inside = true;
3957+ _is_grabbed = true;
3958+ Refresh();
3959+ FullRedraw();
3960+
3961+ /* Ungrab the pointer and start the X move, to make the decorator handle it */
3962+ _titlebar_grab_area->SetGrabbed(false);
3963+ wm->StartMove(maximized, x, y);
3964+ }
3965 }
3966 }
3967
3968-void
3969-PanelMenuView::OnMaximizedGrabEnd(int x, int y, unsigned long, unsigned long)
3970+void PanelMenuView::OnMaximizedGrabEnd(int x, int y)
3971 {
3972- _panel_titlebar_grab_area->SetGrabbed(false);
3973+ _titlebar_grab_area->SetGrabbed(false);
3974
3975- x += _panel_titlebar_grab_area->GetAbsoluteX();
3976- y += _panel_titlebar_grab_area->GetAbsoluteY();
3977+ x += _titlebar_grab_area->GetAbsoluteX();
3978+ y += _titlebar_grab_area->GetAbsoluteY();
3979 _is_inside = GetAbsoluteGeometry().IsPointInside(x, y);
3980
3981 if (!_is_inside)
3982@@ -1465,115 +1520,108 @@
3983 FullRedraw();
3984 }
3985
3986-void
3987-PanelMenuView::OnMouseDoubleClicked(int x, int y, unsigned long button_flags, unsigned long)
3988-{
3989- if (nux::GetEventButton(button_flags) != 1 || _places_showing)
3990- return;
3991-
3992- guint32 window_xid = GetMaximizedWindow();
3993-
3994- if (window_xid != 0)
3995- {
3996- WindowManager::Default()->Restore(window_xid);
3997- _is_inside = true;
3998- }
3999-}
4000-
4001-void
4002-PanelMenuView::OnMouseClicked(int x, int y, unsigned long button_flags, unsigned long)
4003-{
4004- if (nux::GetEventButton(button_flags) != 1 || _places_showing)
4005- return;
4006-
4007- guint32 window_xid = GetMaximizedWindow();
4008-
4009- if (window_xid != 0)
4010- {
4011- WindowManager::Default()->Raise(window_xid);
4012- }
4013-}
4014-
4015-void
4016-PanelMenuView::OnMouseMiddleClicked(int x, int y, unsigned long button_flags, unsigned long)
4017-{
4018- if (nux::GetEventButton(button_flags) != 2 || _places_showing)
4019- return;
4020-
4021- guint32 window_xid = GetMaximizedWindow();
4022-
4023- if (window_xid != 0)
4024- {
4025- WindowManager::Default()->Lower(window_xid);
4026- }
4027-}
4028-
4029 // Introspectable
4030 std::string
4031 PanelMenuView::GetName() const
4032 {
4033- return "";
4034+ return "MenuView";
4035 }
4036
4037 void PanelMenuView::AddProperties(GVariantBuilder* builder)
4038 {
4039-}
4040-
4041-void PanelMenuView::OnPlaceViewShown(GVariant* data, PanelMenuView* self)
4042-{
4043- self->_places_showing = true;
4044- self->QueueDraw();
4045-}
4046-
4047-void PanelMenuView::OnPlaceViewHidden(GVariant* data, PanelMenuView* self)
4048-{
4049- self->_places_showing = false;
4050- self->QueueDraw();
4051-}
4052-
4053-void PanelMenuView::OnSwitcherShown(GVariant* data, PanelMenuView* self)
4054-{
4055- if (!self || !data)
4056- return;
4057-
4058- self->_switcher_showing = g_variant_get_boolean(data);
4059-
4060- if (!self->_switcher_showing)
4061+ PanelIndicatorsView::AddProperties(builder);
4062+
4063+ variant::BuilderWrapper(builder)
4064+ .add("mouse_inside", _is_inside)
4065+ .add("grabbed", _is_grabbed)
4066+ .add("active_win_maximized", _is_maximized)
4067+ .add("panel_title", _panel_title)
4068+ .add("monitor", _monitor)
4069+ .add("active_window", _active_xid)
4070+ .add("draw_menus", DrawMenus())
4071+ .add("draw_window_buttons", DrawWindowButtons())
4072+ .add("controls_active_window", _we_control_active);
4073+}
4074+
4075+void PanelMenuView::OnSwitcherShown(GVariant* data)
4076+{
4077+ if (!data)
4078+ return;
4079+
4080+ bool switcher_shown;
4081+ int monitor;
4082+ g_variant_get(data, "(bi)", &switcher_shown, &monitor);
4083+
4084+ if (switcher_shown == _switcher_showing || monitor != _monitor)
4085+ return;
4086+
4087+ _switcher_showing = switcher_shown;
4088+
4089+ if (!_switcher_showing)
4090 {
4091 auto mouse = nux::GetGraphicsDisplay()->GetMouseScreenCoord();
4092- self->_is_inside = self->GetAbsoluteGeometry().IsPointInside(mouse.x, mouse.y);
4093-
4094- if (self->_panel_title)
4095- {
4096- g_free(self->_panel_title);
4097- self->_panel_title = nullptr;
4098- }
4099+ _is_inside = GetAbsoluteGeometry().IsInside(mouse);
4100 }
4101 else
4102 {
4103- self->_show_now_activated = false;
4104- }
4105-
4106- self->Refresh();
4107- self->QueueDraw();
4108-}
4109-
4110-void PanelMenuView::OnSwitcherSelectionChanged(GVariant* data, PanelMenuView* self)
4111-{
4112- if (!self || !data)
4113- return;
4114-
4115- if (self->_panel_title)
4116- g_free(self->_panel_title);
4117-
4118- self->_panel_title = g_strdup(g_variant_get_string(data, 0));
4119-
4120- self->Refresh();
4121- self->QueueDraw();
4122-}
4123-
4124-gboolean
4125-PanelMenuView::UpdateShowNowWithDelay(PanelMenuView *self)
4126+ _show_now_activated = false;
4127+ }
4128+
4129+ Refresh();
4130+ QueueDraw();
4131+}
4132+
4133+void PanelMenuView::OnSwitcherSelectionChanged(GVariant* data)
4134+{
4135+ if (!data || !_switcher_showing)
4136+ return;
4137+
4138+ const gchar *title = g_variant_get_string(data, 0);
4139+ _panel_title = (title ? title : "");
4140+
4141+ Refresh();
4142+ QueueDraw();
4143+}
4144+
4145+void PanelMenuView::OnLauncherKeyNavStarted(GVariant* data)
4146+{
4147+ if (_launcher_keynav)
4148+ return;
4149+
4150+
4151+ if (!data || (data && g_variant_get_int32(data) == _monitor))
4152+ {
4153+ _launcher_keynav = true;
4154+ }
4155+}
4156+
4157+void PanelMenuView::OnLauncherKeyNavEnded(GVariant* data)
4158+{
4159+ if (!_launcher_keynav)
4160+ return;
4161+
4162+ _launcher_keynav = false;
4163+
4164+ auto mouse = nux::GetGraphicsDisplay()->GetMouseScreenCoord();
4165+ _is_inside = GetAbsoluteGeometry().IsInside(mouse);
4166+
4167+ Refresh();
4168+ QueueDraw();
4169+}
4170+
4171+void PanelMenuView::OnLauncherSelectionChanged(GVariant* data)
4172+{
4173+ if (!data || !_launcher_keynav)
4174+ return;
4175+
4176+ const gchar *title = g_variant_get_string(data, 0);
4177+ _panel_title = (title ? title : "");
4178+
4179+ Refresh();
4180+ QueueDraw();
4181+}
4182+
4183+gboolean PanelMenuView::UpdateShowNowWithDelay(PanelMenuView *self)
4184 {
4185 bool active = false;
4186
4187@@ -1597,8 +1645,7 @@
4188 return FALSE;
4189 }
4190
4191-void
4192-PanelMenuView::UpdateShowNow(bool status)
4193+void PanelMenuView::UpdateShowNow(bool status)
4194 {
4195 /* When we get a show now event, if we are requested to show the menus,
4196 * we take the last incoming event and we wait for small delay (to avoid the
4197@@ -1610,6 +1657,7 @@
4198 {
4199 _show_now_activated = false;
4200 QueueDraw();
4201+ return;
4202 }
4203
4204 if (_update_show_now_id != 0)
4205@@ -1626,27 +1674,55 @@
4206 }
4207 }
4208
4209-void
4210-PanelMenuView::SetMonitor(int monitor)
4211+void PanelMenuView::SetMonitor(int monitor)
4212 {
4213 _monitor = monitor;
4214 _monitor_geo = UScreen::GetDefault()->GetMonitorGeometry(_monitor);
4215+
4216+ _maximized_set.clear();
4217+ GList* windows = bamf_matcher_get_window_stack_for_monitor(_matcher, _monitor);
4218+
4219+ for (GList* l = windows; l; l = l->next)
4220+ {
4221+ if (!BAMF_IS_WINDOW(l->data))
4222+ continue;
4223+
4224+ auto window = static_cast<BamfWindow*>(l->data);
4225+ auto view = static_cast<BamfView*>(l->data);
4226+
4227+ if (bamf_view_is_active(view))
4228+ {
4229+ _active_xid = bamf_window_get_xid(window);
4230+ }
4231+
4232+ if (bamf_window_maximized(window) == BAMF_WINDOW_MAXIMIZED)
4233+ {
4234+ Window xid = bamf_window_get_xid(window);
4235+
4236+ _decor_map[xid] = WindowManager::Default()->IsWindowDecorated(xid);
4237+
4238+ if (_decor_map[xid])
4239+ WindowManager::Default()->Undecorate(xid);
4240+
4241+ _maximized_set.insert(xid);
4242+ }
4243+ }
4244+
4245+ Window maximized = GetMaximizedWindow();
4246+ Window buttons_win = (maximized == _active_xid) ? maximized : 0;
4247+
4248+ _window_buttons->SetMonitor(_monitor);
4249+ _window_buttons->SetControlledWindow(buttons_win);
4250+
4251+ g_list_free(windows);
4252 }
4253
4254-bool
4255-PanelMenuView::GetControlsActive()
4256+bool PanelMenuView::GetControlsActive() const
4257 {
4258 return _we_control_active;
4259 }
4260
4261-bool
4262-PanelMenuView::HasOurWindowFocused()
4263-{
4264- return _is_own_window;
4265-}
4266-
4267-void
4268-PanelMenuView::OnPanelViewMouseEnter(int x, int y, unsigned long mouse_button_state, unsigned long special_keys_state)
4269+void PanelMenuView::OnPanelViewMouseEnter(int x, int y, unsigned long mouse_button_state, unsigned long special_keys_state)
4270 {
4271 if (!_is_inside)
4272 {
4273@@ -1659,8 +1735,7 @@
4274 }
4275 }
4276
4277-void
4278-PanelMenuView::OnPanelViewMouseLeave(int x, int y, unsigned long mouse_button_state, unsigned long special_keys_state)
4279+void PanelMenuView::OnPanelViewMouseLeave(int x, int y, unsigned long mouse_button_state, unsigned long special_keys_state)
4280 {
4281 if (_is_inside)
4282 {
4283
4284=== modified file 'plugins/unityshell/src/PanelMenuView.h'
4285--- plugins/unityshell/src/PanelMenuView.h 2012-03-21 12:31:11 +0000
4286+++ plugins/unityshell/src/PanelMenuView.h 2012-04-05 23:42:20 +0000
4287@@ -1,6 +1,6 @@
4288 // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
4289 /*
4290- * Copyright (C) 2010 Canonical Ltd
4291+ * Copyright (C) 2010-2012 Canonical Ltd
4292 *
4293 * This program is free software: you can redistribute it and/or modify
4294 * it under the terms of the GNU General Public License version 3 as
4295@@ -15,14 +15,15 @@
4296 * along with this program. If not, see <http://www.gnu.org/licenses/>.
4297 *
4298 * Authored by: Neil Jagdish Patel <neil.patel@canonical.com>
4299+ * Marco Trevisan <3v1n0@ubuntu.com>
4300 */
4301
4302 #ifndef PANEL_MENU_VIEW_H
4303 #define PANEL_MENU_VIEW_H
4304
4305-#include <Nux/View.h>
4306-#include <map>
4307-#include <set>
4308+#include <UnityCore/GLibWrapper.h>
4309+#include <UnityCore/GLibSignal.h>
4310+#include <libbamf/libbamf.h>
4311
4312 #include "PanelIndicatorsView.h"
4313 #include "StaticCairoText.h"
4314@@ -30,10 +31,7 @@
4315 #include "PanelTitlebarGrabAreaView.h"
4316 #include "PluginAdapter.h"
4317 #include "Animator.h"
4318-
4319-#include <UnityCore/GLibWrapper.h>
4320-#include <UnityCore/GLibSignal.h>
4321-#include <libbamf/libbamf.h>
4322+#include "UBusWrapper.h"
4323
4324 namespace unity
4325 {
4326@@ -41,41 +39,50 @@
4327 class PanelMenuView : public PanelIndicatorsView
4328 {
4329 public:
4330- // This contains all the menubar logic for the Panel. Mainly it contains
4331- // the following states:
4332- // 1. Unmaximized window + no mouse hover
4333- // 2. Unmaximized window + mouse hover
4334- // 3. Unmaximized window + active menu (Alt+F/arrow key nav)
4335- // 4. Maximized window + no mouse hover
4336- // 5. Maximized window + mouse hover
4337- // 6. Maximized window + active menu
4338- //
4339- // It also deals with undecorating maximized windows (and redecorating them
4340- // on unmaximize)
4341-
4342- PanelMenuView(int padding = 6);
4343+ PanelMenuView();
4344 ~PanelMenuView();
4345
4346 void SetMenuShowTimings(int fadein, int fadeout, int discovery,
4347 int discovery_fadein, int discovery_fadeout);
4348
4349- void FullRedraw();
4350+ void SetMousePosition(int x, int y);
4351+ void SetMonitor(int monitor);
4352+
4353+ Window GetTopWindow() const;
4354+ Window GetMaximizedWindow() const;
4355+ bool GetControlsActive() const;
4356+
4357+ void NotifyAllMenusClosed();
4358+
4359+ virtual void AddIndicator(indicator::Indicator::Ptr const& indicator);
4360+
4361+ virtual void OverlayShown();
4362+ virtual void OverlayHidden();
4363+
4364+protected:
4365+ std::string GetName() const;
4366+ void AddProperties(GVariantBuilder* builder);
4367
4368 virtual void Draw(nux::GraphicsEngine& GfxContext, bool force_draw);
4369 virtual void DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw);
4370- virtual long PostLayoutManagement(long LayoutResult);
4371-
4372- void SetMousePosition(int x, int y);
4373-
4374+ virtual void PreLayoutManagement();
4375+ virtual nux::Area* FindAreaUnderMouse(const nux::Point& mouse_position,
4376+ nux::NuxEventType event_type);
4377+ virtual void OnEntryAdded(indicator::Entry::Ptr const& entry);
4378+
4379+private:
4380 void OnActiveChanged(PanelIndicatorEntryView* view, bool is_active);
4381 void OnViewOpened(BamfMatcher* matcher, BamfView* view);
4382 void OnViewClosed(BamfMatcher* matcher, BamfView* view);
4383+ void OnApplicationClosed(BamfApplication* app);
4384 void OnActiveWindowChanged(BamfMatcher* matcher, BamfView* old_view, BamfView* new_view);
4385 void OnActiveAppChanged(BamfMatcher* matcher, BamfApplication* old_app, BamfApplication* new_app);
4386 void OnNameChanged(BamfView* bamf_view, gchar* new_name, gchar* old_name);
4387
4388 void OnSpreadInitiate();
4389 void OnSpreadTerminate();
4390+ void OnExpoInitiate();
4391+ void OnExpoTerminate();
4392 void OnWindowMinimized(guint32 xid);
4393 void OnWindowUnminimized(guint32 xid);
4394 void OnWindowUnmapped(guint32 xid);
4395@@ -86,42 +93,30 @@
4396 void OnWindowDecorated(guint32 xid);
4397 void OnWindowUndecorated(guint32 xid);
4398
4399- guint32 GetMaximizedWindow();
4400-
4401- void OnMaximizedGrabStart(int, int, unsigned long, unsigned long);
4402- void OnMaximizedGrabMove(int, int, int, int, unsigned long, unsigned long);
4403- void OnMaximizedGrabEnd(int, int, unsigned long, unsigned long);
4404- void OnMouseDoubleClicked(int, int, unsigned long, unsigned long);
4405- void OnMouseClicked(int, int, unsigned long, unsigned long);
4406- void OnMouseMiddleClicked(int, int, unsigned long, unsigned long);
4407-
4408- void Refresh();
4409- void AllMenusClosed();
4410-
4411- void OnCloseClicked();
4412- void OnMinimizeClicked();
4413- void OnRestoreClicked();
4414- void SetMonitor(int monitor);
4415- bool GetControlsActive();
4416-
4417- bool HasOurWindowFocused();
4418-
4419-protected:
4420- std::string GetName() const;
4421- void AddProperties(GVariantBuilder* builder);
4422-
4423- virtual nux::Area* FindAreaUnderMouse(const nux::Point& mouse_position, nux::NuxEventType event_type);
4424+ void OnMaximizedActivate(int x, int y);
4425+ void OnMaximizedRestore(int x, int y);
4426+ void OnMaximizedLower(int x, int y);
4427+ void OnMaximizedGrabStart(int x, int y);
4428+ void OnMaximizedGrabMove(int x, int y);
4429+ void OnMaximizedGrabEnd(int x, int y);
4430+
4431+ void FullRedraw();
4432+ void Refresh(bool force = false);
4433+ void DrawTitle(cairo_t *cr_real, nux::Geometry const& geo, std::string const& label) const;
4434+
4435 void OnPanelViewMouseEnter(int x, int y, unsigned long mouse_button_state, unsigned long special_keys_state);
4436 void OnPanelViewMouseLeave(int x, int y, unsigned long mouse_button_state, unsigned long special_keys_state);
4437 void OnPanelViewMouseMove(int x, int y, int dx, int dy, unsigned long mouse_button_state, unsigned long special_keys_state);
4438- virtual void OnEntryAdded(unity::indicator::Entry::Ptr const& entry);
4439-
4440-private:
4441- gchar* GetActiveViewName();
4442- static void OnPlaceViewShown(GVariant* data, PanelMenuView* self);
4443- static void OnPlaceViewHidden(GVariant* data, PanelMenuView* self);
4444- static void OnSwitcherShown(GVariant* data, PanelMenuView* self);
4445- static void OnSwitcherSelectionChanged(GVariant* data, PanelMenuView* self);
4446+
4447+ BamfWindow* GetBamfWindowForXid(Window xid) const;
4448+
4449+ std::string GetActiveViewName(bool use_appname = false) const;
4450+
4451+ void OnSwitcherShown(GVariant* data);
4452+ void OnSwitcherSelectionChanged(GVariant* data);
4453+ void OnLauncherKeyNavStarted(GVariant* data);
4454+ void OnLauncherKeyNavEnded(GVariant* data);
4455+ void OnLauncherSelectionChanged(GVariant* data);
4456
4457 void UpdateShowNow(bool ignore);
4458
4459@@ -130,53 +125,47 @@
4460 static gboolean OnNewAppShow(PanelMenuView* self);
4461 static gboolean OnNewAppHide(PanelMenuView* self);
4462
4463- void DrawText(cairo_t *cr_real,
4464- int &x, int y, int width, int height,
4465- const char* font_desc,
4466- const char* label,
4467- int increase_size=0
4468- );
4469+ bool IsValidWindow(Window xid) const;
4470+ bool IsWindowUnderOurControl(Window xid) const;
4471
4472- bool DrawMenus();
4473- bool DrawWindowButtons();
4474+ bool DrawMenus() const;
4475+ bool DrawWindowButtons() const;
4476
4477 void OnFadeInChanged(double);
4478 void OnFadeOutChanged(double);
4479
4480-private:
4481 glib::Object<BamfMatcher> _matcher;
4482
4483- nux::TextureLayer* _title_layer;
4484- nux::HLayout* _menu_layout;
4485- nux::CairoGraphics _util_cg;
4486+ nux::TextureLayer* _title_layer;
4487+ nux::HLayout* _menu_layout;
4488+ nux::ObjectPtr<nux::BaseTexture> _title_texture;
4489 nux::ObjectPtr<nux::IOpenGLBaseTexture> _gradient_texture;
4490
4491 bool _is_inside;
4492 bool _is_grabbed;
4493 bool _is_maximized;
4494- bool _is_own_window;
4495+
4496 PanelIndicatorEntryView* _last_active_view;
4497+ WindowButtons* _window_buttons;
4498+ PanelTitlebarGrabArea* _titlebar_grab_area;
4499 glib::Object<BamfApplication> _new_application;
4500
4501- WindowButtons* _window_buttons;
4502- PanelTitlebarGrabArea* _panel_titlebar_grab_area;
4503-
4504- std::map<guint32, bool> _decor_map;
4505- std::set<guint32> _maximized_set;
4506+ std::map<Window, bool> _decor_map;
4507+ std::set<Window> _maximized_set;
4508 std::list<glib::Object<BamfApplication>> _new_apps;
4509-
4510- int _padding;
4511- int _last_width;
4512- int _last_height;
4513-
4514- bool _places_showing;
4515+ std::string _panel_title;
4516+ nux::Geometry _last_geo;
4517+
4518+ bool _overlay_showing;
4519 bool _switcher_showing;
4520+ bool _launcher_keynav;
4521 bool _show_now_activated;
4522 bool _we_control_active;
4523 bool _new_app_menu_shown;
4524
4525- int _monitor;
4526- guint32 _active_xid;
4527+ int _monitor;
4528+ Window _active_xid;
4529+
4530 guint32 _active_moved_id;
4531 guint32 _update_show_now_id;
4532 guint32 _new_app_show_id;
4533@@ -188,8 +177,9 @@
4534 glib::Signal<void, BamfMatcher*, BamfView*, BamfView*> _active_win_changed_signal;
4535 glib::Signal<void, BamfMatcher*, BamfApplication*, BamfApplication*> _active_app_changed_signal;
4536 glib::Signal<void, BamfView*, gchar*, gchar*> _view_name_changed_signal;
4537+ sigc::connection _style_changed_connection;
4538
4539- std::vector<unsigned int> _ubus_interests;
4540+ UBusManager _ubus_manager;
4541
4542 int _menus_fadein;
4543 int _menus_fadeout;
4544@@ -197,10 +187,8 @@
4545 int _menus_discovery_fadein;
4546 int _menus_discovery_fadeout;
4547
4548- gchar* _panel_title;
4549-
4550- Animator* _fade_in_animator;
4551- Animator* _fade_out_animator;
4552+ Animator _fade_in_animator;
4553+ Animator _fade_out_animator;
4554 };
4555
4556 }
4557
4558=== modified file 'plugins/unityshell/src/PanelTitlebarGrabAreaView.cpp'
4559--- plugins/unityshell/src/PanelTitlebarGrabAreaView.cpp 2012-02-25 16:19:39 +0000
4560+++ plugins/unityshell/src/PanelTitlebarGrabAreaView.cpp 2012-04-05 23:42:20 +0000
4561@@ -1,6 +1,6 @@
4562 // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
4563 /*
4564- * Copyright (C) 2010-2011 Canonical Ltd
4565+ * Copyright (C) 2010-2012 Canonical Ltd
4566 *
4567 * This program is free software: you can redistribute it and/or modify
4568 * it under the terms of the GNU General Public License version 3 as
4569@@ -27,17 +27,41 @@
4570 #include <UnityCore/Variant.h>
4571 #include <X11/cursorfont.h>
4572
4573+namespace unity
4574+{
4575+namespace
4576+{
4577+ unsigned int MOUSE_DOWN_TIMEOUT = 150;
4578+ unsigned int MOUSE_MOVEMENT_TOLERANCE = 4;
4579+}
4580+
4581 PanelTitlebarGrabArea::PanelTitlebarGrabArea()
4582 : InputArea(NUX_TRACKER_LOCATION)
4583- , _grab_cursor(None)
4584+ , grab_cursor_(None)
4585+ , grab_started_(false)
4586+ , mouse_down_timer_(0)
4587+ , mouse_down_button_(0)
4588 {
4589 EnableDoubleClick(true);
4590+
4591+ mouse_down.connect(sigc::mem_fun(this, &PanelTitlebarGrabArea::OnMouseDown));
4592+ mouse_up.connect(sigc::mem_fun(this, &PanelTitlebarGrabArea::OnMouseUp));
4593+ mouse_drag.connect(sigc::mem_fun(this, &PanelTitlebarGrabArea::OnGrabMove));
4594+
4595+ mouse_double_click.connect([&] (int x, int y, unsigned long button_flags, unsigned long)
4596+ {
4597+ if (nux::GetEventButton(button_flags) == 1)
4598+ restore_request.emit(x, y);
4599+ });
4600 }
4601
4602 PanelTitlebarGrabArea::~PanelTitlebarGrabArea()
4603 {
4604- if (_grab_cursor)
4605- XFreeCursor(nux::GetGraphicsDisplay()->GetX11Display(), _grab_cursor);
4606+ if (grab_cursor_)
4607+ XFreeCursor(nux::GetGraphicsDisplay()->GetX11Display(), grab_cursor_);
4608+
4609+ if (mouse_down_timer_)
4610+ g_source_remove(mouse_down_timer_);
4611 }
4612
4613 void PanelTitlebarGrabArea::SetGrabbed(bool enabled)
4614@@ -48,32 +72,120 @@
4615 if (!panel_window || !display)
4616 return;
4617
4618- if (enabled && !_grab_cursor)
4619+ if (enabled && !grab_cursor_)
4620 {
4621- _grab_cursor = XCreateFontCursor(display, XC_fleur);
4622- XDefineCursor(display, panel_window->GetInputWindowId(), _grab_cursor);
4623+ grab_cursor_ = XCreateFontCursor(display, XC_fleur);
4624+ XDefineCursor(display, panel_window->GetInputWindowId(), grab_cursor_);
4625 }
4626- else if (!enabled && _grab_cursor)
4627+ else if (!enabled && grab_cursor_)
4628 {
4629 XUndefineCursor(display, panel_window->GetInputWindowId());
4630- XFreeCursor(display, _grab_cursor);
4631- _grab_cursor = None;
4632+ XFreeCursor(display, grab_cursor_);
4633+ grab_cursor_ = None;
4634 }
4635 }
4636
4637 bool PanelTitlebarGrabArea::IsGrabbed()
4638 {
4639- return (_grab_cursor != None);
4640+ return (grab_cursor_ != None);
4641+}
4642+
4643+void PanelTitlebarGrabArea::OnMouseDown(int x, int y, unsigned long button_flags, unsigned long)
4644+{
4645+ mouse_down_button_ = nux::GetEventButton(button_flags);
4646+
4647+ if (mouse_down_button_ == 2)
4648+ {
4649+ lower_request.emit(x, y);
4650+ }
4651+ else if (mouse_down_button_ == 1)
4652+ {
4653+ mouse_down_point_.x = x;
4654+ mouse_down_point_.y = y;
4655+
4656+ mouse_down_timer_ =
4657+ g_timeout_add(MOUSE_DOWN_TIMEOUT, [] (gpointer data) -> gboolean {
4658+ auto self = static_cast<PanelTitlebarGrabArea*>(data);
4659+
4660+ if (!self->grab_started_)
4661+ {
4662+ nux::Point const& mouse = nux::GetGraphicsDisplay()->GetMouseScreenCoord();
4663+ self->grab_started.emit(mouse.x - self->GetAbsoluteX(), mouse.y - self->GetAbsoluteY());
4664+ self->grab_started_ = true;
4665+ }
4666+
4667+ self->mouse_down_timer_ = 0;
4668+ return FALSE;
4669+ }, this);
4670+ }
4671+}
4672+
4673+void PanelTitlebarGrabArea::OnMouseUp(int x, int y, unsigned long button_flags, unsigned long)
4674+{
4675+ int button = nux::GetEventButton(button_flags);
4676+
4677+ if (button == 1)
4678+ {
4679+ if (mouse_down_timer_)
4680+ {
4681+ g_source_remove(mouse_down_timer_);
4682+ mouse_down_timer_ = 0;
4683+
4684+ activate_request.emit(x, y);
4685+ }
4686+
4687+ if (grab_started_)
4688+ {
4689+ grab_end.emit(x, y);
4690+ grab_started_ = false;
4691+ }
4692+ }
4693+
4694+ mouse_down_button_ = 0;
4695+ mouse_down_point_.x = 0;
4696+ mouse_down_point_.y = 0;
4697+}
4698+
4699+void PanelTitlebarGrabArea::OnGrabMove(int x, int y, int, int, unsigned long button_flags, unsigned long)
4700+{
4701+ if (mouse_down_button_ != 1)
4702+ return;
4703+
4704+ if (mouse_down_timer_)
4705+ {
4706+ if (abs(mouse_down_point_.x - x) <= MOUSE_MOVEMENT_TOLERANCE &&
4707+ abs(mouse_down_point_.y - y) <= MOUSE_MOVEMENT_TOLERANCE)
4708+ {
4709+ return;
4710+ }
4711+
4712+ g_source_remove(mouse_down_timer_);
4713+ mouse_down_timer_ = 0;
4714+ }
4715+
4716+ if (!grab_started_)
4717+ {
4718+ grab_started.emit(x, y);
4719+ grab_started_ = true;
4720+ }
4721+ else
4722+ {
4723+ grab_move.emit(x, y);
4724+ }
4725 }
4726
4727 std::string
4728 PanelTitlebarGrabArea::GetName() const
4729 {
4730- return "panel-titlebar-grab-area";
4731+ return "GrabArea";
4732 }
4733
4734 void
4735 PanelTitlebarGrabArea::AddProperties(GVariantBuilder* builder)
4736 {
4737- unity::variant::BuilderWrapper(builder).add(GetGeometry());
4738+ unity::variant::BuilderWrapper(builder)
4739+ .add(GetGeometry())
4740+ .add("grabbed", IsGrabbed());
4741+}
4742+
4743 }
4744
4745=== modified file 'plugins/unityshell/src/PanelTitlebarGrabAreaView.h'
4746--- plugins/unityshell/src/PanelTitlebarGrabAreaView.h 2012-02-25 16:19:39 +0000
4747+++ plugins/unityshell/src/PanelTitlebarGrabAreaView.h 2012-04-05 23:42:20 +0000
4748@@ -1,6 +1,6 @@
4749 // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
4750 /*
4751- * Copyright (C) 2010-2011 Canonical Ltd
4752+ * Copyright (C) 2010-2012 Canonical Ltd
4753 *
4754 * This program is free software: you can redistribute it and/or modify
4755 * it under the terms of the GNU General Public License version 3 as
4756@@ -27,10 +27,13 @@
4757
4758 #include "Introspectable.h"
4759
4760+namespace unity
4761+{
4762+
4763 class PanelTitlebarGrabArea : public nux::InputArea, public unity::debug::Introspectable
4764 {
4765- /* This acts a bit like a titlebar, it can be grabbed (such that we can pull
4766- * the window down) */
4767+ /* This acts a bit like a decorator, it can be clicked or grabbed (such that
4768+ * we can pull the window down) */
4769
4770 public:
4771 PanelTitlebarGrabArea();
4772@@ -39,11 +42,29 @@
4773 void SetGrabbed(bool enabled);
4774 bool IsGrabbed();
4775
4776+ sigc::signal<void, int, int> lower_request;
4777+ sigc::signal<void, int, int> activate_request;
4778+ sigc::signal<void, int, int> restore_request;
4779+ sigc::signal<void, int, int> grab_started;
4780+ sigc::signal<void, int, int> grab_move;
4781+ sigc::signal<void, int, int> grab_end;
4782+
4783+protected:
4784+ std::string GetName() const;
4785+ void AddProperties(GVariantBuilder* builder);
4786+
4787 private:
4788- std::string GetName() const;
4789- void AddProperties(GVariantBuilder* builder);
4790+ void OnMouseDown(int x, int y, unsigned long button_flags, unsigned long);
4791+ void OnMouseUp(int x, int y, unsigned long button_flags, unsigned long);
4792+ void OnGrabMove(int x, int y, int, int, unsigned long button_flags, unsigned long);
4793
4794- Cursor _grab_cursor;
4795+ Cursor grab_cursor_;
4796+ bool grab_started_;
4797+ guint mouse_down_timer_;
4798+ nux::Point mouse_down_point_;
4799+ unsigned int mouse_down_button_;
4800 };
4801
4802+} // NAMESPACE
4803+
4804 #endif
4805
4806=== modified file 'plugins/unityshell/src/PanelTray.cpp'
4807--- plugins/unityshell/src/PanelTray.cpp 2012-03-21 12:31:11 +0000
4808+++ plugins/unityshell/src/PanelTray.cpp 2012-04-05 23:42:20 +0000
4809@@ -1,5 +1,5 @@
4810 /*
4811- * Copyright (C) 2010 Canonical Ltd
4812+ * Copyright (C) 2010-2012 Canonical Ltd
4813 *
4814 * This program is free software: you can redistribute it and/or modify
4815 * it under the terms of the GNU General Public License version 3 as
4816@@ -14,11 +14,14 @@
4817 * along with this program. If not, see <http://www.gnu.org/licenses/>.
4818 *
4819 * Authored by: Neil Jagdish Patel <neil.patel@canonical.com>
4820+ * Marco Trevisan (Treviño) <3v1n0@ubuntu.com>
4821 */
4822
4823 #include "PanelTray.h"
4824+#include "PanelStyle.h"
4825
4826 #include <NuxCore/Logger.h>
4827+#include <UnityCore/Variant.h>
4828
4829 namespace
4830 {
4831@@ -31,137 +34,118 @@
4832 {
4833
4834 PanelTray::PanelTray()
4835- : View(NUX_TRACKER_LOCATION),
4836- _window(0),
4837- _tray(NULL),
4838- _last_x(0),
4839- _last_y(0),
4840- _tray_icon_added_id(0)
4841-{
4842- _settings = g_settings_new(SETTINGS_NAME.c_str());
4843- _whitelist = g_settings_get_strv(_settings, "systray-whitelist");
4844-
4845- RealInit();
4846-}
4847-
4848-unsigned int
4849-PanelTray::xid ()
4850-{
4851- if (!_window)
4852- return 0;
4853-
4854- return gdk_x11_window_get_xid (gtk_widget_get_window (_window));
4855-}
4856-
4857-void PanelTray::RealInit()
4858-{
4859- _window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
4860- gtk_window_set_type_hint(GTK_WINDOW(_window), GDK_WINDOW_TYPE_HINT_DOCK);
4861- gtk_window_set_has_resize_grip(GTK_WINDOW(_window), FALSE);
4862- gtk_window_set_keep_above(GTK_WINDOW(_window), TRUE);
4863- gtk_window_set_skip_pager_hint(GTK_WINDOW(_window), TRUE);
4864- gtk_window_set_skip_taskbar_hint(GTK_WINDOW(_window), TRUE);
4865- gtk_window_resize(GTK_WINDOW(_window), 1, 24);
4866- gtk_window_move(GTK_WINDOW(_window), -24,-24);
4867- gtk_widget_set_name(_window, "UnityPanelApplet");
4868-
4869- gtk_widget_set_visual(_window, gdk_screen_get_rgba_visual(gdk_screen_get_default()));
4870- gtk_widget_realize(_window);
4871- gtk_widget_set_app_paintable(_window, TRUE);
4872- _tray_expose_id = g_signal_connect(_window, "draw", G_CALLBACK(PanelTray::OnTrayDraw), this);
4873+ : View(NUX_TRACKER_LOCATION)
4874+ , settings_(g_settings_new(SETTINGS_NAME.c_str()))
4875+ , window_(gtk_window_new(GTK_WINDOW_TOPLEVEL))
4876+ , whitelist_(g_settings_get_strv(settings_, "systray-whitelist"))
4877+{
4878+ int panel_height = panel::Style::Instance().panel_height;
4879+
4880+ whitelist_changed_.Connect(settings_, "changed::systray-whitelist", [&] (GSettings*, gchar*) {
4881+ g_strfreev(whitelist_);
4882+ whitelist_ = g_settings_get_strv(settings_, "systray-whitelist");
4883+ });
4884+
4885+ auto gtkwindow = glib::object_cast<GtkWindow>(window_);
4886+ gtk_window_set_type_hint(gtkwindow, GDK_WINDOW_TYPE_HINT_DOCK);
4887+ gtk_window_set_has_resize_grip(gtkwindow, FALSE);
4888+ gtk_window_set_keep_above(gtkwindow, TRUE);
4889+ gtk_window_set_skip_pager_hint(gtkwindow, TRUE);
4890+ gtk_window_set_skip_taskbar_hint(gtkwindow, TRUE);
4891+ gtk_window_resize(gtkwindow, 1, panel_height);
4892+ gtk_window_move(gtkwindow, -panel_height,-panel_height);
4893+ gtk_widget_set_name(window_, "UnityPanelApplet");
4894+
4895+ gtk_widget_set_visual(window_, gdk_screen_get_rgba_visual(gdk_screen_get_default()));
4896+ gtk_widget_realize(window_);
4897+ gtk_widget_set_app_paintable(window_, TRUE);
4898+ draw_signal_.Connect(window_, "draw", sigc::mem_fun(this, &PanelTray::OnTrayDraw));
4899
4900 if (!g_getenv("UNITY_PANEL_TRAY_DISABLE"))
4901 {
4902- _tray = na_tray_new_for_screen(gdk_screen_get_default(),
4903+ tray_ = na_tray_new_for_screen(gdk_screen_get_default(),
4904 GTK_ORIENTATION_HORIZONTAL,
4905 (NaTrayFilterCallback)FilterTrayCallback,
4906 this);
4907- na_tray_set_icon_size(_tray, 24);
4908-
4909- _tray_icon_added_id = g_signal_connect(na_tray_get_manager(_tray), "tray_icon_removed",
4910- G_CALLBACK(PanelTray::OnTrayIconRemoved), this);
4911-
4912- gtk_container_add(GTK_CONTAINER(_window), GTK_WIDGET(_tray));
4913- gtk_widget_show(GTK_WIDGET(_tray));
4914+ na_tray_set_icon_size(tray_, panel_height);
4915+
4916+ icon_removed_signal_.Connect(na_tray_get_manager(tray_), "tray_icon_removed",
4917+ sigc::mem_fun(this, &PanelTray::OnTrayIconRemoved));
4918+
4919+ gtk_container_add(GTK_CONTAINER(window_.RawPtr()), GTK_WIDGET(tray_.RawPtr()));
4920+ gtk_widget_show(GTK_WIDGET(tray_.RawPtr()));
4921 }
4922
4923- SetMinMaxSize(1, 24);
4924-
4925+ SetMinMaxSize(1, panel_height);
4926 }
4927
4928 PanelTray::~PanelTray()
4929 {
4930- if (_tray)
4931- {
4932- g_signal_handler_disconnect(na_tray_get_manager(_tray), _tray_icon_added_id);
4933- _tray = NULL;
4934- }
4935-
4936 g_idle_remove_by_data(this);
4937-
4938- if (_tray_expose_id)
4939- g_signal_handler_disconnect(_window, _tray_expose_id);
4940-
4941- gtk_widget_destroy(_window);
4942- g_strfreev(_whitelist);
4943- g_object_unref(_settings);
4944-}
4945-
4946-void
4947-PanelTray::Draw(nux::GraphicsEngine& gfx_context, bool force_draw)
4948-{
4949- nux::Geometry geo(GetAbsoluteGeometry());
4950+ g_strfreev(whitelist_);
4951+
4952+ if (gtk_widget_get_realized(window_))
4953+ gtk_widget_destroy(window_);
4954+}
4955+
4956+Window PanelTray::xid()
4957+{
4958+ if (!window_)
4959+ return 0;
4960+
4961+ return gdk_x11_window_get_xid(gtk_widget_get_window(window_));
4962+}
4963+
4964+void PanelTray::Draw(nux::GraphicsEngine& gfx_context, bool force_draw)
4965+{
4966+ nux::Geometry const& geo = GetAbsoluteGeometry();
4967
4968 gfx_context.PushClippingRectangle(geo);
4969 nux::GetPainter().PaintBackground(gfx_context, geo);
4970 gfx_context.PopClippingRectangle();
4971
4972- if (geo.x != _last_x || geo.y != _last_y)
4973+ if (geo != last_geo_)
4974 {
4975- _last_x = geo.x;
4976- _last_y = geo.y;
4977-
4978- gtk_window_move(GTK_WINDOW(_window), geo.x + PADDING, geo.y);
4979+ last_geo_ = geo;
4980+ gtk_window_move(GTK_WINDOW(window_.RawPtr()), geo.x + PADDING, geo.y);
4981 }
4982 }
4983
4984-void
4985-PanelTray::Sync()
4986+void PanelTray::Sync()
4987 {
4988- if (_tray)
4989+ if (tray_)
4990 {
4991- SetMinMaxSize(WidthOfTray() + (PADDING * 2), 24);
4992+ SetMinMaxSize(WidthOfTray() + (PADDING * 2), panel::Style::Instance().panel_height);
4993 QueueRelayout();
4994 QueueDraw();
4995
4996- if (_children.size())
4997- gtk_widget_show(_window);
4998+ if (!children_.empty())
4999+ gtk_widget_show(window_);
5000 else
The diff has been truncated for viewing.