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

Proposed by Marco Trevisan (Treviño)
Status: Merged
Approved by: Didier Roche-Tolomelli
Approved revision: no longer in the source branch.
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) Approve
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.
Revision history for this message
Tim Penhey (thumper) wrote :

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

Revision history for this message
Tim Penhey (thumper) wrote :

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

Revision history for this message
Tim Penhey (thumper) wrote :

Reviews in progress on the others.

review: Needs Fixing
Revision history for this message
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)

Revision history for this message
Tim Penhey (thumper) wrote :

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

Revision history for this message
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.

Revision history for this message
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!

Revision history for this message
Tim Penhey (thumper) wrote :

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

review: Approve
Revision history for this message
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
=== modified file 'UnityCore/Variant.cpp'
--- UnityCore/Variant.cpp 2012-03-21 12:31:11 +0000
+++ UnityCore/Variant.cpp 2012-04-05 23:42:20 +0000
@@ -142,15 +142,44 @@
142 return *this;142 return *this;
143}143}
144144
145BuilderWrapper& BuilderWrapper::add(char const* name, unsigned value)145BuilderWrapper& BuilderWrapper::add(char const* name, long int value)
146{
147 g_variant_builder_add(builder_, "{sv}", name, g_variant_new_int64(value));
148 return *this;
149}
150
151BuilderWrapper& BuilderWrapper::add(char const* name, long long int value)
152{
153 g_variant_builder_add(builder_, "{sv}", name, g_variant_new_int64(value));
154 return *this;
155}
156
157BuilderWrapper& BuilderWrapper::add(char const* name, unsigned int value)
146{158{
147 g_variant_builder_add(builder_, "{sv}", name, g_variant_new_uint32(value));159 g_variant_builder_add(builder_, "{sv}", name, g_variant_new_uint32(value));
148 return *this;160 return *this;
149}161}
150162
163BuilderWrapper& BuilderWrapper::add(char const* name, long unsigned int value)
164{
165 g_variant_builder_add(builder_, "{sv}", name, g_variant_new_uint64(value));
166 return *this;
167}
168
169BuilderWrapper& BuilderWrapper::add(char const* name, long long unsigned int value)
170{
171 g_variant_builder_add(builder_, "{sv}", name, g_variant_new_uint64(value));
172 return *this;
173}
174
151BuilderWrapper& BuilderWrapper::add(char const* name, float value)175BuilderWrapper& BuilderWrapper::add(char const* name, float value)
152{176{
153 // floats get promoted to doubles automatically177 g_variant_builder_add(builder_, "{sv}", name, g_variant_new_double(value));
178 return *this;
179}
180
181BuilderWrapper& BuilderWrapper::add(char const* name, double value)
182{
154 g_variant_builder_add(builder_, "{sv}", name, g_variant_new_double(value));183 g_variant_builder_add(builder_, "{sv}", name, g_variant_new_double(value));
155 return *this;184 return *this;
156}185}
157186
=== modified file 'UnityCore/Variant.h'
--- UnityCore/Variant.h 2012-03-21 12:31:11 +0000
+++ UnityCore/Variant.h 2012-04-05 23:42:20 +0000
@@ -73,8 +73,13 @@
73 BuilderWrapper& add(char const* name, char const* value);73 BuilderWrapper& add(char const* name, char const* value);
74 BuilderWrapper& add(char const* name, std::string const& value);74 BuilderWrapper& add(char const* name, std::string const& value);
75 BuilderWrapper& add(char const* name, int value);75 BuilderWrapper& add(char const* name, int value);
76 BuilderWrapper& add(char const* name, unsigned value);76 BuilderWrapper& add(char const* name, long int value);
77 BuilderWrapper& add(char const* name, long long int value);
78 BuilderWrapper& add(char const* name, unsigned int value);
79 BuilderWrapper& add(char const* name, long unsigned int value);
80 BuilderWrapper& add(char const* name, long long unsigned int value);
77 BuilderWrapper& add(char const* name, float value);81 BuilderWrapper& add(char const* name, float value);
82 BuilderWrapper& add(char const* name, double value);
78 BuilderWrapper& add(char const* name, GVariant* value);83 BuilderWrapper& add(char const* name, GVariant* value);
79 BuilderWrapper& add(nux::Rect const& value);84 BuilderWrapper& add(nux::Rect const& value);
8085
8186
=== modified file 'plugins/unityshell/src/DashController.cpp'
--- plugins/unityshell/src/DashController.cpp 2012-03-21 12:31:11 +0000
+++ plugins/unityshell/src/DashController.cpp 2012-04-05 23:42:20 +0000
@@ -40,6 +40,7 @@
40Controller::Controller()40Controller::Controller()
41 : launcher_width(64)41 : launcher_width(64)
42 , use_primary(false)42 , use_primary(false)
43 , monitor_(0)
43 , window_(0)44 , window_(0)
44 , visible_(false)45 , visible_(false)
45 , need_show_(false)46 , need_show_(false)
@@ -126,7 +127,7 @@
126 g_variant_get(data, UBUS_OVERLAY_FORMAT_STRING, &overlay_identity, &can_maximise, &overlay_monitor);127 g_variant_get(data, UBUS_OVERLAY_FORMAT_STRING, &overlay_identity, &can_maximise, &overlay_monitor);
127128
128 // hide if something else is coming up129 // hide if something else is coming up
129 if (g_strcmp0(overlay_identity, "dash"))130 if (overlay_identity.Str() != "dash")
130 {131 {
131 HideDash(true);132 HideDash(true);
132 }133 }
@@ -272,7 +273,8 @@
272273
273 StartShowHideTimeline();274 StartShowHideTimeline();
274275
275 GVariant* info = g_variant_new(UBUS_OVERLAY_FORMAT_STRING, "dash", TRUE, GetIdealMonitor());276 monitor_ = GetIdealMonitor();
277 GVariant* info = g_variant_new(UBUS_OVERLAY_FORMAT_STRING, "dash", TRUE, monitor_);
276 ubus_manager_.SendMessage(UBUS_OVERLAY_SHOWN, info);278 ubus_manager_.SendMessage(UBUS_OVERLAY_SHOWN, info);
277}279}
278280
@@ -298,7 +300,7 @@
298300
299 StartShowHideTimeline();301 StartShowHideTimeline();
300302
301 GVariant* info = g_variant_new(UBUS_OVERLAY_FORMAT_STRING, "dash", TRUE, GetIdealMonitor());303 GVariant* info = g_variant_new(UBUS_OVERLAY_FORMAT_STRING, "dash", TRUE, monitor_);
302 ubus_manager_.SendMessage(UBUS_OVERLAY_HIDDEN, info);304 ubus_manager_.SendMessage(UBUS_OVERLAY_HIDDEN, info);
303}305}
304306
305307
=== modified file 'plugins/unityshell/src/DashController.h'
--- plugins/unityshell/src/DashController.h 2012-03-27 22:34:53 +0000
+++ plugins/unityshell/src/DashController.h 2012-04-05 23:42:20 +0000
@@ -89,6 +89,7 @@
89private:89private:
90 glib::SignalManager sig_manager_;90 glib::SignalManager sig_manager_;
91 UBusManager ubus_manager_;91 UBusManager ubus_manager_;
92 int monitor_;
9293
93 nux::BaseWindow* window_;94 nux::BaseWindow* window_;
94 bool visible_;95 bool visible_;
9596
=== modified file 'plugins/unityshell/src/LauncherController.cpp'
--- plugins/unityshell/src/LauncherController.cpp 2012-04-05 00:32:14 +0000
+++ plugins/unityshell/src/LauncherController.cpp 2012-04-05 23:42:20 +0000
@@ -1101,9 +1101,9 @@
1101void Controller::KeyNavGrab()1101void Controller::KeyNavGrab()
1102{1102{
1103 pimpl->ubus.SendMessage(UBUS_PLACE_VIEW_CLOSE_REQUEST);1103 pimpl->ubus.SendMessage(UBUS_PLACE_VIEW_CLOSE_REQUEST);
1104 pimpl->launcher_grabbed = true;
1104 KeyNavActivate();1105 KeyNavActivate();
1105 pimpl->keyboard_launcher_->GrabKeyboard();1106 pimpl->keyboard_launcher_->GrabKeyboard();
1106 pimpl->launcher_grabbed = true;
11071107
1108 pimpl->launcher_key_press_connection_ =1108 pimpl->launcher_key_press_connection_ =
1109 pimpl->keyboard_launcher_->key_down.connect(sigc::mem_fun(pimpl, &Controller::Impl::ReceiveLauncherKeyPress));1109 pimpl->keyboard_launcher_->key_down.connect(sigc::mem_fun(pimpl, &Controller::Impl::ReceiveLauncherKeyPress));
@@ -1124,18 +1124,50 @@
1124 pimpl->keyboard_launcher_->EnterKeyNavMode();1124 pimpl->keyboard_launcher_->EnterKeyNavMode();
1125 pimpl->model_->SetSelection(0);1125 pimpl->model_->SetSelection(0);
11261126
1127 pimpl->ubus.SendMessage(UBUS_LAUNCHER_START_KEY_SWTICHER, g_variant_new_boolean(true));1127 if (pimpl->launcher_grabbed)
1128 pimpl->ubus.SendMessage(UBUS_LAUNCHER_START_KEY_NAV, NULL);1128 {
1129 pimpl->ubus.SendMessage(UBUS_LAUNCHER_START_KEY_NAV,
1130 g_variant_new_int32(pimpl->keyboard_launcher_->monitor));
1131 }
1132 else
1133 {
1134 pimpl->ubus.SendMessage(UBUS_LAUNCHER_START_KEY_SWTICHER,
1135 g_variant_new_int32(pimpl->keyboard_launcher_->monitor));
1136 }
1137
1138 AbstractLauncherIcon::Ptr const& selected = pimpl->model_->Selection();
1139
1140 if (selected)
1141 {
1142 pimpl->ubus.SendMessage(UBUS_LAUNCHER_SELECTION_CHANGED,
1143 g_variant_new_string(selected->tooltip_text().c_str()));
1144 }
1129}1145}
11301146
1131void Controller::KeyNavNext()1147void Controller::KeyNavNext()
1132{1148{
1133 pimpl->model_->SelectNext();1149 pimpl->model_->SelectNext();
1150
1151 AbstractLauncherIcon::Ptr const& selected = pimpl->model_->Selection();
1152
1153 if (selected)
1154 {
1155 pimpl->ubus.SendMessage(UBUS_LAUNCHER_SELECTION_CHANGED,
1156 g_variant_new_string(selected->tooltip_text().c_str()));
1157 }
1134}1158}
11351159
1136void Controller::KeyNavPrevious()1160void Controller::KeyNavPrevious()
1137{1161{
1138 pimpl->model_->SelectPrevious();1162 pimpl->model_->SelectPrevious();
1163
1164 AbstractLauncherIcon::Ptr const& selected = pimpl->model_->Selection();
1165
1166 if (selected)
1167 {
1168 pimpl->ubus.SendMessage(UBUS_LAUNCHER_SELECTION_CHANGED,
1169 g_variant_new_string(selected->tooltip_text().c_str()));
1170 }
1139}1171}
11401172
1141void Controller::KeyNavTerminate(bool activate)1173void Controller::KeyNavTerminate(bool activate)
@@ -1143,13 +1175,28 @@
1143 if (!pimpl->launcher_keynav)1175 if (!pimpl->launcher_keynav)
1144 return;1176 return;
11451177
1178 if (activate && pimpl->keynav_restore_window_)
1179 {
1180 /* If the selected icon is running, we must not restore the input to the old */
1181 AbstractLauncherIcon::Ptr const& icon = pimpl->model_->Selection();
1182 pimpl->keynav_restore_window_ = !icon->GetQuirk(AbstractLauncherIcon::QUIRK_RUNNING);
1183 }
1184
1146 pimpl->keyboard_launcher_->ExitKeyNavMode();1185 pimpl->keyboard_launcher_->ExitKeyNavMode();
1186
1147 if (pimpl->launcher_grabbed)1187 if (pimpl->launcher_grabbed)
1148 {1188 {
1149 pimpl->keyboard_launcher_->UnGrabKeyboard();1189 pimpl->keyboard_launcher_->UnGrabKeyboard();
1150 pimpl->launcher_key_press_connection_.disconnect();1190 pimpl->launcher_key_press_connection_.disconnect();
1151 pimpl->launcher_event_outside_connection_.disconnect();1191 pimpl->launcher_event_outside_connection_.disconnect();
1152 pimpl->launcher_grabbed = false;1192 pimpl->launcher_grabbed = false;
1193 pimpl->ubus.SendMessage(UBUS_LAUNCHER_END_KEY_NAV,
1194 g_variant_new_boolean(pimpl->keynav_restore_window_));
1195 }
1196 else
1197 {
1198 pimpl->ubus.SendMessage(UBUS_LAUNCHER_END_KEY_SWTICHER,
1199 g_variant_new_boolean(pimpl->keynav_restore_window_));
1153 }1200 }
11541201
1155 if (activate)1202 if (activate)
@@ -1158,9 +1205,6 @@
1158 pimpl->launcher_keynav = false;1205 pimpl->launcher_keynav = false;
1159 if (!pimpl->launcher_open)1206 if (!pimpl->launcher_open)
1160 pimpl->keyboard_launcher_.Release();1207 pimpl->keyboard_launcher_.Release();
1161
1162 pimpl->ubus.SendMessage(UBUS_LAUNCHER_END_KEY_SWTICHER, g_variant_new_boolean(true));
1163 pimpl->ubus.SendMessage(UBUS_LAUNCHER_END_KEY_NAV, g_variant_new_boolean(pimpl->keynav_restore_window_));
1164}1208}
11651209
1166bool Controller::KeyNavIsActive() const1210bool Controller::KeyNavIsActive() const
@@ -1260,8 +1304,7 @@
1260 // <RETURN> (start/activate currently selected icon)1304 // <RETURN> (start/activate currently selected icon)
1261 case NUX_VK_ENTER:1305 case NUX_VK_ENTER:
1262 case NUX_KP_ENTER:1306 case NUX_KP_ENTER:
1263 model_->Selection()->Activate(ActionArg(ActionArg::LAUNCHER, 0));1307 parent_->KeyNavTerminate(true);
1264 parent_->KeyNavTerminate(false);
1265 break;1308 break;
12661309
1267 default:1310 default:
12681311
=== modified file 'plugins/unityshell/src/PanelController.cpp'
--- plugins/unityshell/src/PanelController.cpp 2012-03-22 19:33:10 +0000
+++ plugins/unityshell/src/PanelController.cpp 2012-04-05 23:42:20 +0000
@@ -26,6 +26,7 @@
2626
27#include "UScreen.h"27#include "UScreen.h"
28#include "PanelView.h"28#include "PanelView.h"
29#include "PanelStyle.h"
2930
30namespace unity31namespace unity
31{32{
@@ -46,8 +47,8 @@
46 void FirstMenuShow();47 void FirstMenuShow();
47 void QueueRedraw();48 void QueueRedraw();
4849
49 unsigned int GetTrayXid();50 std::vector<Window> GetTrayXids() const;
50 std::list <nux::Geometry> GetGeometries();51 std::vector<nux::Geometry> GetGeometries() const;
5152
52 // NOTE: nux::Property maybe?53 // NOTE: nux::Property maybe?
53 void SetOpacity(float opacity);54 void SetOpacity(float opacity);
@@ -60,7 +61,7 @@
6061
61 void OnScreenChanged(int primary_monitor, std::vector<nux::Geometry>& monitors, Introspectable *iobj);62 void OnScreenChanged(int primary_monitor, std::vector<nux::Geometry>& monitors, Introspectable *iobj);
62private:63private:
63 unity::PanelView* ViewForWindow(nux::BaseWindow* window);64 unity::PanelView* ViewForWindow(nux::BaseWindow* window) const;
6465
65 static void WindowConfigureCallback(int window_width,66 static void WindowConfigureCallback(int window_width,
66 int window_height,67 int window_height,
@@ -98,17 +99,21 @@
98 }99 }
99}100}
100101
101unsigned int Controller::Impl::GetTrayXid()102std::vector<Window> Controller::Impl::GetTrayXids() const
102{103{
103 if (!windows_.empty())104 std::vector<Window> xids;
104 return ViewForWindow(windows_.front())->GetTrayXid();105
105 else106 for (auto window: windows_)
106 return 0;107 {
108 xids.push_back(ViewForWindow(window)->GetTrayXid());
109 }
110
111 return xids;
107}112}
108113
109std::list<nux::Geometry> Controller::Impl::GetGeometries()114std::vector<nux::Geometry> Controller::Impl::GetGeometries() const
110{115{
111 std::list<nux::Geometry> geometries;116 std::vector<nux::Geometry> geometries;
112117
113 for (auto window : windows_)118 for (auto window : windows_)
114 {119 {
@@ -171,7 +176,7 @@
171 }176 }
172}177}
173178
174PanelView* Controller::Impl::ViewForWindow(nux::BaseWindow* window)179PanelView* Controller::Impl::ViewForWindow(nux::BaseWindow* window) const
175{180{
176 nux::Layout* layout = window->GetLayout();181 nux::Layout* layout = window->GetLayout();
177 std::list<nux::Area*>::iterator it = layout->GetChildren().begin();182 std::list<nux::Area*>::iterator it = layout->GetChildren().begin();
@@ -198,8 +203,9 @@
198 (*it)->InputWindowEnableStruts(false);203 (*it)->InputWindowEnableStruts(false);
199204
200 nux::Geometry geo = monitors[i];205 nux::Geometry geo = monitors[i];
201 geo.height = 24;206 geo.height = panel::Style::Instance().panel_height;
202 (*it)->SetGeometry(geo);207 (*it)->SetGeometry(geo);
208 (*it)->SetMinMaxSize(geo.width, geo.height);
203209
204 view = ViewForWindow(*it);210 view = ViewForWindow(*it);
205 view->SetPrimary(i == primary_monitor);211 view->SetPrimary(i == primary_monitor);
@@ -224,7 +230,7 @@
224 nux::HLayout* layout = new nux::HLayout(NUX_TRACKER_LOCATION);230 nux::HLayout* layout = new nux::HLayout(NUX_TRACKER_LOCATION);
225231
226 PanelView* view = new PanelView();232 PanelView* view = new PanelView();
227 view->SetMaximumHeight(24);233 view->SetMaximumHeight(panel::Style::Instance().panel_height);
228 view->SetOpacity(opacity_);234 view->SetOpacity(opacity_);
229 view->SetOpacityMaximizedToggle(opacity_maximized_toggle_);235 view->SetOpacityMaximizedToggle(opacity_maximized_toggle_);
230 view->SetMenuShowTimings(menus_fadein_, menus_fadeout_, menus_discovery_,236 view->SetMenuShowTimings(menus_fadein_, menus_fadeout_, menus_discovery_,
@@ -238,17 +244,18 @@
238 layout->SetHorizontalExternalMargin(0);244 layout->SetHorizontalExternalMargin(0);
239245
240 nux::BaseWindow* window = new nux::BaseWindow("");246 nux::BaseWindow* window = new nux::BaseWindow("");
247 nux::Geometry geo = monitors[i];
248 geo.height = panel::Style::Instance().panel_height;
249
241 window->SinkReference();250 window->SinkReference();
242 window->SetConfigureNotifyCallback(&Impl::WindowConfigureCallback, window);251 window->SetConfigureNotifyCallback(&Impl::WindowConfigureCallback, window);
243 window->SetLayout(layout);
244 window->SetBackgroundColor(nux::Color(0.0f, 0.0f, 0.0f, 0.0f));252 window->SetBackgroundColor(nux::Color(0.0f, 0.0f, 0.0f, 0.0f));
245 window->ShowWindow(true);253 window->ShowWindow(true);
246 window->EnableInputWindow(true, "panel", false, false);254 window->EnableInputWindow(true, "panel", false, false);
247 window->InputWindowEnableStruts(true);255 window->InputWindowEnableStruts(true);
248
249 nux::Geometry geo = monitors[i];
250 geo.height = 24;
251 window->SetGeometry(geo);256 window->SetGeometry(geo);
257 window->SetMinMaxSize(geo.width, geo.height);
258 window->SetLayout(layout);
252259
253 windows_.push_back(window);260 windows_.push_back(window);
254261
@@ -325,12 +332,12 @@
325 pimpl->QueueRedraw();332 pimpl->QueueRedraw();
326}333}
327334
328unsigned int Controller::GetTrayXid()335std::vector<Window> Controller::GetTrayXids() const
329{336{
330 return pimpl->GetTrayXid();337 return pimpl->GetTrayXids();
331}338}
332339
333std::list<nux::Geometry> Controller::GetGeometries()340std::vector<nux::Geometry> Controller::GetGeometries() const
334{341{
335 return pimpl->GetGeometries();342 return pimpl->GetGeometries();
336}343}
337344
=== modified file 'plugins/unityshell/src/PanelController.h'
--- plugins/unityshell/src/PanelController.h 2012-03-22 19:33:10 +0000
+++ plugins/unityshell/src/PanelController.h 2012-04-05 23:42:20 +0000
@@ -20,9 +20,7 @@
20#ifndef _PANEL_CONTROLLER_H_20#ifndef _PANEL_CONTROLLER_H_
21#define _PANEL_CONTROLLER_H_21#define _PANEL_CONTROLLER_H_
2222
23#include <list>
24#include <memory>23#include <memory>
25
26#include <Nux/Nux.h>24#include <Nux/Nux.h>
2725
28#include "Introspectable.h"26#include "Introspectable.h"
@@ -42,8 +40,8 @@
42 void FirstMenuShow();40 void FirstMenuShow();
43 void QueueRedraw();41 void QueueRedraw();
4442
45 unsigned int GetTrayXid ();43 std::vector<Window> GetTrayXids() const;
46 std::list<nux::Geometry> GetGeometries ();44 std::vector<nux::Geometry> GetGeometries() const;
4745
48 // NOTE: nux::Property maybe?46 // NOTE: nux::Property maybe?
49 void SetOpacity(float opacity);47 void SetOpacity(float opacity);
5048
=== modified file 'plugins/unityshell/src/PanelIndicatorEntryView.cpp'
--- plugins/unityshell/src/PanelIndicatorEntryView.cpp 2012-04-03 03:40:06 +0000
+++ plugins/unityshell/src/PanelIndicatorEntryView.cpp 2012-04-05 23:42:20 +0000
@@ -1,6 +1,6 @@
1// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-1// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
2/*2/*
3 * Copyright (C) 2010 Canonical Ltd3 * Copyright (C) 2010-2012 Canonical Ltd
4 *4 *
5 * This program is free software: you can redistribute it and/or modify5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as6 * it under the terms of the GNU General Public License version 3 as
@@ -15,6 +15,7 @@
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *16 *
17 * Authored by: Neil Jagdish Patel <neil.patel@canonical.com>17 * Authored by: Neil Jagdish Patel <neil.patel@canonical.com>
18 * Marco Trevisan (Treviño) <3v1n0@ubuntu.com>
18 */19 */
1920
20#include <Nux/Nux.h>21#include <Nux/Nux.h>
@@ -24,22 +25,18 @@
24#include <NuxGraphics/GLThread.h>25#include <NuxGraphics/GLThread.h>
25#include <Nux/BaseWindow.h>26#include <Nux/BaseWindow.h>
26#include <Nux/WindowCompositor.h>27#include <Nux/WindowCompositor.h>
2728#include <UnityCore/Variant.h>
28#include <boost/algorithm/string.hpp>
2929
30#include <glib.h>30#include <glib.h>
31#include <pango/pangocairo.h>
32#include <gdk-pixbuf/gdk-pixbuf.h>31#include <gdk-pixbuf/gdk-pixbuf.h>
33#include <gtk/gtk.h>32#include <gtk/gtk.h>
34#include <time.h>33#include <time.h>
34#include <boost/algorithm/string.hpp>
3535
36#include "CairoTexture.h"36#include "CairoTexture.h"
37// TODO: this include should be at the top, but it fails :(
38#include "PanelIndicatorEntryView.h"37#include "PanelIndicatorEntryView.h"
39
40#include "PanelStyle.h"38#include "PanelStyle.h"
41#include <UnityCore/GLibWrapper.h>39#include "WindowManager.h"
42#include <UnityCore/Variant.h>
4340
4441
45namespace unity42namespace unity
@@ -47,52 +44,45 @@
4744
48namespace45namespace
49{46{
50void draw_menu_bg(cairo_t* cr, int width, int height);47const int DEFAULT_SPACING = 3;
51GdkPixbuf* make_pixbuf(int image_type, std::string const& image_data, bool dash_showing);
52const int PANEL_HEIGHT = 24;
53const int SPACING = 3;
54}48}
5549
50using namespace indicator;
5651
57PanelIndicatorEntryView::PanelIndicatorEntryView(52PanelIndicatorEntryView::PanelIndicatorEntryView(Entry::Ptr const& proxy, int padding,
58 indicator::Entry::Ptr const& proxy,53 IndicatorEntryType type)
59 int padding,
60 IndicatorEntryType type)
61 : TextureArea(NUX_TRACKER_LOCATION)54 : TextureArea(NUX_TRACKER_LOCATION)
62 , proxy_(proxy)55 , proxy_(proxy)
56 , spacing_(DEFAULT_SPACING)
57 , left_padding_(padding < 0 ? 0 : padding)
58 , right_padding_(left_padding_)
63 , type_(type)59 , type_(type)
64 , util_cg_(CAIRO_FORMAT_ARGB32, 1, 1)60 , entry_texture_(nullptr)
65 , texture_layer_(NULL)
66 , padding_(padding < 0 ? 0 : padding)
67 , opacity_(1.0f)61 , opacity_(1.0f)
68 , draw_active_(false)62 , draw_active_(false)
69 , dash_showing_(false)63 , overlay_showing_(false)
70 , disabled_(false)64 , disabled_(false)
65 , focused_(true)
71{66{
72 on_indicator_activate_changed_connection_ = proxy_->active_changed.connect(sigc::mem_fun(this, &PanelIndicatorEntryView::OnActiveChanged));67 proxy_->active_changed.connect(sigc::mem_fun(this, &PanelIndicatorEntryView::OnActiveChanged));
73 on_indicator_updated_connection_ = proxy_->updated.connect(sigc::mem_fun(this, &PanelIndicatorEntryView::Refresh));68 proxy_->updated.connect(sigc::mem_fun(this, &PanelIndicatorEntryView::Refresh));
74
75 on_font_changed_connection_ = g_signal_connect(gtk_settings_get_default(), "notify::gtk-font-name", (GCallback) &PanelIndicatorEntryView::OnFontChanged, this);
7669
77 InputArea::mouse_down.connect(sigc::mem_fun(this, &PanelIndicatorEntryView::OnMouseDown));70 InputArea::mouse_down.connect(sigc::mem_fun(this, &PanelIndicatorEntryView::OnMouseDown));
78 InputArea::mouse_up.connect(sigc::mem_fun(this, &PanelIndicatorEntryView::OnMouseUp));71 InputArea::mouse_up.connect(sigc::mem_fun(this, &PanelIndicatorEntryView::OnMouseUp));
7972
80 InputArea::SetAcceptMouseWheelEvent(true);73 InputArea::SetAcceptMouseWheelEvent(true);
74
81 if (type_ != MENU)75 if (type_ != MENU)
82 InputArea::mouse_wheel.connect(sigc::mem_fun(this, &PanelIndicatorEntryView::OnMouseWheel));76 InputArea::mouse_wheel.connect(sigc::mem_fun(this, &PanelIndicatorEntryView::OnMouseWheel));
8377
84 on_panelstyle_changed_connection_ = panel::Style::Instance().changed.connect(sigc::mem_fun(this, &PanelIndicatorEntryView::Refresh));78 panel::Style::Instance().changed.connect(sigc::mem_fun(this, &PanelIndicatorEntryView::Refresh));
79
85 Refresh();80 Refresh();
86}81}
8782
88PanelIndicatorEntryView::~PanelIndicatorEntryView()83PanelIndicatorEntryView::~PanelIndicatorEntryView()
89{84{
90 on_indicator_activate_changed_connection_.disconnect();85 // Nothing to do...
91 on_indicator_updated_connection_.disconnect();
92 on_panelstyle_changed_connection_.disconnect();
93 g_signal_handler_disconnect(gtk_settings_get_default(), on_font_changed_connection_);
94 if (texture_layer_)
95 delete texture_layer_;
96}86}
9787
98void PanelIndicatorEntryView::OnActiveChanged(bool is_active)88void PanelIndicatorEntryView::OnActiveChanged(bool is_active)
@@ -108,10 +98,15 @@
10898
109void PanelIndicatorEntryView::ShowMenu(int button)99void PanelIndicatorEntryView::ShowMenu(int button)
110{100{
111 proxy_->ShowMenu(GetAbsoluteX(),101 auto wm = WindowManager::Default();
112 GetAbsoluteY() + PANEL_HEIGHT,102
113 button,103 if (!wm->IsExpoActive() && !wm->IsScaleActive())
114 time(NULL));104 {
105 proxy_->ShowMenu(GetAbsoluteX(),
106 GetAbsoluteY() + panel::Style::Instance().panel_height,
107 button,
108 time(nullptr));
109 }
115}110}
116111
117void PanelIndicatorEntryView::OnMouseDown(int x, int y, long button_flags, long key_flags)112void PanelIndicatorEntryView::OnMouseDown(int x, int y, long button_flags, long key_flags)
@@ -119,8 +114,8 @@
119 if (proxy_->active() || IsDisabled())114 if (proxy_->active() || IsDisabled())
120 return;115 return;
121116
122 if (((proxy_->label_visible() && proxy_->label_sensitive()) ||117 if (((IsLabelVisible() && IsLabelSensitive()) ||
123 (proxy_->image_visible() && proxy_->image_sensitive())))118 (IsIconVisible() && IsIconSensitive())))
124 {119 {
125 int button = nux::GetEventButton(button_flags);120 int button = nux::GetEventButton(button_flags);
126121
@@ -144,12 +139,12 @@
144 int px = geo.x + x;139 int px = geo.x + x;
145 int py = geo.y + y;140 int py = geo.y + y;
146141
147 if (((proxy_->label_visible() && proxy_->label_sensitive()) ||142 if (((IsLabelVisible() && IsLabelSensitive()) ||
148 (proxy_->image_visible() && proxy_->image_sensitive())) &&143 (IsIconVisible() && IsIconSensitive())) &&
149 button == 2 && type_ == INDICATOR)144 button == 2 && type_ == INDICATOR)
150 {145 {
151 if (geo.IsPointInside(px, py))146 if (geo.IsPointInside(px, py))
152 proxy_->SecondaryActivate(time(NULL));147 proxy_->SecondaryActivate(time(nullptr));
153148
154 SetOpacity(1.0f);149 SetOpacity(1.0f);
155 }150 }
@@ -187,78 +182,290 @@
187 }182 }
188}183}
189184
185glib::Object<GdkPixbuf> PanelIndicatorEntryView::MakePixbuf()
186{
187 glib::Object<GdkPixbuf> pixbuf;
188 GtkIconTheme* theme = gtk_icon_theme_get_default();
189 int image_type = proxy_->image_type();
190
191 if (image_type == GTK_IMAGE_PIXBUF)
192 {
193 gsize len = 0;
194 guchar* decoded = g_base64_decode(proxy_->image_data().c_str(), &len);
195
196 glib::Object<GInputStream> stream(g_memory_input_stream_new_from_data(decoded,
197 len,
198 nullptr));
199
200 pixbuf = gdk_pixbuf_new_from_stream(stream, nullptr, nullptr);
201
202 g_free(decoded);
203 g_input_stream_close(stream, nullptr, nullptr);
204 }
205 else if (image_type == GTK_IMAGE_STOCK ||
206 image_type == GTK_IMAGE_ICON_NAME)
207 {
208 pixbuf = gtk_icon_theme_load_icon(theme, proxy_->image_data().c_str(), 22,
209 (GtkIconLookupFlags)0, nullptr);
210 }
211 else if (image_type == GTK_IMAGE_GICON)
212 {
213 glib::Object<GIcon> icon(g_icon_new_for_string(proxy_->image_data().c_str(), nullptr));
214
215 GtkIconInfo* info = gtk_icon_theme_lookup_by_gicon(theme, icon, 22,
216 (GtkIconLookupFlags)0);
217 if (info)
218 {
219 pixbuf = gtk_icon_info_load_icon(info, nullptr);
220 gtk_icon_info_free(info);
221 }
222 }
223
224 return pixbuf;
225}
226
227void PanelIndicatorEntryView::DrawEntryPrelight(cairo_t* cr, unsigned int width, unsigned int height)
228{
229 GtkStyleContext* style_context = panel::Style::Instance().GetStyleContext();
230
231 gtk_style_context_save(style_context);
232
233 GtkWidgetPath* widget_path = gtk_widget_path_new();
234 gtk_widget_path_append_type(widget_path, GTK_TYPE_MENU_BAR);
235 gtk_widget_path_append_type(widget_path, GTK_TYPE_MENU_ITEM);
236 gtk_widget_path_iter_set_name(widget_path, -1 , "UnityPanelWidget");
237
238 gtk_style_context_set_path(style_context, widget_path);
239 gtk_style_context_add_class(style_context, GTK_STYLE_CLASS_MENUBAR);
240 gtk_style_context_add_class(style_context, GTK_STYLE_CLASS_MENUITEM);
241 gtk_style_context_set_state(style_context, GTK_STATE_FLAG_PRELIGHT);
242
243 gtk_render_background(style_context, cr, 0, 0, width, height);
244 gtk_render_frame(style_context, cr, 0, 0, width, height);
245
246 gtk_widget_path_free(widget_path);
247
248 gtk_style_context_restore(style_context);
249}
250
251void PanelIndicatorEntryView::DrawEntryContent(cairo_t *cr, unsigned int width, unsigned int height, glib::Object<GdkPixbuf> const& pixbuf, glib::Object<PangoLayout> const& layout)
252{
253 int x = left_padding_;
254
255 if (IsActive())
256 DrawEntryPrelight(cr, width, height);
257
258 if (pixbuf && IsIconVisible())
259 {
260 GtkStyleContext* style_context = panel::Style::Instance().GetStyleContext();
261 unsigned int icon_width = gdk_pixbuf_get_width(pixbuf);
262
263 gtk_style_context_save(style_context);
264
265 GtkWidgetPath* widget_path = gtk_widget_path_new();
266 gint pos = gtk_widget_path_append_type(widget_path, GTK_TYPE_MENU_BAR);
267 pos = gtk_widget_path_append_type(widget_path, GTK_TYPE_MENU_ITEM);
268 gtk_widget_path_iter_set_name(widget_path, pos, "UnityPanelWidget");
269
270 gtk_style_context_set_path(style_context, widget_path);
271 gtk_style_context_add_class(style_context, GTK_STYLE_CLASS_MENUBAR);
272 gtk_style_context_add_class(style_context, GTK_STYLE_CLASS_MENUITEM);
273
274 if (!IsFocused())
275 {
276 gtk_style_context_set_state(style_context, GTK_STATE_FLAG_BACKDROP);
277 }
278 else if (IsActive())
279 {
280 gtk_style_context_set_state(style_context, GTK_STATE_FLAG_PRELIGHT);
281 }
282
283 int y = (int)((height - gdk_pixbuf_get_height(pixbuf)) / 2);
284 if (overlay_showing_ && !IsActive())
285 {
286 /* Most of the images we get are straight pixbufs (annoyingly), so when
287 * the Overlay opens, we use the pixbuf as a mask to punch out an icon from
288 * a white square. It works surprisingly well for most symbolic-type
289 * icon themes/icons.
290 */
291 cairo_save(cr);
292
293 cairo_push_group(cr);
294 gdk_cairo_set_source_pixbuf(cr, pixbuf, x, y);
295 cairo_paint_with_alpha(cr, (IsIconSensitive() && IsFocused()) ? 1.0 : 0.5);
296
297 cairo_pattern_t* pat = cairo_pop_group(cr);
298
299 cairo_set_source_rgba(cr, 1.0f, 1.0f, 1.0f, 1.0f);
300 cairo_rectangle(cr, x, y, width, height);
301 cairo_mask(cr, pat);
302
303 cairo_pattern_destroy(pat);
304 cairo_restore(cr);
305 }
306 else
307 {
308 cairo_push_group(cr);
309 gtk_render_icon(style_context, cr, pixbuf, x, y);
310 cairo_pop_group_to_source(cr);
311 cairo_paint_with_alpha(cr, (IsIconSensitive() && IsFocused()) ? 1.0 : 0.5);
312 }
313
314 gtk_widget_path_free(widget_path);
315
316 gtk_style_context_restore(style_context);
317
318 x += icon_width + spacing_;
319 }
320
321 if (layout)
322 {
323 PangoRectangle log_rect;
324 pango_layout_get_extents(layout, nullptr, &log_rect);
325 unsigned int text_height = log_rect.height / PANGO_SCALE;
326 unsigned int text_width = log_rect.width / PANGO_SCALE;
327
328 pango_cairo_update_layout(cr, layout);
329
330 GtkStyleContext* style_context = panel::Style::Instance().GetStyleContext();
331
332 gtk_style_context_save(style_context);
333
334 GtkWidgetPath* widget_path = gtk_widget_path_new();
335 gint pos = gtk_widget_path_append_type(widget_path, GTK_TYPE_MENU_BAR);
336 pos = gtk_widget_path_append_type(widget_path, GTK_TYPE_MENU_ITEM);
337 gtk_widget_path_iter_set_name(widget_path, pos, "UnityPanelWidget");
338
339 gtk_style_context_set_path(style_context, widget_path);
340 gtk_style_context_add_class(style_context, GTK_STYLE_CLASS_MENUBAR);
341 gtk_style_context_add_class(style_context, GTK_STYLE_CLASS_MENUITEM);
342
343 if (!IsFocused())
344 {
345 gtk_style_context_set_state(style_context, GTK_STATE_FLAG_BACKDROP);
346 }
347 else if (IsActive())
348 {
349 gtk_style_context_set_state(style_context, GTK_STATE_FLAG_PRELIGHT);
350 }
351
352 int y = (height - text_height) / 2;
353
354
355 unsigned int text_space = GetMaximumWidth() - x - right_padding_;
356
357 if (text_width > text_space)
358 {
359 cairo_pattern_t* linpat;
360 int out_pixels = text_width - text_space;
361 const int fading_pixels = 15;
362
363 int fading_width = out_pixels < fading_pixels ? out_pixels : fading_pixels;
364
365 cairo_push_group(cr);
366 if (overlay_showing_)
367 {
368 cairo_move_to(cr, x, y);
369 cairo_set_source_rgb(cr, 1.0f, 1.0f, 1.0f);
370 pango_cairo_show_layout(cr, layout);
371 }
372 else
373 {
374 gtk_render_layout(style_context, cr, x, y, layout);
375 }
376 cairo_pop_group_to_source(cr);
377
378 int right_margin = width - right_padding_;
379 linpat = cairo_pattern_create_linear(right_margin - fading_width, y, right_margin, y);
380 cairo_pattern_add_color_stop_rgba(linpat, 0, 0, 0, 0, 1);
381 cairo_pattern_add_color_stop_rgba(linpat, 1, 0, 0, 0, 0);
382 cairo_mask(cr, linpat);
383 cairo_pattern_destroy(linpat);
384 }
385 else
386 {
387 if (overlay_showing_)
388 {
389 cairo_move_to(cr, x, y);
390 cairo_set_source_rgb(cr, 1.0f, 1.0f, 1.0f);
391 pango_cairo_show_layout(cr, layout);
392 }
393 else
394 {
395 gtk_render_layout(style_context, cr, x, y, layout);
396 }
397 }
398
399 gtk_widget_path_free(widget_path);
400 gtk_style_context_restore(style_context);
401 }
402}
403
190// We need to do a couple of things here:404// We need to do a couple of things here:
191// 1. Figure out our width405// 1. Figure out our width
192// 2. Figure out if we're active406// 2. Figure out if we're active
193// 3. Paint something407// 3. Paint something
194void PanelIndicatorEntryView::Refresh()408void PanelIndicatorEntryView::Refresh()
195{409{
196 if (!IsVisible())410 if (!proxy_->visible())
197 {411 {
198 SetVisible(false);412 SetVisible(false);
413 // This will destroy the object texture. No need to manually delete the pointer
414 entry_texture_ = nullptr;
415 SetColor(nux::color::Transparent);
416
417 QueueDraw();
418 refreshed.emit(this);
419
199 return;420 return;
200 }421 }
201422
202 SetVisible(true);423 glib::Object<PangoLayout> layout;
203424 cairo_t* cr;
204 PangoLayout* layout = NULL;425
205 PangoFontDescription* desc = NULL;426 std::string label = GetLabel();
206 PangoAttrList* attrs = NULL;427 glib::Object<GdkPixbuf> const& pixbuf = MakePixbuf();
207 GtkSettings* settings = gtk_settings_get_default();428
208 cairo_t* cr;429 unsigned int width = 0;
209 char* font_description = NULL;430 unsigned int icon_width = 0;
210 GdkScreen* screen = gdk_screen_get_default();431 unsigned int height = panel::Style::Instance().panel_height;
211 int dpi = 0;432 unsigned int text_width = 0;
212
213 std::string label = proxy_->label();
214 glib::Object<GdkPixbuf> pixbuf(make_pixbuf(proxy_->image_type(),
215 proxy_->image_data(),
216 dash_showing_));
217
218
219 int x = 0;
220 int width = 0;
221 int height = PANEL_HEIGHT;
222 int icon_width = 0;
223 int text_width = 0;
224 int text_height = 0;
225
226 if (proxy_->show_now())
227 {
228 if (!pango_parse_markup(label.c_str(),
229 -1,
230 '_',
231 &attrs,
232 NULL,
233 NULL,
234 NULL))
235 {
236 g_debug("pango_parse_markup failed");
237 }
238 }
239 boost::erase_all(label, "_");
240433
241 // First lets figure out our size434 // First lets figure out our size
242 if (pixbuf && proxy_->image_visible())435 if (pixbuf && IsIconVisible())
243 {436 {
244 width = gdk_pixbuf_get_width(pixbuf);437 width = gdk_pixbuf_get_width(pixbuf);
245 icon_width = width;438 icon_width = width;
246 }439 }
247440
248 if (!label.empty() && proxy_->label_visible())441 if (!label.empty() && IsLabelVisible())
249 {442 {
443 using namespace panel;
250 PangoContext* cxt;444 PangoContext* cxt;
445 PangoAttrList* attrs = nullptr;
251 PangoRectangle log_rect;446 PangoRectangle log_rect;
252447 GdkScreen* screen = gdk_screen_get_default();
253 cr = util_cg_.GetContext();448 PangoFontDescription* desc = nullptr;
254449 PanelItem panel_item = (type_ == MENU) ? PanelItem::MENU : PanelItem::INDICATOR;
255 g_object_get(settings,450
256 "gtk-font-name", &font_description,451 Style& panel_style = Style::Instance();
257 "gtk-xft-dpi", &dpi,452 std::string const& font_description = panel_style.GetFontDescription(panel_item);
258 NULL);453 int dpi = panel_style.GetTextDPI();
259 desc = pango_font_description_from_string(font_description);454
455 if (proxy_->show_now())
456 {
457 if (!pango_parse_markup(label.c_str(), -1, '_', &attrs, nullptr, nullptr, nullptr))
458 {
459 g_debug("pango_parse_markup failed");
460 }
461 }
462
463 desc = pango_font_description_from_string(font_description.c_str());
260 pango_font_description_set_weight(desc, PANGO_WEIGHT_NORMAL);464 pango_font_description_set_weight(desc, PANGO_WEIGHT_NORMAL);
261465
466 nux::CairoGraphics cairo_graphics(CAIRO_FORMAT_ARGB32, 1, 1);
467 cr = cairo_graphics.GetContext();
468
262 layout = pango_cairo_create_layout(cr);469 layout = pango_cairo_create_layout(cr);
263 if (attrs)470 if (attrs)
264 {471 {
@@ -267,198 +474,90 @@
267 }474 }
268475
269 pango_layout_set_font_description(layout, desc);476 pango_layout_set_font_description(layout, desc);
477
478 boost::erase_all(label, "_");
270 pango_layout_set_text(layout, label.c_str(), -1);479 pango_layout_set_text(layout, label.c_str(), -1);
271480
272 cxt = pango_layout_get_context(layout);481 cxt = pango_layout_get_context(layout);
273 pango_cairo_context_set_font_options(cxt, gdk_screen_get_font_options(screen));482 pango_cairo_context_set_font_options(cxt, gdk_screen_get_font_options(screen));
274 pango_cairo_context_set_resolution(cxt, (float)dpi / (float)PANGO_SCALE);483 pango_cairo_context_set_resolution(cxt, dpi / static_cast<float>(PANGO_SCALE));
275 pango_layout_context_changed(layout);484 pango_layout_context_changed(layout);
276485
277 pango_layout_get_extents(layout, NULL, &log_rect);486 pango_layout_get_extents(layout, nullptr, &log_rect);
278 text_width = log_rect.width / PANGO_SCALE;487 text_width = log_rect.width / PANGO_SCALE;
279 text_height = log_rect.height / PANGO_SCALE;
280488
281 if (icon_width)489 if (icon_width)
282 width += SPACING;490 width += spacing_;
283 width += text_width;491 width += text_width;
284492
285 pango_font_description_free(desc);493 pango_font_description_free(desc);
286 g_free(font_description);
287 cairo_destroy(cr);494 cairo_destroy(cr);
288 }495 }
289496
290 if (width)497 if (width)
291 width += padding_ * 2;498 width += left_padding_ + right_padding_;
292499
500 width = std::min<int>(width, GetMaximumWidth());
293 SetMinimumWidth(width);501 SetMinimumWidth(width);
294502
295 nux::CairoGraphics cairo_graphics(CAIRO_FORMAT_ARGB32, width, height);503 nux::CairoGraphics cg(CAIRO_FORMAT_ARGB32, width, height);
296 cr = cairo_graphics.GetContext();504 cr = cg.GetContext();
297 cairo_set_line_width(cr, 1);505 cairo_set_line_width(cr, 1);
298
299 cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);506 cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);
300 cairo_paint(cr);507 cairo_paint(cr);
301508
302 cairo_set_operator(cr, CAIRO_OPERATOR_OVER);509 cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
303510 DrawEntryContent(cr, width, height, pixbuf, layout);
304 if (IsActive())511
305 draw_menu_bg(cr, width, height);512 entry_texture_ = texture_from_cairo_graphics(cg);
306513 SetTexture(entry_texture_);
307 x = padding_;
308
309 if (pixbuf && proxy_->image_visible())
310 {
311 GtkStyleContext* style_context = panel::Style::Instance().GetStyleContext();
312
313 gtk_style_context_save(style_context);
314
315 GtkWidgetPath* widget_path = gtk_widget_path_new();
316 gint pos = gtk_widget_path_append_type(widget_path, GTK_TYPE_MENU_BAR);
317 pos = gtk_widget_path_append_type(widget_path, GTK_TYPE_MENU_ITEM);
318 gtk_widget_path_iter_set_name(widget_path, pos, "UnityPanelWidget");
319
320 gtk_style_context_set_path(style_context, widget_path);
321 gtk_style_context_add_class(style_context, GTK_STYLE_CLASS_MENUBAR);
322 gtk_style_context_add_class(style_context, GTK_STYLE_CLASS_MENUITEM);
323
324 if (IsActive())
325 gtk_style_context_set_state(style_context, GTK_STATE_FLAG_PRELIGHT);
326
327 int y = (int)((height - gdk_pixbuf_get_height(pixbuf)) / 2);
328 if (dash_showing_ && !IsActive())
329 {
330 /* Most of the images we get are straight pixbufs (annoyingly), so when
331 * the Dash opens, we use the pixbuf as a mask to punch out an icon from
332 * a white square. It works surprisingly well for most symbolic-type
333 * icon themes/icons.
334 */
335 cairo_save(cr);
336
337 cairo_push_group(cr);
338 gdk_cairo_set_source_pixbuf(cr, pixbuf, x, y);
339 cairo_paint_with_alpha(cr, proxy_->image_sensitive() ? 1.0 : 0.5);
340
341 cairo_pattern_t* pat = cairo_pop_group(cr);
342
343 cairo_set_source_rgba(cr, 1.0f, 1.0f, 1.0f, 1.0f);
344 cairo_rectangle(cr, x, y, width, height);
345 cairo_mask(cr, pat);
346
347 cairo_pattern_destroy(pat);
348 cairo_restore(cr);
349 }
350 else
351 {
352 cairo_push_group(cr);
353 gtk_render_icon(style_context, cr, pixbuf, x, y);
354 cairo_pop_group_to_source(cr);
355 cairo_paint_with_alpha(cr, proxy_->image_sensitive() ? 1.0 : 0.5);
356 }
357
358 gtk_widget_path_free(widget_path);
359
360 gtk_style_context_restore(style_context);
361
362 x += icon_width + SPACING;
363 }
364
365 if (!label.empty() && proxy_->label_visible())
366 {
367 pango_cairo_update_layout(cr, layout);
368
369 GtkStyleContext* style_context = panel::Style::Instance().GetStyleContext();
370
371 gtk_style_context_save(style_context);
372
373 GtkWidgetPath* widget_path = gtk_widget_path_new();
374 gint pos = gtk_widget_path_append_type(widget_path, GTK_TYPE_MENU_BAR);
375 pos = gtk_widget_path_append_type(widget_path, GTK_TYPE_MENU_ITEM);
376 gtk_widget_path_iter_set_name(widget_path, pos, "UnityPanelWidget");
377
378 gtk_style_context_set_path(style_context, widget_path);
379 gtk_style_context_add_class(style_context, GTK_STYLE_CLASS_MENUBAR);
380 gtk_style_context_add_class(style_context, GTK_STYLE_CLASS_MENUITEM);
381
382 if (IsActive())
383 gtk_style_context_set_state(style_context, GTK_STATE_FLAG_PRELIGHT);
384
385 int y = (int)((height - text_height) / 2);
386 if (dash_showing_)
387 {
388 cairo_move_to(cr, x, y);
389 cairo_set_source_rgb(cr, 1.0f, 1.0f, 1.0f);
390 pango_cairo_show_layout(cr, layout);
391 }
392 else
393 {
394 gtk_render_layout(style_context, cr, x, y, layout);
395 }
396
397 gtk_widget_path_free(widget_path);
398
399 gtk_style_context_restore(style_context);
400 }
401
402 cairo_destroy(cr);514 cairo_destroy(cr);
403 if (layout)515
404 g_object_unref(layout);516 SetVisible(true);
405
406 nux::BaseTexture* texture2D = texture_from_cairo_graphics(cairo_graphics);
407
408 nux::TexCoordXForm texxform;
409 texxform.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD);
410 texxform.SetWrap(nux::TEXWRAP_REPEAT, nux::TEXWRAP_REPEAT);
411
412 nux::ROPConfig rop;
413 rop.Blend = true;
414 rop.SrcBlend = GL_ONE;
415 rop.DstBlend = GL_ONE_MINUS_SRC_ALPHA;
416
417 if (texture_layer_)
418 delete texture_layer_;
419
420 texture_layer_ = new nux::TextureLayer(texture2D->GetDeviceTexture(), texxform,
421 nux::color::White, true, rop);
422 SetPaintLayer(texture_layer_);
423
424 texture2D->UnReference();
425
426 NeedRedraw();
427
428 refreshed.emit(this);517 refreshed.emit(this);
518 QueueDraw();
429}519}
430520
431void PanelIndicatorEntryView::Draw(nux::GraphicsEngine& GfxContext, bool force_draw)521void PanelIndicatorEntryView::Draw(nux::GraphicsEngine& GfxContext, bool force_draw)
432{522{
433 if (opacity_ == 1.0f)523 nux::Geometry const& geo = GetGeometry();
434 {
435 TextureArea::Draw(GfxContext, force_draw);
436 return;
437 }
438
439 auto geo = GetGeometry();
440 GfxContext.PushClippingRectangle(geo);524 GfxContext.PushClippingRectangle(geo);
441525
442 if (texture_layer_)526 if (cached_geo_ != geo)
443 {527 {
528 Refresh();
529 cached_geo_ = geo;
530 }
531
532 if (entry_texture_ && opacity_ > 0.0f)
533 {
534 /* "Clear" out the background */
535 nux::ROPConfig rop;
536 rop.Blend = true;
537 rop.SrcBlend = GL_ONE;
538 rop.DstBlend = GL_ONE_MINUS_SRC_ALPHA;
539
540 nux::ColorLayer layer(nux::color::Transparent, true, rop);
541 nux::GetPainter().PushDrawLayer(GfxContext, geo, &layer);
542
444 nux::TexCoordXForm texxform;543 nux::TexCoordXForm texxform;
445 GfxContext.QRP_1Tex(geo.x, geo.y, geo.width, geo.height,544 GfxContext.QRP_1Tex(geo.x, geo.y, geo.width, geo.height,
446 texture_layer_->GetDeviceTexture(), texxform,545 entry_texture_->GetDeviceTexture(), texxform,
447 nux::color::White * opacity_);546 nux::color::White * opacity_);
448 }547 }
449548
450 GfxContext.PopClippingRectangle();549 GfxContext.PopClippingRectangle();
451}550}
452551
453void PanelIndicatorEntryView::DashShown()552void PanelIndicatorEntryView::OverlayShown()
454{553{
455 dash_showing_ = true;554 overlay_showing_ = true;
456 Refresh();555 Refresh();
457}556}
458557
459void PanelIndicatorEntryView::DashHidden()558void PanelIndicatorEntryView::OverlayHidden()
460{559{
461 dash_showing_ = false;560 overlay_showing_ = false;
462 Refresh();561 Refresh();
463}562}
464563
@@ -478,60 +577,131 @@
478 return opacity_;577 return opacity_;
479}578}
480579
580PanelIndicatorEntryView::IndicatorEntryType PanelIndicatorEntryView::GetType() const
581{
582 return type_;
583}
584
585std::string PanelIndicatorEntryView::GetLabel() const
586{
587 if (proxy_.get())
588 {
589 return proxy_->label();
590 }
591
592 return "";
593}
594
595bool PanelIndicatorEntryView::IsLabelVisible() const
596{
597 if (proxy_.get())
598 {
599 return proxy_->label_visible();
600 }
601
602 return false;
603}
604
605bool PanelIndicatorEntryView::IsLabelSensitive() const
606{
607 if (proxy_.get())
608 {
609 return proxy_->label_sensitive();
610 }
611
612 return false;
613}
614
615bool PanelIndicatorEntryView::IsIconVisible() const
616{
617 if (proxy_.get())
618 {
619 return proxy_->image_visible();
620 }
621
622 return false;
623}
624
625bool PanelIndicatorEntryView::IsIconSensitive() const
626{
627 if (proxy_.get())
628 {
629 return proxy_->image_sensitive();
630 }
631
632 return false;
633}
634
481std::string PanelIndicatorEntryView::GetName() const635std::string PanelIndicatorEntryView::GetName() const
482{636{
483 return proxy_->id();637 return "IndicatorEntry";
484}638}
485639
486void PanelIndicatorEntryView::AddProperties(GVariantBuilder* builder)640void PanelIndicatorEntryView::AddProperties(GVariantBuilder* builder)
487{641{
488 variant::BuilderWrapper(builder)642 variant::BuilderWrapper(builder)
489 .add(GetGeometry())643 .add(GetGeometry())
490 .add("label", proxy_->label())644 .add("id", GetEntryID())
491 .add("label_sensitive", proxy_->label_sensitive())645 .add("name_hint", proxy_->name_hint())
492 .add("label_visible", proxy_->label_visible())646 .add("type", GetType())
493 .add("icon_sensitive", proxy_->image_sensitive())647 .add("label", GetLabel())
494 .add("icon_visible", proxy_->image_visible())648 .add("label_sensitive", IsLabelSensitive())
649 .add("label_visible", IsLabelVisible())
650 .add("icon_sensitive", IsIconSensitive())
651 .add("icon_visible", IsIconVisible())
652 .add("entry_visible", IsVisible())
495 .add("active", proxy_->active())653 .add("active", proxy_->active())
496 .add("priority", proxy_->priority());654 .add("priority", proxy_->priority())
655 .add("focused", IsFocused());
497}656}
498657
499bool PanelIndicatorEntryView::GetShowNow()658bool PanelIndicatorEntryView::GetShowNow() const
500{659{
501 return proxy_.get() ? proxy_->show_now() : false;660 return proxy_.get() ? proxy_->show_now() : false;
502}661}
503662
504void PanelIndicatorEntryView::GetGeometryForSync(indicator::EntryLocationMap& locations)663void PanelIndicatorEntryView::GetGeometryForSync(EntryLocationMap& locations)
505{664{
506 if (!IsVisible())665 if (!IsVisible())
507 return;666 return;
508667
509 locations[proxy_->id()] = GetAbsoluteGeometry();668 locations[GetEntryID()] = GetAbsoluteGeometry();
510}
511
512bool PanelIndicatorEntryView::IsEntryValid() const
513{
514 if (proxy_.get())
515 {
516 return proxy_->image_visible() || proxy_->label_visible();
517 }
518 return false;
519}669}
520670
521bool PanelIndicatorEntryView::IsSensitive() const671bool PanelIndicatorEntryView::IsSensitive() const
522{672{
523 if (proxy_.get())673 if (proxy_.get())
524 {674 {
525 return proxy_->image_sensitive() || proxy_->label_sensitive();675 return IsIconSensitive() || IsLabelSensitive();
526 }676 }
527 return false;677 return false;
528}678}
529679
680bool PanelIndicatorEntryView::IsVisible()
681{
682 if (proxy_.get())
683 {
684 return TextureArea::IsVisible() && proxy_->visible();
685 }
686
687 return TextureArea::IsVisible();
688}
689
530bool PanelIndicatorEntryView::IsActive() const690bool PanelIndicatorEntryView::IsActive() const
531{691{
532 return draw_active_;692 return draw_active_;
533}693}
534694
695std::string PanelIndicatorEntryView::GetEntryID() const
696{
697 if (proxy_.get())
698 {
699 return proxy_->id();
700 }
701
702 return "";
703}
704
535int PanelIndicatorEntryView::GetEntryPriority() const705int PanelIndicatorEntryView::GetEntryPriority() const
536{706{
537 if (proxy_.get())707 if (proxy_.get())
@@ -551,95 +721,18 @@
551 return (disabled_ || !proxy_.get() || !IsSensitive());721 return (disabled_ || !proxy_.get() || !IsSensitive());
552}722}
553723
554bool PanelIndicatorEntryView::IsVisible()724void PanelIndicatorEntryView::SetFocusedState(bool focused)
555{725{
556 if (proxy_.get())726 if (focused_ != focused)
557 {727 {
558 return proxy_->visible();728 focused_ = focused;
559 }729 Refresh();
560 return false;730 }
561}731}
562732
563void PanelIndicatorEntryView::OnFontChanged(GObject* gobject, GParamSpec* pspec,733bool PanelIndicatorEntryView::IsFocused() const
564 gpointer data)734{
565{735 return focused_;
566 PanelIndicatorEntryView* self = reinterpret_cast<PanelIndicatorEntryView*>(data);736}
567 self->Refresh();
568}
569
570namespace
571{
572
573void draw_menu_bg(cairo_t* cr, int width, int height)
574{
575 GtkStyleContext* style_context = panel::Style::Instance().GetStyleContext();
576
577 gtk_style_context_save(style_context);
578
579 GtkWidgetPath* widget_path = gtk_widget_path_new();
580 gint pos = gtk_widget_path_append_type(widget_path, GTK_TYPE_WINDOW);
581 gtk_widget_path_iter_set_name(widget_path, pos, "UnityPanelWidget");
582 gtk_widget_path_append_type(widget_path, GTK_TYPE_MENU_BAR);
583 gtk_widget_path_append_type(widget_path, GTK_TYPE_MENU_ITEM);
584
585 gtk_style_context_set_path(style_context, widget_path);
586 gtk_style_context_add_class(style_context, GTK_STYLE_CLASS_MENUBAR);
587 gtk_style_context_add_class(style_context, GTK_STYLE_CLASS_MENUITEM);
588 gtk_style_context_set_state(style_context, GTK_STATE_FLAG_PRELIGHT);
589
590 gtk_render_background(style_context, cr, 0, 0, width, height);
591 gtk_render_frame(style_context, cr, 0, 0, width, height);
592
593 gtk_widget_path_free(widget_path);
594
595 gtk_style_context_restore(style_context);
596}
597
598GdkPixbuf* make_pixbuf(int image_type, std::string const& image_data, bool dash_showing)
599{
600 GdkPixbuf* ret = NULL;
601 GtkIconTheme* theme = gtk_icon_theme_get_default();
602
603 if (image_type == GTK_IMAGE_PIXBUF)
604 {
605 gsize len = 0;
606 guchar* decoded = g_base64_decode(image_data.c_str(), &len);
607
608 GInputStream* stream = g_memory_input_stream_new_from_data(decoded,
609 len, NULL);
610
611 ret = gdk_pixbuf_new_from_stream(stream, NULL, NULL);
612
613 g_free(decoded);
614 g_input_stream_close(stream, NULL, NULL);
615 g_object_unref(stream);
616 }
617 else if (image_type == GTK_IMAGE_STOCK ||
618 image_type == GTK_IMAGE_ICON_NAME)
619 {
620 ret = gtk_icon_theme_load_icon(theme,
621 image_data.c_str(),
622 22,
623 (GtkIconLookupFlags)0,
624 NULL);
625 }
626 else if (image_type == GTK_IMAGE_GICON)
627 {
628 glib::Object<GIcon> icon(g_icon_new_for_string(image_data.c_str(), NULL));
629
630 GtkIconInfo* info = gtk_icon_theme_lookup_by_gicon(
631 theme, icon, 22, (GtkIconLookupFlags)0);
632 if (info)
633 {
634 ret = gtk_icon_info_load_icon(info, NULL);
635 gtk_icon_info_free(info);
636 }
637 }
638
639 return ret;
640}
641
642} // anon namespace
643
644737
645} // namespace unity738} // namespace unity
646739
=== modified file 'plugins/unityshell/src/PanelIndicatorEntryView.h'
--- plugins/unityshell/src/PanelIndicatorEntryView.h 2012-03-21 12:31:11 +0000
+++ plugins/unityshell/src/PanelIndicatorEntryView.h 2012-04-05 23:42:20 +0000
@@ -1,6 +1,6 @@
1// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-1// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
2/*2/*
3 * Copyright (C) 2010 Canonical Ltd3 * Copyright (C) 2010-2012 Canonical Ltd
4 *4 *
5 * This program is free software: you can redistribute it and/or modify5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as6 * it under the terms of the GNU General Public License version 3 as
@@ -15,6 +15,7 @@
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *16 *
17 * Authored by: Neil Jagdish Patel <neil.patel@canonical.com>17 * Authored by: Neil Jagdish Patel <neil.patel@canonical.com>
18 * Marco Trevisan (Treviño) <3v1n0@ubuntu.com>
18 */19 */
1920
20#ifndef PANEL_INDICATOR_OBJECT_ENTRY_VIEW_H21#ifndef PANEL_INDICATOR_OBJECT_ENTRY_VIEW_H
@@ -26,78 +27,101 @@
26#include <NuxGraphics/GraphicsEngine.h>27#include <NuxGraphics/GraphicsEngine.h>
2728
28#include <UnityCore/IndicatorEntry.h>29#include <UnityCore/IndicatorEntry.h>
30#include <UnityCore/GLibWrapper.h>
31#include <UnityCore/GLibSignal.h>
32
33#include <gtk/gtk.h>
2934
30#include "Introspectable.h"35#include "Introspectable.h"
3136
3237
33namespace unity38namespace unity
34{39{
3540class PanelIndicatorEntryView : public nux::TextureArea, public debug::Introspectable
36class PanelIndicatorEntryView : public nux::TextureArea, public unity::debug::Introspectable
37{41{
38public:42public:
39 typedef enum {43 enum IndicatorEntryType {
40 INDICATOR,44 INDICATOR,
41 MENU,45 MENU,
42 OTHER46 OTHER
43 } IndicatorEntryType;47 };
4448
45 PanelIndicatorEntryView(indicator::Entry::Ptr const& proxy, int padding = 5,49 PanelIndicatorEntryView(indicator::Entry::Ptr const& proxy, int padding = 5,
46 IndicatorEntryType type = INDICATOR);50 IndicatorEntryType type = INDICATOR);
47 ~PanelIndicatorEntryView();51
4852 virtual ~PanelIndicatorEntryView();
49 void Refresh();53
5054 IndicatorEntryType GetType() const;
51 void Activate(int button = 1);55 std::string GetEntryID() const;
52 void Unactivate();56 int GetEntryPriority() const;
53 bool GetShowNow();57
58 virtual std::string GetLabel() const;
59 virtual bool IsLabelVisible() const;
60 virtual bool IsLabelSensitive() const;
61
62 virtual bool IsIconVisible() const;
63 virtual bool IsIconSensitive() const;
64
65 virtual void Activate(int button = 1);
66 virtual void Unactivate();
67
68 virtual void GetGeometryForSync(indicator::EntryLocationMap& locations);
69
70 bool GetShowNow() const;
71 bool IsSensitive() const;
72 bool IsActive() const;
73 bool IsVisible();
74
54 void SetDisabled(bool disabled);75 void SetDisabled(bool disabled);
55 bool IsDisabled();76 bool IsDisabled();
77
56 void SetOpacity(double alpha);78 void SetOpacity(double alpha);
57 double GetOpacity();79 double GetOpacity();
5880
59 void GetGeometryForSync(indicator::EntryLocationMap& locations);81 void SetFocusedState(bool focused);
60 bool IsEntryValid() const;82 bool IsFocused() const;
61 bool IsSensitive() const;83
62 bool IsActive() const;84 void OverlayShown();
63 bool IsVisible();85 void OverlayHidden();
64 int GetEntryPriority() const;86
6587 sigc::signal<void, PanelIndicatorEntryView*, bool> active_changed;
66 void DashShown();88 sigc::signal<void, PanelIndicatorEntryView*> refreshed;
67 void DashHidden();89
6890protected:
69 std::string GetName() const;91 std::string GetName() const;
70 void AddProperties(GVariantBuilder* builder);92 void AddProperties(GVariantBuilder* builder);
7193
72 virtual void Draw(nux::GraphicsEngine& GfxContext, bool force_draw);94 virtual void Draw(nux::GraphicsEngine& GfxContext, bool force_draw);
7395 virtual void DrawEntryPrelight(cairo_t* cr, unsigned int w, unsigned int h);
74 sigc::signal<void, PanelIndicatorEntryView*, bool> active_changed;96 virtual void DrawEntryContent(cairo_t* cr, unsigned int width, unsigned int height,
75 sigc::signal<void, PanelIndicatorEntryView*> refreshed;97 glib::Object<GdkPixbuf> const& pixbuf,
98 glib::Object<PangoLayout> const& layout);
99
100 void Refresh();
101 void SetActiveState(bool active, int button);
102 virtual void ShowMenu(int button = 1);
103
104 indicator::Entry::Ptr proxy_;
105 unsigned int spacing_;
106 unsigned int left_padding_;
107 unsigned int right_padding_;
76108
77private:109private:
78 unity::indicator::Entry::Ptr proxy_;110 void OnMouseDown(int x, int y, long button_flags, long key_flags);
111 void OnMouseUp(int x, int y, long button_flags, long key_flags);
112 void OnMouseWheel(int x, int y, int delta, unsigned long mouse_state, unsigned long key_state);
113 void OnActiveChanged(bool is_active);
114
115 glib::Object<GdkPixbuf> MakePixbuf();
116
79 IndicatorEntryType type_;117 IndicatorEntryType type_;
80 nux::CairoGraphics util_cg_;118 nux::BaseTexture* entry_texture_;
81 nux::TextureLayer* texture_layer_;119 nux::Geometry cached_geo_;
82 int padding_;
83 double opacity_;120 double opacity_;
84 bool draw_active_;121 bool draw_active_;
85 bool dash_showing_;122 bool overlay_showing_;
86 bool disabled_;123 bool disabled_;
87 gulong on_font_changed_connection_;124 bool focused_;
88
89 static void OnFontChanged(GObject* gobject, GParamSpec* pspec, gpointer data);
90 void OnMouseDown(int x, int y, long button_flags, long key_flags);
91 void OnMouseUp(int x, int y, long button_flags, long key_flags);
92 void OnMouseWheel(int x, int y, int delta, unsigned long mouse_state, unsigned long key_state);
93 void OnActiveChanged(bool is_active);
94
95 void SetActiveState(bool active, int button);
96 void ShowMenu(int button);
97
98 sigc::connection on_indicator_activate_changed_connection_;
99 sigc::connection on_indicator_updated_connection_;
100 sigc::connection on_panelstyle_changed_connection_;
101};125};
102126
103}127}
104128
=== modified file 'plugins/unityshell/src/PanelIndicatorsView.cpp'
--- plugins/unityshell/src/PanelIndicatorsView.cpp 2012-03-21 12:31:11 +0000
+++ plugins/unityshell/src/PanelIndicatorsView.cpp 2012-04-05 23:42:20 +0000
@@ -1,6 +1,6 @@
1// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-1// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
2/*2/*
3 * Copyright (C) 2011 Canonical Ltd3 * Copyright (C) 2011-2012 Canonical Ltd
4 *4 *
5 * This program is free software: you can redistribute it and/or modify5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as6 * it under the terms of the GNU General Public License version 3 as
@@ -14,7 +14,7 @@
14 * You should have received a copy of the GNU General Public License14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *16 *
17 * Authored by: Marco Trevisan (Treviño) <mail@3v1n0.net>17 * Authored by: Marco Trevisan (Treviño) <3v1n0@ubuntu.com>
18 * Neil Jagdish Patel <neil.patel@canonical.com>18 * Neil Jagdish Patel <neil.patel@canonical.com>
19 */19 */
2020
@@ -36,6 +36,8 @@
3636
37namespace unity37namespace unity
38{38{
39using namespace indicator;
40
39NUX_IMPLEMENT_OBJECT_TYPE(PanelIndicatorsView);41NUX_IMPLEMENT_OBJECT_TYPE(PanelIndicatorsView);
4042
41PanelIndicatorsView::PanelIndicatorsView()43PanelIndicatorsView::PanelIndicatorsView()
@@ -45,8 +47,9 @@
45{47{
46 LOG_DEBUG(logger) << "Indicators View Added: ";48 LOG_DEBUG(logger) << "Indicators View Added: ";
47 layout_ = new nux::HLayout("", NUX_TRACKER_LOCATION);49 layout_ = new nux::HLayout("", NUX_TRACKER_LOCATION);
50 layout_->SetContentDistribution(nux::eStackRight);
4851
49 SetCompositionLayout(layout_);52 SetLayout(layout_);
50}53}
5154
52PanelIndicatorsView::~PanelIndicatorsView()55PanelIndicatorsView::~PanelIndicatorsView()
@@ -59,7 +62,7 @@
59}62}
6063
61void64void
62PanelIndicatorsView::AddIndicator(indicator::Indicator::Ptr const& indicator)65PanelIndicatorsView::AddIndicator(Indicator::Ptr const& indicator)
63{66{
64 LOG_DEBUG(logger) << "IndicatorAdded: " << indicator->name();67 LOG_DEBUG(logger) << "IndicatorAdded: " << indicator->name();
65 indicators_.push_back(indicator);68 indicators_.push_back(indicator);
@@ -76,7 +79,7 @@
76}79}
7780
78void81void
79PanelIndicatorsView::RemoveIndicator(indicator::Indicator::Ptr const& indicator)82PanelIndicatorsView::RemoveIndicator(Indicator::Ptr const& indicator)
80{83{
81 auto connections = indicators_connections_.find(indicator);84 auto connections = indicators_connections_.find(indicator);
8285
@@ -88,7 +91,7 @@
88 }91 }
8992
90 for (auto entry : indicator->GetEntries())93 for (auto entry : indicator->GetEntries())
91 OnEntryRemoved (entry->id());94 OnEntryRemoved(entry->id());
9295
93 for (auto i = indicators_.begin(); i != indicators_.end(); i++)96 for (auto i = indicators_.begin(); i != indicators_.end(); i++)
94 {97 {
@@ -102,6 +105,12 @@
102 LOG_DEBUG(logger) << "IndicatorRemoved: " << indicator->name();105 LOG_DEBUG(logger) << "IndicatorRemoved: " << indicator->name();
103}106}
104107
108PanelIndicatorsView::Indicators
109PanelIndicatorsView::GetIndicators()
110{
111 return indicators_;
112}
113
105void114void
106PanelIndicatorsView::Draw(nux::GraphicsEngine& GfxContext, bool force_draw)115PanelIndicatorsView::Draw(nux::GraphicsEngine& GfxContext, bool force_draw)
107{116{
@@ -121,16 +130,45 @@
121 entry.second->QueueDraw();130 entry.second->QueueDraw();
122}131}
123132
133void
134PanelIndicatorsView::SetMaximumEntriesWidth(int max_width)
135{
136 unsigned int n_entries = 0;
137
138 for (auto entry : entries_)
139 if (entry.second->IsVisible())
140 n_entries++;
141
142 if (n_entries > 0)
143 {
144 for (auto entry : entries_)
145 {
146 if (entry.second->IsVisible() && n_entries > 0)
147 {
148 int max_entry_width = max_width / n_entries;
149
150 if (entry.second->GetBaseWidth() > max_entry_width)
151 entry.second->SetMaximumWidth(max_entry_width);
152
153 max_width -= entry.second->GetBaseWidth();
154 --n_entries;
155 }
156 }
157 }
158}
159
124PanelIndicatorEntryView*160PanelIndicatorEntryView*
125PanelIndicatorsView::ActivateEntry(std::string const& entry_id)161PanelIndicatorsView::ActivateEntry(std::string const& entry_id, int button)
126{162{
127 auto entry = entries_.find(entry_id);163 auto entry = entries_.find(entry_id);
128164
129 if (entry != entries_.end() && entry->second->IsEntryValid())165 if (entry != entries_.end())
130 {166 {
131 PanelIndicatorEntryView* view = entry->second;167 PanelIndicatorEntryView* view = entry->second;
132 LOG_DEBUG(logger) << "Activating: " << entry_id;168
133 view->Activate();169 if (view->IsSensitive() && view->IsVisible())
170 view->Activate(button);
171
134 return view;172 return view;
135 }173 }
136174
@@ -148,24 +186,27 @@
148 for (auto entry : sorted_entries)186 for (auto entry : sorted_entries)
149 {187 {
150 PanelIndicatorEntryView* view = entry.second;188 PanelIndicatorEntryView* view = entry.second;
151 if (view->IsSensitive())189
190 if (view->IsSensitive() && view->IsVisible() && view->IsFocused())
152 {191 {
153 view->Activate();192 /* Use the 0 button, it means it's a keyboard activation */
193 view->Activate(0);
154 return true;194 return true;
155 }195 }
156 }196 }
197
157 return false;198 return false;
158}199}
159200
160void201void
161PanelIndicatorsView::GetGeometryForSync(indicator::EntryLocationMap& locations)202PanelIndicatorsView::GetGeometryForSync(EntryLocationMap& locations)
162{203{
163 for (auto entry : entries_)204 for (auto entry : entries_)
164 entry.second->GetGeometryForSync(locations);205 entry.second->GetGeometryForSync(locations);
165}206}
166207
167PanelIndicatorEntryView*208PanelIndicatorEntryView*
168PanelIndicatorsView::ActivateEntryAt(int x, int y)209PanelIndicatorsView::ActivateEntryAt(int x, int y, int button)
169{210{
170 PanelIndicatorEntryView* target = nullptr;211 PanelIndicatorEntryView* target = nullptr;
171 bool found_old_active = false;212 bool found_old_active = false;
@@ -180,9 +221,10 @@
180 {221 {
181 PanelIndicatorEntryView* view = entry.second;222 PanelIndicatorEntryView* view = entry.second;
182223
183 if (!target && view->IsVisible() && view->GetAbsoluteGeometry().IsPointInside(x, y))224 if (!target && view->IsVisible() && view->IsFocused() &&
225 view->GetAbsoluteGeometry().IsPointInside(x, y))
184 {226 {
185 view->Activate(0);227 view->Activate(button);
186 target = view;228 target = view;
187 break;229 break;
188 }230 }
@@ -219,11 +261,13 @@
219 GfxContext.PopClippingRectangle();261 GfxContext.PopClippingRectangle();
220}262}
221263
222PanelIndicatorEntryView *264void
223PanelIndicatorsView::AddEntry(indicator::Entry::Ptr const& entry, int padding,265PanelIndicatorsView::AddEntryView(PanelIndicatorEntryView* view,
224 IndicatorEntryPosition pos, IndicatorEntryType type)266 IndicatorEntryPosition pos)
225{267{
226 auto view = new PanelIndicatorEntryView(entry, padding, type);268 if (!view)
269 return;
270
227 int entry_pos = pos;271 int entry_pos = pos;
228272
229 view->SetOpacity(opacity_);273 view->SetOpacity(opacity_);
@@ -233,7 +277,7 @@
233 {277 {
234 entry_pos = nux::NUX_LAYOUT_BEGIN;278 entry_pos = nux::NUX_LAYOUT_BEGIN;
235279
236 if (entry->priority() > -1)280 if (view->GetEntryPriority() > -1)
237 {281 {
238 for (auto area : layout_->GetChildren())282 for (auto area : layout_->GetChildren())
239 {283 {
@@ -241,7 +285,7 @@
241285
242 if (en)286 if (en)
243 {287 {
244 if (en && entry->priority() <= en->GetEntryPriority())288 if (en && view->GetEntryPriority() <= en->GetEntryPriority())
245 break;289 break;
246290
247 entry_pos++;291 entry_pos++;
@@ -251,20 +295,28 @@
251 }295 }
252296
253 layout_->AddView(view, 0, nux::eCenter, nux::eFull, 1.0, (nux::LayoutPosition) entry_pos);297 layout_->AddView(view, 0, nux::eCenter, nux::eFull, 1.0, (nux::LayoutPosition) entry_pos);
254 layout_->SetContentDistribution(nux::eStackRight);298
255 entries_[entry->id()] = view;299 entries_[view->GetEntryID()] = view;
256300
257 AddChild(view);301 AddChild(view);
258 QueueRelayout();302 QueueRelayout();
259 QueueDraw();303 QueueDraw();
260304
261 on_indicator_updated.emit(view);305 on_indicator_updated.emit(view);
306}
307
308PanelIndicatorEntryView *
309PanelIndicatorsView::AddEntry(Entry::Ptr const& entry, int padding,
310 IndicatorEntryPosition pos, IndicatorEntryType type)
311{
312 auto view = new PanelIndicatorEntryView(entry, padding, type);
313 AddEntryView(view, pos);
262314
263 return view;315 return view;
264}316}
265317
266void318void
267PanelIndicatorsView::OnEntryAdded(indicator::Entry::Ptr const& entry)319PanelIndicatorsView::OnEntryAdded(Entry::Ptr const& entry)
268{320{
269 AddEntry(entry);321 AddEntry(entry);
270}322}
@@ -279,19 +331,25 @@
279}331}
280332
281void333void
334PanelIndicatorsView::RemoveEntryView(PanelIndicatorEntryView* view)
335{
336 if (!view)
337 return;
338
339 std::string const& entry_id = view->GetEntryID();
340 RemoveChild(view);
341 on_indicator_updated.emit(view);
342 entries_.erase(entry_id);
343 layout_->RemoveChildObject(view);
344
345 QueueRelayout();
346 QueueDraw();
347}
348
349void
282PanelIndicatorsView::RemoveEntry(std::string const& entry_id)350PanelIndicatorsView::RemoveEntry(std::string const& entry_id)
283{351{
284 PanelIndicatorEntryView* view = entries_[entry_id];352 RemoveEntryView(entries_[entry_id]);
285
286 if (view)
287 {
288 layout_->RemoveChildObject(view);
289 entries_.erase(entry_id);
290 on_indicator_updated.emit(view);
291
292 QueueRelayout();
293 QueueDraw();
294 }
295}353}
296354
297void355void
@@ -301,17 +359,17 @@
301}359}
302360
303void361void
304PanelIndicatorsView::DashShown()362PanelIndicatorsView::OverlayShown()
305{363{
306 for (auto entry: entries_)364 for (auto entry: entries_)
307 entry.second->DashShown();365 entry.second->OverlayShown();
308}366}
309367
310void368void
311PanelIndicatorsView::DashHidden()369PanelIndicatorsView::OverlayHidden()
312{370{
313 for (auto entry: entries_)371 for (auto entry: entries_)
314 entry.second->DashHidden();372 entry.second->OverlayHidden();
315}373}
316374
317double375double
@@ -337,13 +395,16 @@
337395
338std::string PanelIndicatorsView::GetName() const396std::string PanelIndicatorsView::GetName() const
339{397{
340 return "IndicatorsView";398 return "Indicators";
341}399}
342400
343void401void
344PanelIndicatorsView::AddProperties(GVariantBuilder* builder)402PanelIndicatorsView::AddProperties(GVariantBuilder* builder)
345{403{
346 variant::BuilderWrapper(builder).add(GetGeometry());404 variant::BuilderWrapper(builder)
405 .add(GetGeometry())
406 .add("entries", entries_.size())
407 .add("opacity", opacity_);
347}408}
348409
349} // namespace unity410} // namespace unity
350411
=== modified file 'plugins/unityshell/src/PanelIndicatorsView.h'
--- plugins/unityshell/src/PanelIndicatorsView.h 2012-03-21 12:31:11 +0000
+++ plugins/unityshell/src/PanelIndicatorsView.h 2012-04-05 23:42:20 +0000
@@ -42,11 +42,11 @@
42 void AddIndicator(indicator::Indicator::Ptr const& indicator);42 void AddIndicator(indicator::Indicator::Ptr const& indicator);
43 void RemoveIndicator(indicator::Indicator::Ptr const& indicator);43 void RemoveIndicator(indicator::Indicator::Ptr const& indicator);
4444
45 typedef enum {45 enum IndicatorEntryPosition {
46 AUTO = -1,46 AUTO = -1,
47 START = nux::NUX_LAYOUT_BEGIN,47 START = nux::NUX_LAYOUT_BEGIN,
48 END = nux::NUX_LAYOUT_END,48 END = nux::NUX_LAYOUT_END,
49 } IndicatorEntryPosition;49 };
5050
51 typedef PanelIndicatorEntryView::IndicatorEntryType IndicatorEntryType;51 typedef PanelIndicatorEntryView::IndicatorEntryType IndicatorEntryType;
5252
@@ -56,37 +56,46 @@
56 IndicatorEntryType type = IndicatorEntryType::INDICATOR);56 IndicatorEntryType type = IndicatorEntryType::INDICATOR);
57 void RemoveEntry(std::string const& entry_id);57 void RemoveEntry(std::string const& entry_id);
5858
59 PanelIndicatorEntryView* ActivateEntryAt(int x, int y);59 PanelIndicatorEntryView* ActivateEntryAt(int x, int y, int button = 1);
60 PanelIndicatorEntryView* ActivateEntry(std::string const& entry_id);60 PanelIndicatorEntryView* ActivateEntry(std::string const& entry_id, int button = 1);
61 bool ActivateIfSensitive();61 bool ActivateIfSensitive();
62
63 virtual void OverlayShown();
64 virtual void OverlayHidden();
65
66 void SetOpacity(double opacity);
67 double GetOpacity();
68
69 void SetMaximumEntriesWidth(int max_width);
62 void GetGeometryForSync(indicator::EntryLocationMap& locations);70 void GetGeometryForSync(indicator::EntryLocationMap& locations);
6371
72 virtual void QueueDraw();
73
74 sigc::signal<void, PanelIndicatorEntryView*> on_indicator_updated;
75
76protected:
77 std::string GetName() const;
78 void AddProperties(GVariantBuilder* builder);
79
80 typedef std::vector<indicator::Indicator::Ptr> Indicators;
81 Indicators GetIndicators();
82
64 virtual void Draw(nux::GraphicsEngine& GfxContext, bool force_draw);83 virtual void Draw(nux::GraphicsEngine& GfxContext, bool force_draw);
65 virtual void DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw);84 virtual void DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw);
66 virtual void QueueDraw();
6785
68 virtual void OnEntryAdded(indicator::Entry::Ptr const& entry);86 virtual void OnEntryAdded(indicator::Entry::Ptr const& entry);
69 virtual void OnEntryRefreshed(PanelIndicatorEntryView* view);87 virtual void OnEntryRefreshed(PanelIndicatorEntryView* view);
70 virtual void OnEntryRemoved(std::string const& entry_id);88 virtual void OnEntryRemoved(std::string const& entry_id);
7189
72 void DashShown();90 virtual void AddEntryView(PanelIndicatorEntryView* view,
73 void DashHidden();91 IndicatorEntryPosition pos = AUTO);
7492 virtual void RemoveEntryView(PanelIndicatorEntryView* view);
75 void SetOpacity(double opacity);93
76 double GetOpacity();
77
78 sigc::signal<void, PanelIndicatorEntryView*> on_indicator_updated;
79
80protected:
81 nux::HLayout* layout_;94 nux::HLayout* layout_;
82 typedef std::map<std::string, PanelIndicatorEntryView*> Entries;95 typedef std::map<std::string, PanelIndicatorEntryView*> Entries;
83 Entries entries_;96 Entries entries_;
8497
85 std::string GetName() const;
86 void AddProperties(GVariantBuilder* builder);
87
88private:98private:
89 typedef std::vector<indicator::Indicator::Ptr> Indicators;
90 Indicators indicators_;99 Indicators indicators_;
91 double opacity_;100 double opacity_;
92101
93102
=== modified file 'plugins/unityshell/src/PanelMenuView.cpp'
--- plugins/unityshell/src/PanelMenuView.cpp 2012-04-03 03:36:34 +0000
+++ plugins/unityshell/src/PanelMenuView.cpp 2012-04-05 23:42:20 +0000
@@ -1,6 +1,6 @@
1// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-1// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
2/*2/*
3 * Copyright (C) 2010 Canonical Ltd3 * Copyright (C) 2010-2012 Canonical Ltd
4 *4 *
5 * This program is free software: you can redistribute it and/or modify5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as6 * it under the terms of the GNU General Public License version 3 as
@@ -15,61 +15,52 @@
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *16 *
17 * Authored by: Neil Jagdish Patel <neil.patel@canonical.com>17 * Authored by: Neil Jagdish Patel <neil.patel@canonical.com>
18 * Marco Trevisan <mail@3v1n0.net>18 * Marco Trevisan <3v1n0@ubuntu.com>
19 */19 */
20#include <glib.h>
21#include <pango/pangocairo.h>
22#include <gtk/gtk.h>
2320
24#include <Nux/Nux.h>21#include <Nux/Nux.h>
25#include <Nux/HLayout.h>22#include <NuxCore/Logger.h>
26#include <Nux/VLayout.h>
27#include <Nux/TextureArea.h>
28
29#include <NuxGraphics/GLThread.h>
30#include <NuxGraphics/XInputWindow.h>
31#include <Nux/BaseWindow.h>
3223
33#include "CairoTexture.h"24#include "CairoTexture.h"
34#include "PanelMenuView.h"25#include "PanelMenuView.h"
35#include "PanelStyle.h"26#include "PanelStyle.h"
36#include <UnityCore/Variant.h>
37
38#include <gio/gdesktopappinfo.h>
39#include <gconf/gconf-client.h>
40
41#include <glib.h>
42#include <glib/gi18n-lib.h>
43
44#include "DashSettings.h"27#include "DashSettings.h"
45#include "ubus-server.h"
46#include "UBusMessages.h"28#include "UBusMessages.h"
47
48#include "UScreen.h"29#include "UScreen.h"
4930
31#include <UnityCore/Variant.h>
32
33#include <glib/gi18n-lib.h>
34
50namespace unity35namespace unity
51{36{
5237
53namespace38namespace
54{39{
55 const std::string WINDOW_TITLE_FONT_KEY = "/apps/metacity/general/titlebar_font";40 nux::logging::Logger logger("unity.panel.menu");
41 const int MAIN_LEFT_PADDING = 4;
42 const int TITLE_PADDING = 2;
43 const int MENUBAR_PADDING = 4;
44 const int MENU_ENTRIES_PADDING = 6;
45 const int DEFAULT_MENUS_FADEIN = 100;
46 const int DEFAULT_MENUS_FADEOUT = 120;
47 const int DEFAULT_MENUS_DISCOVERY = 2;
48 const int DEFAULT_DISCOVERY_FADEIN = 200;
49 const int DEFAULT_DISCOVERY_FADEOUT = 300;
50
51 const std::string DESKTOP_NAME(_("Ubuntu Desktop"));
56}52}
5753
58PanelMenuView::PanelMenuView(int padding)54PanelMenuView::PanelMenuView()
59 : _matcher(bamf_matcher_get_default()),55 : _matcher(bamf_matcher_get_default()),
60 _title_layer(nullptr),
61 _util_cg(CAIRO_FORMAT_ARGB32, 1, 1),
62 _gradient_texture(nullptr),
63 _is_inside(false),56 _is_inside(false),
64 _is_grabbed(false),57 _is_grabbed(false),
65 _is_maximized(false),58 _is_maximized(false),
66 _is_own_window(false),
67 _last_active_view(nullptr),59 _last_active_view(nullptr),
68 _new_application(nullptr),60 _new_application(nullptr),
69 _last_width(0),61 _overlay_showing(false),
70 _last_height(0),
71 _places_showing(false),
72 _switcher_showing(false),62 _switcher_showing(false),
63 _launcher_keynav(false),
73 _show_now_activated(false),64 _show_now_activated(false),
74 _we_control_active(false),65 _we_control_active(false),
75 _new_app_menu_shown(false),66 _new_app_menu_shown(false),
@@ -79,26 +70,19 @@
79 _update_show_now_id(0),70 _update_show_now_id(0),
80 _new_app_show_id(0),71 _new_app_show_id(0),
81 _new_app_hide_id(0),72 _new_app_hide_id(0),
82 _menus_fadein(100),73 _menus_fadein(DEFAULT_MENUS_FADEIN),
83 _menus_fadeout(120),74 _menus_fadeout(DEFAULT_MENUS_FADEOUT),
84 _menus_discovery(2),75 _menus_discovery(DEFAULT_MENUS_DISCOVERY),
85 _menus_discovery_fadein(200),76 _menus_discovery_fadein(DEFAULT_DISCOVERY_FADEIN),
86 _menus_discovery_fadeout(300),77 _menus_discovery_fadeout(DEFAULT_DISCOVERY_FADEOUT),
87 _panel_title(nullptr),78 _fade_in_animator(_menus_fadein),
88 _fade_in_animator(nullptr),79 _fade_out_animator(_menus_fadeout)
89 _fade_out_animator(nullptr)
90{80{
91 WindowManager* win_manager;81 layout_->SetContentDistribution(nux::eStackLeft);
9282
93 // TODO: kill _menu_layout - should just use the _layout defined83 BamfWindow* active_win = bamf_matcher_get_active_window(_matcher);
94 // in the base class.84 if (BAMF_IS_WINDOW(active_win))
95 _menu_layout = new nux::HLayout("", NUX_TRACKER_LOCATION);85 _active_xid = bamf_window_get_xid(active_win);
96 _menu_layout->SetParentObject(this);
97
98 /* This is for our parent and for PanelView to read indicator entries, we
99 * shouldn't touch this again
100 */
101 layout_ = _menu_layout;
10286
103 _view_opened_signal.Connect(_matcher, "view-opened",87 _view_opened_signal.Connect(_matcher, "view-opened",
104 sigc::mem_fun(this, &PanelMenuView::OnViewOpened));88 sigc::mem_fun(this, &PanelMenuView::OnViewOpened));
@@ -109,35 +93,35 @@
109 _active_app_changed_signal.Connect(_matcher, "active-application-changed",93 _active_app_changed_signal.Connect(_matcher, "active-application-changed",
110 sigc::mem_fun(this, &PanelMenuView::OnActiveAppChanged));94 sigc::mem_fun(this, &PanelMenuView::OnActiveAppChanged));
11195
112 _padding = padding;
113
114 _window_buttons = new WindowButtons();96 _window_buttons = new WindowButtons();
97 _window_buttons->SetMonitor(_monitor);
98 _window_buttons->SetControlledWindow(_active_xid);
115 _window_buttons->SetParentObject(this);99 _window_buttons->SetParentObject(this);
116 _window_buttons->NeedRedraw();100 _window_buttons->SetLeftAndRightPadding(MAIN_LEFT_PADDING, MENUBAR_PADDING);
101 _window_buttons->SetMaximumHeight(panel::Style::Instance().panel_height);
102 _window_buttons->ComputeContentSize();
117103
118 _window_buttons->close_clicked.connect(sigc::mem_fun(this, &PanelMenuView::OnCloseClicked));
119 _window_buttons->minimize_clicked.connect(sigc::mem_fun(this, &PanelMenuView::OnMinimizeClicked));
120 _window_buttons->restore_clicked.connect(sigc::mem_fun(this, &PanelMenuView::OnRestoreClicked));
121 _window_buttons->mouse_enter.connect(sigc::mem_fun(this, &PanelMenuView::OnPanelViewMouseEnter));104 _window_buttons->mouse_enter.connect(sigc::mem_fun(this, &PanelMenuView::OnPanelViewMouseEnter));
122 _window_buttons->mouse_leave.connect(sigc::mem_fun(this, &PanelMenuView::OnPanelViewMouseLeave));105 _window_buttons->mouse_leave.connect(sigc::mem_fun(this, &PanelMenuView::OnPanelViewMouseLeave));
123 //_window_buttons->mouse_move.connect(sigc::mem_fun(this, &PanelMenuView::OnPanelViewMouseMove));106 //_window_buttons->mouse_move.connect(sigc::mem_fun(this, &PanelMenuView::OnPanelViewMouseMove));
124107 AddChild(_window_buttons);
125 _panel_titlebar_grab_area = new PanelTitlebarGrabArea();108
126 _panel_titlebar_grab_area->SetParentObject(this);109 layout_->SetLeftAndRightPadding(_window_buttons->GetContentWidth(), 0);
127 _panel_titlebar_grab_area->mouse_down.connect(sigc::mem_fun(this, &PanelMenuView::OnMouseClicked));110 layout_->SetBaseHeight(panel::Style::Instance().panel_height);
128 _panel_titlebar_grab_area->mouse_down.connect(sigc::mem_fun(this, &PanelMenuView::OnMouseMiddleClicked));111
129 _panel_titlebar_grab_area->mouse_down.connect(sigc::mem_fun(this, &PanelMenuView::OnMaximizedGrabStart));112 _titlebar_grab_area = new PanelTitlebarGrabArea();
130 _panel_titlebar_grab_area->mouse_drag.connect(sigc::mem_fun(this, &PanelMenuView::OnMaximizedGrabMove));113 _titlebar_grab_area->SetParentObject(this);
131 _panel_titlebar_grab_area->mouse_up.connect(sigc::mem_fun(this, &PanelMenuView::OnMaximizedGrabEnd));114 _titlebar_grab_area->activate_request.connect(sigc::mem_fun(this, &PanelMenuView::OnMaximizedActivate));
132 _panel_titlebar_grab_area->mouse_double_click.connect(sigc::mem_fun(this, &PanelMenuView::OnMouseDoubleClicked));115 _titlebar_grab_area->restore_request.connect(sigc::mem_fun(this, &PanelMenuView::OnMaximizedRestore));
133116 _titlebar_grab_area->lower_request.connect(sigc::mem_fun(this, &PanelMenuView::OnMaximizedLower));
134 win_manager = WindowManager::Default();117 _titlebar_grab_area->grab_started.connect(sigc::mem_fun(this, &PanelMenuView::OnMaximizedGrabStart));
135118 _titlebar_grab_area->grab_move.connect(sigc::mem_fun(this, &PanelMenuView::OnMaximizedGrabMove));
119 _titlebar_grab_area->grab_end.connect(sigc::mem_fun(this, &PanelMenuView::OnMaximizedGrabEnd));
120 AddChild(_titlebar_grab_area);
121
122 WindowManager* win_manager = WindowManager::Default();
136 win_manager->window_minimized.connect(sigc::mem_fun(this, &PanelMenuView::OnWindowMinimized));123 win_manager->window_minimized.connect(sigc::mem_fun(this, &PanelMenuView::OnWindowMinimized));
137 win_manager->window_unminimized.connect(sigc::mem_fun(this, &PanelMenuView::OnWindowUnminimized));124 win_manager->window_unminimized.connect(sigc::mem_fun(this, &PanelMenuView::OnWindowUnminimized));
138 //win_manager->initiate_spread.connect(sigc::mem_fun(this, &PanelMenuView::OnSpreadInitiate));
139 //win_manager->terminate_spread.connect(sigc::mem_fun(this, &PanelMenuView::OnSpreadTerminate));
140
141 win_manager->window_maximized.connect(sigc::mem_fun(this, &PanelMenuView::OnWindowMaximized));125 win_manager->window_maximized.connect(sigc::mem_fun(this, &PanelMenuView::OnWindowMaximized));
142 win_manager->window_restored.connect(sigc::mem_fun(this, &PanelMenuView::OnWindowRestored));126 win_manager->window_restored.connect(sigc::mem_fun(this, &PanelMenuView::OnWindowRestored));
143 win_manager->window_unmapped.connect(sigc::mem_fun(this, &PanelMenuView::OnWindowUnmapped));127 win_manager->window_unmapped.connect(sigc::mem_fun(this, &PanelMenuView::OnWindowUnmapped));
@@ -146,39 +130,40 @@
146 win_manager->window_resized.connect(sigc::mem_fun(this, &PanelMenuView::OnWindowMoved));130 win_manager->window_resized.connect(sigc::mem_fun(this, &PanelMenuView::OnWindowMoved));
147 win_manager->window_decorated.connect(sigc::mem_fun(this, &PanelMenuView::OnWindowDecorated));131 win_manager->window_decorated.connect(sigc::mem_fun(this, &PanelMenuView::OnWindowDecorated));
148 win_manager->window_undecorated.connect(sigc::mem_fun(this, &PanelMenuView::OnWindowUndecorated));132 win_manager->window_undecorated.connect(sigc::mem_fun(this, &PanelMenuView::OnWindowUndecorated));
149133 win_manager->initiate_spread.connect(sigc::mem_fun(this, &PanelMenuView::OnSpreadInitiate));
150 panel::Style::Instance().changed.connect(sigc::mem_fun(this, &PanelMenuView::Refresh));134 win_manager->terminate_spread.connect(sigc::mem_fun(this, &PanelMenuView::OnSpreadTerminate));
135 win_manager->initiate_expo.connect(sigc::mem_fun(this, &PanelMenuView::OnExpoInitiate));
136 win_manager->terminate_expo.connect(sigc::mem_fun(this, &PanelMenuView::OnExpoTerminate));
137 win_manager->compiz_screen_viewport_switch_ended.connect(sigc::mem_fun(this, &PanelMenuView::OnExpoTerminate));
138
139 _style_changed_connection = panel::Style::Instance().changed.connect([&] {
140 _window_buttons->ComputeContentSize();
141 layout_->SetLeftAndRightPadding(_window_buttons->GetContentWidth(), 0);
142
143 Refresh(true);
144 FullRedraw();
145 });
151146
152 mouse_enter.connect(sigc::mem_fun(this, &PanelMenuView::OnPanelViewMouseEnter));147 mouse_enter.connect(sigc::mem_fun(this, &PanelMenuView::OnPanelViewMouseEnter));
153 mouse_leave.connect(sigc::mem_fun(this, &PanelMenuView::OnPanelViewMouseLeave));148 mouse_leave.connect(sigc::mem_fun(this, &PanelMenuView::OnPanelViewMouseLeave));
154 //mouse_move.connect(sigc::mem_fun(this, &PanelMenuView::OnPanelViewMouseMove));149 //mouse_move.connect(sigc::mem_fun(this, &PanelMenuView::OnPanelViewMouseMove));
155150
156 _panel_titlebar_grab_area->mouse_enter.connect(sigc::mem_fun(this, &PanelMenuView::OnPanelViewMouseEnter));151 _titlebar_grab_area->mouse_enter.connect(sigc::mem_fun(this, &PanelMenuView::OnPanelViewMouseEnter));
157 _panel_titlebar_grab_area->mouse_leave.connect(sigc::mem_fun(this, &PanelMenuView::OnPanelViewMouseLeave));152 _titlebar_grab_area->mouse_leave.connect(sigc::mem_fun(this, &PanelMenuView::OnPanelViewMouseLeave));
158153
159 // Register for all the interesting events154 _ubus_manager.RegisterInterest(UBUS_SWITCHER_SHOWN, sigc::mem_fun(this, &PanelMenuView::OnSwitcherShown));
160 UBusServer* ubus = ubus_server_get_default();155 _ubus_manager.RegisterInterest(UBUS_SWITCHER_SELECTION_CHANGED, sigc::mem_fun(this, &PanelMenuView::OnSwitcherSelectionChanged));
161 _ubus_interests.push_back(ubus_server_register_interest(ubus, UBUS_OVERLAY_SHOWN,156
162 (UBusCallback)PanelMenuView::OnPlaceViewShown,157 _ubus_manager.RegisterInterest(UBUS_LAUNCHER_START_KEY_NAV, sigc::mem_fun(this, &PanelMenuView::OnLauncherKeyNavStarted));
163 this));158 _ubus_manager.RegisterInterest(UBUS_LAUNCHER_END_KEY_NAV, sigc::mem_fun(this, &PanelMenuView::OnLauncherKeyNavEnded));
164 _ubus_interests.push_back(ubus_server_register_interest(ubus, UBUS_OVERLAY_HIDDEN,159 _ubus_manager.RegisterInterest(UBUS_LAUNCHER_START_KEY_SWTICHER, sigc::mem_fun(this, &PanelMenuView::OnLauncherKeyNavStarted));
165 (UBusCallback)PanelMenuView::OnPlaceViewHidden,160 _ubus_manager.RegisterInterest(UBUS_LAUNCHER_END_KEY_SWTICHER, sigc::mem_fun(this, &PanelMenuView::OnLauncherKeyNavEnded));
166 this));161 _ubus_manager.RegisterInterest(UBUS_LAUNCHER_SELECTION_CHANGED, sigc::mem_fun(this, &PanelMenuView::OnLauncherSelectionChanged));
167162
168 _ubus_interests.push_back(ubus_server_register_interest(ubus, UBUS_SWITCHER_SHOWN,163 _fade_in_animator.animation_updated.connect(sigc::mem_fun(this, &PanelMenuView::OnFadeInChanged));
169 (UBusCallback)PanelMenuView::OnSwitcherShown,164 _fade_in_animator.animation_ended.connect(sigc::mem_fun(this, &PanelMenuView::FullRedraw));
170 this));165 _fade_out_animator.animation_updated.connect(sigc::mem_fun(this, &PanelMenuView::OnFadeOutChanged));
171 _ubus_interests.push_back(ubus_server_register_interest(ubus, UBUS_SWITCHER_SELECTION_CHANGED,166 _fade_out_animator.animation_ended.connect(sigc::mem_fun(this, &PanelMenuView::FullRedraw));
172 (UBusCallback)PanelMenuView::OnSwitcherSelectionChanged,
173 this));
174
175 _fade_in_animator = new Animator(_menus_fadein);
176 _fade_out_animator = new Animator(_menus_fadeout);
177
178 _fade_in_animator->animation_updated.connect(sigc::mem_fun(this, &PanelMenuView::OnFadeInChanged));
179 _fade_in_animator->animation_ended.connect(sigc::mem_fun(this, &PanelMenuView::FullRedraw));
180 _fade_out_animator->animation_updated.connect(sigc::mem_fun(this, &PanelMenuView::OnFadeOutChanged));
181 _fade_out_animator->animation_ended.connect(sigc::mem_fun(this, &PanelMenuView::FullRedraw));
182167
183 SetOpacity(0.0f);168 SetOpacity(0.0f);
184 _window_buttons->SetOpacity(0.0f);169 _window_buttons->SetOpacity(0.0f);
@@ -198,41 +183,48 @@
198 if (_new_app_hide_id)183 if (_new_app_hide_id)
199 g_source_remove(_new_app_hide_id);184 g_source_remove(_new_app_hide_id);
200185
201 if (_title_layer)
202 delete _title_layer;
203
204 if (_fade_in_animator)
205 delete _fade_in_animator;
206
207 if (_fade_out_animator)
208 delete _fade_out_animator;
209
210 _menu_layout->UnReference();
211 _window_buttons->UnReference();186 _window_buttons->UnReference();
212 _panel_titlebar_grab_area->UnReference();187 _titlebar_grab_area->UnReference();
213188
214 UBusServer* ubus = ubus_server_get_default();189 _style_changed_connection.disconnect();
215 for (auto interest : _ubus_interests)190}
191
192void PanelMenuView::OverlayShown()
193{
194 _overlay_showing = true;
195 QueueDraw();
196}
197
198void PanelMenuView::OverlayHidden()
199{
200 _overlay_showing = false;
201 QueueDraw();
202}
203
204void PanelMenuView::AddIndicator(indicator::Indicator::Ptr const& indicator)
205{
206 if (!GetIndicators().empty())
216 {207 {
217 if (interest != 0)208 LOG_ERROR(logger) << "PanelMenuView has already an indicator!";
218 ubus_server_unregister_interest(ubus, interest);209 return;
219 }210 }
211
212 PanelIndicatorsView::AddIndicator(indicator);
220}213}
221214
222void215void PanelMenuView::SetMenuShowTimings(int fadein, int fadeout, int discovery,
223PanelMenuView::SetMenuShowTimings(int fadein, int fadeout, int discovery,216 int discovery_fadein, int discovery_fadeout)
224 int discovery_fadein, int discovery_fadeout)
225{217{
226 if (fadein > -1)218 if (fadein > -1)
227 {219 {
228 _menus_fadein = fadein;220 _menus_fadein = fadein;
229 _fade_in_animator->SetDuration(_menus_fadein);221 _fade_in_animator.SetDuration(_menus_fadein);
230 }222 }
231223
232 if (fadeout > -1)224 if (fadeout > -1)
233 {225 {
234 _menus_fadeout = fadeout;226 _menus_fadeout = fadeout;
235 _fade_out_animator->SetDuration(_menus_fadeout);227 _fade_out_animator.SetDuration(_menus_fadeout);
236 }228 }
237229
238 if (discovery > -1)230 if (discovery > -1)
@@ -245,16 +237,13 @@
245 _menus_discovery_fadeout = discovery_fadeout;237 _menus_discovery_fadeout = discovery_fadeout;
246}238}
247239
248void240void PanelMenuView::FullRedraw()
249PanelMenuView::FullRedraw()
250{241{
251 _menu_layout->NeedRedraw();242 QueueDraw();
252 _window_buttons->NeedRedraw();243 _window_buttons->QueueDraw();
253 NeedRedraw();
254}244}
255245
256nux::Area*246nux::Area* PanelMenuView::FindAreaUnderMouse(const nux::Point& mouse_position, nux::NuxEventType event_type)
257PanelMenuView::FindAreaUnderMouse(const nux::Point& mouse_position, nux::NuxEventType event_type)
258{247{
259 bool mouse_inside = TestMousePointerInclusionFilterMouseWheel(mouse_position, event_type);248 bool mouse_inside = TestMousePointerInclusionFilterMouseWheel(mouse_position, event_type);
260249
@@ -262,80 +251,59 @@
262 return nullptr;251 return nullptr;
263252
264 Area* found_area = nullptr;253 Area* found_area = nullptr;
254
255 if (_overlay_showing)
256 {
257 if (_window_buttons)
258 return _window_buttons->FindAreaUnderMouse(mouse_position, event_type);
259 }
260
265 if (!_we_control_active)261 if (!_we_control_active)
266 {262 {
267 found_area = _panel_titlebar_grab_area->FindAreaUnderMouse(mouse_position, event_type);263 /* When the current panel is not active, it all behaves like a grab-area */
268 NUX_RETURN_VALUE_IF_NOTNULL(found_area, found_area);264 if (GetAbsoluteGeometry().IsInside(mouse_position))
265 return _titlebar_grab_area;
269 }266 }
270267
271 if (_is_maximized || _places_showing)268 if (_is_maximized)
272 {269 {
273 if (_window_buttons)270 if (_window_buttons)
274 {271 {
275 found_area = _window_buttons->FindAreaUnderMouse(mouse_position, event_type);272 found_area = _window_buttons->FindAreaUnderMouse(mouse_position, event_type);
276 NUX_RETURN_VALUE_IF_NOTNULL(found_area, found_area);273 NUX_RETURN_VALUE_IF_NOTNULL(found_area, found_area);
277 }274 }
278275 }
279 if (_panel_titlebar_grab_area)276
280 {277 if (_titlebar_grab_area && !_overlay_showing)
281 found_area = _panel_titlebar_grab_area->FindAreaUnderMouse(mouse_position, event_type);278 {
282 NUX_RETURN_VALUE_IF_NOTNULL(found_area, found_area);279 found_area = _titlebar_grab_area->FindAreaUnderMouse(mouse_position, event_type);
283 }280 NUX_RETURN_VALUE_IF_NOTNULL(found_area, found_area);
284 }281 }
285282
286 if (_panel_titlebar_grab_area)283 return PanelIndicatorsView::FindAreaUnderMouse(mouse_position, event_type);
287 {
288 found_area = _panel_titlebar_grab_area->FindAreaUnderMouse(mouse_position, event_type);
289 NUX_RETURN_VALUE_IF_NOTNULL(found_area, found_area);
290 }
291
292 if (!_is_own_window)
293 {
294 found_area = _menu_layout->FindAreaUnderMouse(mouse_position, event_type);
295 NUX_RETURN_VALUE_IF_NOTNULL(found_area, found_area);
296 }
297
298 return View::FindAreaUnderMouse(mouse_position, event_type);
299}284}
300285
301long PanelMenuView::PostLayoutManagement(long LayoutResult)286void PanelMenuView::PreLayoutManagement()
302{287{
303 long res = View::PostLayoutManagement(LayoutResult);288 PanelIndicatorsView::PreLayoutManagement();
304 int old_window_buttons_w, new_window_buttons_w;289 nux::Geometry const& geo = GetGeometry();
305 int old_menu_area_w, new_menu_area_w;290
306
307 nux::Geometry geo = GetGeometry();
308
309 int h_padding = _padding - 2;
310 int v_padding = 1;
311
312 old_window_buttons_w = _window_buttons->GetContentWidth();
313 _window_buttons->SetGeometry(geo.x + h_padding, geo.y + v_padding, old_window_buttons_w, geo.height);
314 _window_buttons->ComputeContentSize();291 _window_buttons->ComputeContentSize();
315 new_window_buttons_w = _window_buttons->GetContentWidth();292 int buttons_diff = geo.height - _window_buttons->GetContentHeight();
316293 _window_buttons->SetBaseY(buttons_diff > 0 ? std::ceil(buttons_diff/2.0f) : 0);
317 /* Explicitly set the size and position of the widgets */294
318 geo.x += h_padding + new_window_buttons_w + h_padding;295 layout_->ComputeContentSize();
319 geo.width -= h_padding + new_window_buttons_w + h_padding;296 int layout_width = layout_->GetContentWidth();
320297
321 old_menu_area_w = _menu_layout->GetContentWidth();298 _titlebar_grab_area->SetBaseX(layout_width);
322 _menu_layout->SetGeometry(geo.x, geo.y, old_menu_area_w, geo.height);299 _titlebar_grab_area->SetBaseHeight(geo.height);
323 _menu_layout->ComputeContentSize();300 _titlebar_grab_area->SetMinimumWidth(geo.width - layout_width);
324 new_menu_area_w = _menu_layout->GetContentWidth();301 _titlebar_grab_area->SetMaximumWidth(geo.width - layout_width);
325302
326 geo.x += new_menu_area_w;303 SetMaximumEntriesWidth(geo.width - _window_buttons->GetContentWidth());
327 geo.width -= new_menu_area_w;
328
329 _panel_titlebar_grab_area->SetGeometry(geo.x, geo.y, geo.width, geo.height);
330
331 if (_is_inside)
332 NeedRedraw();
333
334 return res;
335}304}
336305
337void306void PanelMenuView::OnFadeInChanged(double opacity)
338PanelMenuView::OnFadeInChanged(double opacity)
339{307{
340 if (DrawMenus() && GetOpacity() != 1.0f)308 if (DrawMenus() && GetOpacity() != 1.0f)
341 SetOpacity(opacity);309 SetOpacity(opacity);
@@ -343,11 +311,10 @@
343 if (DrawWindowButtons() && _window_buttons->GetOpacity() != 1.0f)311 if (DrawWindowButtons() && _window_buttons->GetOpacity() != 1.0f)
344 _window_buttons->SetOpacity(opacity);312 _window_buttons->SetOpacity(opacity);
345313
346 NeedRedraw();314 QueueDraw();
347}315}
348316
349void317void PanelMenuView::OnFadeOutChanged(double progress)
350PanelMenuView::OnFadeOutChanged(double progress)
351{318{
352 double opacity = CLAMP(1.0f - progress, 0.0f, 1.0f);319 double opacity = CLAMP(1.0f - progress, 0.0f, 1.0f);
353320
@@ -357,13 +324,16 @@
357 if (!DrawWindowButtons() && _window_buttons->GetOpacity() != 0.0f)324 if (!DrawWindowButtons() && _window_buttons->GetOpacity() != 0.0f)
358 _window_buttons->SetOpacity(opacity);325 _window_buttons->SetOpacity(opacity);
359326
360 NeedRedraw();327 QueueDraw();
361}328}
362329
363bool330bool PanelMenuView::DrawMenus() const
364PanelMenuView::DrawMenus()
365{331{
366 if (!_is_own_window && !_places_showing && _we_control_active && !_switcher_showing)332 auto wm = WindowManager::Default();
333 bool screen_grabbed = (wm->IsExpoActive() || wm->IsScaleActive());
334
335 if (_we_control_active && !_overlay_showing && !screen_grabbed &&
336 !_switcher_showing && !_launcher_keynav)
367 {337 {
368 if (_is_inside || _last_active_view || _show_now_activated || _new_application)338 if (_is_inside || _last_active_view || _show_now_activated || _new_application)
369 {339 {
@@ -374,13 +344,16 @@
374 return false;344 return false;
375}345}
376346
377bool347bool PanelMenuView::DrawWindowButtons() const
378PanelMenuView::DrawWindowButtons()
379{348{
380 if (_places_showing)349 auto wm = WindowManager::Default();
350 bool screen_grabbed = (wm->IsExpoActive() || wm->IsScaleActive());
351
352 if (_overlay_showing)
381 return true;353 return true;
382354
383 if (!_is_own_window && _we_control_active && _is_maximized && !_switcher_showing)355 if (_we_control_active && _is_maximized && !screen_grabbed &&
356 !_launcher_keynav && !_switcher_showing)
384 {357 {
385 if (_is_inside || _show_now_activated || _new_application)358 if (_is_inside || _show_now_activated || _new_application)
386 {359 {
@@ -391,19 +364,18 @@
391 return false;364 return false;
392}365}
393366
394void367void PanelMenuView::Draw(nux::GraphicsEngine& GfxContext, bool force_draw)
395PanelMenuView::Draw(nux::GraphicsEngine& GfxContext, bool force_draw)
396{368{
397 nux::Geometry geo = GetGeometry();369 nux::Geometry const& geo = GetGeometry();
398 int button_width = _padding + _window_buttons->GetContentWidth() + _padding;370 int button_width = _window_buttons->GetContentWidth();
399 float factor = 4;371 const float factor = 4;
400 button_width /= factor;372 button_width /= factor;
401373
402 if (geo.width != _last_width || geo.height != _last_height)374 if (geo != _last_geo)
403 {375 {
404 _last_width = geo.width;376 _last_geo = geo;
405 _last_height = geo.height;377 QueueRelayout();
406 Refresh();378 Refresh(true);
407 }379 }
408380
409 GfxContext.PushClippingRectangle(geo);381 GfxContext.PushClippingRectangle(geo);
@@ -417,7 +389,7 @@
417 nux::ColorLayer layer(nux::Color(0x00000000), true, rop);389 nux::ColorLayer layer(nux::Color(0x00000000), true, rop);
418 nux::GetPainter().PushDrawLayer(GfxContext, GetGeometry(), &layer);390 nux::GetPainter().PushDrawLayer(GfxContext, GetGeometry(), &layer);
419391
420 if (_title_layer && !_is_own_window)392 if (_title_texture)
421 {393 {
422 guint blend_alpha = 0, blend_src = 0, blend_dest = 0;394 guint blend_alpha = 0, blend_src = 0, blend_dest = 0;
423 bool draw_menus = DrawMenus();395 bool draw_menus = DrawMenus();
@@ -429,7 +401,7 @@
429401
430 for (auto entry : entries_)402 for (auto entry : entries_)
431 {403 {
432 if (entry.second->IsEntryValid())404 if (entry.second->IsVisible())
433 {405 {
434 has_menu = true;406 has_menu = true;
435 break;407 break;
@@ -542,20 +514,22 @@
542 geo.width, geo.height,514 geo.width, geo.height,
543 _gradient_texture, texxform0,515 _gradient_texture, texxform0,
544 nux::color::White,516 nux::color::White,
545 _title_layer->GetDeviceTexture(),517 _title_texture->GetDeviceTexture(),
546 texxform1,518 texxform1,
547 nux::color::White);519 nux::color::White);
548 }520 }
549 else if (!_places_showing)521 else if (!_overlay_showing)
550 {522 {
523 double title_opacity = 0.0f;
524
551 if (_we_control_active && _window_buttons->GetOpacity() == 0.0 &&525 if (_we_control_active && _window_buttons->GetOpacity() == 0.0 &&
552 (!has_menu || (has_menu && GetOpacity() == 0.0)))526 (!has_menu || (has_menu && GetOpacity() == 0.0)))
553 {527 {
554 nux::GetPainter().PushDrawLayer(GfxContext, geo, _title_layer);528 title_opacity = 1.0f;
555 }529 }
556 else530 else
557 {531 {
558 double title_opacity = 1.0f;532 title_opacity = 1.0f;
559533
560 if (has_menu)534 if (has_menu)
561 title_opacity -= MAX(GetOpacity(), _window_buttons->GetOpacity());535 title_opacity -= MAX(GetOpacity(), _window_buttons->GetOpacity());
@@ -572,10 +546,13 @@
572 // If we're fading-in the buttons/menus, let's fade-out quickly the title546 // If we're fading-in the buttons/menus, let's fade-out quickly the title
573 title_opacity = CLAMP(title_opacity - 0.2f, 0.0f, 1.0f);547 title_opacity = CLAMP(title_opacity - 0.2f, 0.0f, 1.0f);
574 }548 }
549 }
575550
551 if (title_opacity > 0.0f)
552 {
576 nux::TexCoordXForm texxform;553 nux::TexCoordXForm texxform;
577 GfxContext.QRP_1Tex(geo.x, geo.y, geo.width, geo.height,554 GfxContext.QRP_1Tex(geo.x, geo.y, geo.width, geo.height,
578 _title_layer->GetDeviceTexture(), texxform,555 _title_texture->GetDeviceTexture(), texxform,
579 nux::color::White * title_opacity);556 nux::color::White * title_opacity);
580 }557 }
581 }558 }
@@ -588,10 +565,9 @@
588 GfxContext.PopClippingRectangle();565 GfxContext.PopClippingRectangle();
589}566}
590567
591void568void PanelMenuView::DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw)
592PanelMenuView::DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw)
593{569{
594 nux::Geometry geo = GetGeometry();570 nux::Geometry const& geo = GetGeometry();
595 bool draw_menus = DrawMenus();571 bool draw_menus = DrawMenus();
596 bool draw_buttons = DrawWindowButtons();572 bool draw_buttons = DrawWindowButtons();
597573
@@ -602,17 +578,17 @@
602 for (auto entry : entries_)578 for (auto entry : entries_)
603 entry.second->SetDisabled(false);579 entry.second->SetDisabled(false);
604580
605 _menu_layout->ProcessDraw(GfxContext, true);581 layout_->ProcessDraw(GfxContext, true);
606582
607 _fade_out_animator->Stop();583 _fade_out_animator.Stop();
608584
609 if (_new_application && !_is_inside)585 if (_new_application && !_is_inside)
610 {586 {
611 _fade_in_animator->Start(_menus_discovery_fadein, GetOpacity());587 _fade_in_animator.Start(_menus_discovery_fadein, GetOpacity());
612 }588 }
613 else589 else
614 {590 {
615 _fade_in_animator->Start(GetOpacity());591 _fade_in_animator.Start(GetOpacity());
616 _new_app_menu_shown = false;592 _new_app_menu_shown = false;
617 }593 }
618 }594 }
@@ -622,19 +598,19 @@
622 entry.second->SetDisabled(true);598 entry.second->SetDisabled(true);
623 }599 }
624600
625 if (GetOpacity() != 0.0f && !draw_menus)601 if (GetOpacity() != 0.0f && !draw_menus && !_overlay_showing)
626 {602 {
627 _menu_layout->ProcessDraw(GfxContext, true);603 layout_->ProcessDraw(GfxContext, true);
628604
629 _fade_in_animator->Stop();605 _fade_in_animator.Stop();
630606
631 if (!_new_app_menu_shown)607 if (!_new_app_menu_shown)
632 {608 {
633 _fade_out_animator->Start(1.0f - GetOpacity());609 _fade_out_animator.Start(1.0f - GetOpacity());
634 }610 }
635 else611 else
636 {612 {
637 _fade_out_animator->Start(_menus_discovery_fadeout, 1.0f - GetOpacity());613 _fade_out_animator.Start(_menus_discovery_fadeout, 1.0f - GetOpacity());
638 }614 }
639 }615 }
640616
@@ -642,299 +618,260 @@
642 {618 {
643 _window_buttons->ProcessDraw(GfxContext, true);619 _window_buttons->ProcessDraw(GfxContext, true);
644620
645 _fade_out_animator->Stop();621 if (_window_buttons->GetOpacity() != 1.0f)
646 _fade_in_animator->Start(_window_buttons->GetOpacity());622 {
623 _fade_out_animator.Stop();
624 _fade_in_animator.Start(_window_buttons->GetOpacity());
625 }
647 }626 }
648627
649 if (_window_buttons->GetOpacity() != 0.0f && !draw_buttons)628 if (_window_buttons->GetOpacity() != 0.0f && !draw_buttons)
650 {629 {
651 _window_buttons->ProcessDraw(GfxContext, true);630 _window_buttons->ProcessDraw(GfxContext, true);
652 _fade_in_animator->Stop();631 _fade_in_animator.Stop();
653632
654 /* If we try to hide only the buttons, then use a faster fadeout */633 /* If we try to hide only the buttons, then use a faster fadeout */
655 if (!_fade_out_animator->IsRunning())634 if (!_fade_out_animator.IsRunning())
656 {635 {
657 _fade_out_animator->Start(_menus_fadeout/3, 1.0f - _window_buttons->GetOpacity());636 _fade_out_animator.Start(_menus_fadeout/3, 1.0f - _window_buttons->GetOpacity());
658 }637 }
659 }638 }
660639
661 GfxContext.PopClippingRectangle();640 GfxContext.PopClippingRectangle();
662}641}
663642
664gchar*643std::string PanelMenuView::GetActiveViewName(bool use_appname) const
665PanelMenuView::GetActiveViewName()
666{644{
667 gchar* label = nullptr;645 std::string label;
668 BamfWindow* window;646 BamfWindow* window;
669
670 _is_own_window = false;
671647
672 window = bamf_matcher_get_active_window(_matcher);648 window = bamf_matcher_get_active_window(_matcher);
649
673 if (BAMF_IS_WINDOW(window))650 if (BAMF_IS_WINDOW(window))
674 {651 {
652 BamfView *view = reinterpret_cast<BamfView*>(window);
675 std::vector<Window> const& our_xids = nux::XInputWindow::NativeHandleList();653 std::vector<Window> const& our_xids = nux::XInputWindow::NativeHandleList();
676 guint32 window_xid = bamf_window_get_xid(BAMF_WINDOW(window));654 Window window_xid = bamf_window_get_xid(window);
677655
678 if (std::find(our_xids.begin(), our_xids.end(), window_xid) != our_xids.end())656 if (std::find(our_xids.begin(), our_xids.end(), window_xid) != our_xids.end())
679 {657 {
680 _is_own_window = true;658 /* If the active window is an unity window, we need to fallback to the
681 return g_strdup("");659 * top one, anyway we should always avoid to focus unity internal windows */
682 }660 BamfWindow* top_win = GetBamfWindowForXid(GetTopWindow());
683661
684 if (BAMF_IS_WINDOW(window) &&662 if (top_win && top_win != window)
685 bamf_window_get_window_type(window) == BAMF_WINDOW_DESKTOP)663 {
686 {664 window = top_win;
687 label = g_strdup(_("Ubuntu Desktop"));665 }
688 }666 else
689 else if (!WindowManager::Default()->IsWindowOnCurrentDesktop(window_xid) ||667 {
690 WindowManager::Default()->IsWindowObscured(window_xid))668 return "";
691 {669 }
692 return g_strdup("");670 }
693 }671
694672 if (bamf_window_get_window_type(window) == BAMF_WINDOW_DESKTOP)
695 if (_is_maximized)673 {
696 label = bamf_view_get_name(BAMF_VIEW(window));674 label = DESKTOP_NAME;
697 }675 }
698676 else if (!IsValidWindow(window_xid))
699 if (!label)677 {
700 {678 return "";
701 BamfApplication* app = bamf_matcher_get_active_application(_matcher);679 }
702 if (BAMF_IS_APPLICATION(app))680
703 {681 if (WindowManager::Default()->IsWindowMaximized(window_xid) && !use_appname)
704 const gchar* filename;682 {
705683 label = glib::String(bamf_view_get_name(view)).Str();
706 filename = bamf_application_get_desktop_file(app);684 }
707685
708 if (filename && g_strcmp0(filename, "") != 0)686 if (label.empty())
709 {687 {
710 GDesktopAppInfo* info;688 BamfApplication* app;
711689 app = bamf_matcher_get_application_for_window(_matcher, window);
712 info = g_desktop_app_info_new_from_filename(bamf_application_get_desktop_file(app));690
713691 if (BAMF_IS_APPLICATION(app))
714 if (info)692 {
715 {693 view = reinterpret_cast<BamfView*>(app);
716 label = g_strdup(g_app_info_get_display_name(G_APP_INFO(info)));694 label = glib::String(bamf_view_get_name(view)).Str();
717 g_object_unref(info);695 }
718 }696 }
719 else697
720 {698 if (label.empty())
721 g_warning("Unable to get GDesktopAppInfo for %s",699 {
722 bamf_application_get_desktop_file(app));700 view = reinterpret_cast<BamfView*>(window);
723 }701 label = glib::String(bamf_view_get_name(view)).Str();
724 }702 }
725703 }
726 if (label == nullptr)
727 {
728 BamfView* active_view;
729
730 active_view = (BamfView*)bamf_matcher_get_active_window(_matcher);
731 if (BAMF_IS_VIEW(active_view))
732 label = bamf_view_get_name(active_view);
733 else
734 label = g_strdup("");
735 }
736 }
737 else
738 {
739 label = g_strdup(" ");
740 }
741 }
742
743 char *escaped = g_markup_escape_text(label, -1);
744 g_free(label);
745 label = g_strdup_printf("<b>%s</b>", escaped);
746 g_free(escaped);
747704
748 return label;705 return label;
749}706}
750707
751void PanelMenuView::DrawText(cairo_t *cr_real,708void PanelMenuView::DrawTitle(cairo_t *cr_real, nux::Geometry const& geo, std::string const& label) const
752 int &x, int y, int width, int height,
753 const char* font_desc,
754 const char* label,
755 int increase_size
756 )
757{709{
758 PangoLayout* layout = nullptr;710 using namespace panel;
759 PangoFontDescription* desc = nullptr;711 cairo_t* cr;
760 GtkSettings* settings = gtk_settings_get_default();712 cairo_pattern_t* linpat;
761 cairo_t* cr;713 const int fading_pixels = 35;
762 cairo_pattern_t* linpat;714 int x = MAIN_LEFT_PADDING + TITLE_PADDING + geo.x;
763 GdkScreen* screen = gdk_screen_get_default();715 int y = geo.y;
764 int dpi = 0;716
765 const int fading_pixels = 35;717 int text_width = 0;
766 char *font_description = g_strdup(font_desc);718 int text_height = 0;
767719 int text_space = 0;
768 int text_width = 0;720
769 int text_height = 0;721 // Find out dimensions first
770 int text_space = 0;722 GdkScreen* screen = gdk_screen_get_default();
771723 PangoContext* cxt;
772 { // Find out dimensions first724 PangoRectangle log_rect;
773 GConfClient* client = gconf_client_get_default();725 PangoFontDescription* desc;
774 PangoContext* cxt;726
775 PangoRectangle log_rect;727 nux::CairoGraphics util_cg(CAIRO_FORMAT_ARGB32, 1, 1);
776728 cr = util_cg.GetContext();
777 cr = _util_cg.GetContext();729
778730 int dpi = Style::Instance().GetTextDPI();
779 g_object_get(settings, "gtk-xft-dpi", &dpi, nullptr);731
780732 std::string font_description(Style::Instance().GetFontDescription(PanelItem::TITLE));
781 font_description = gconf_client_get_string(client, WINDOW_TITLE_FONT_KEY.c_str(), nullptr);733 desc = pango_font_description_from_string(font_description.c_str());
782 desc = pango_font_description_from_string(font_description);734
783735 glib::Object<PangoLayout> layout(pango_cairo_create_layout(cr));
784 if (font_desc)736 pango_layout_set_font_description(layout, desc);
785 {737 pango_layout_set_markup(layout, label.c_str(), -1);
786 int size = pango_font_description_get_size(desc);738
787 size /= pango_font_description_get_size_is_absolute(desc) ? 1 : PANGO_SCALE;739 cxt = pango_layout_get_context(layout);
788740 pango_cairo_context_set_font_options(cxt, gdk_screen_get_font_options(screen));
789 // Adjust y depending on size of the font741 pango_cairo_context_set_resolution(cxt, dpi / static_cast<float>(PANGO_SCALE));
790 y -= ((unsigned int)(size - 9)) / 2;742 pango_layout_context_changed(layout);
791743
792 size += increase_size;744 pango_layout_get_extents(layout, nullptr, &log_rect);
793745 text_width = log_rect.width / PANGO_SCALE;
794 char* description = g_strdup_printf("%s %d", font_desc, size);746 text_height = log_rect.height / PANGO_SCALE;
795 pango_font_description_free(desc);747
796 desc = pango_font_description_from_string(description);748 pango_font_description_free(desc);
797 g_free(description);749 cairo_destroy(cr);
798 }750
799751 // Draw the text
800 layout = pango_cairo_create_layout(cr);752 GtkStyleContext* style_context = Style::Instance().GetStyleContext();
801 pango_layout_set_font_description(layout, desc);753 text_space = geo.width - x;
802 pango_layout_set_markup(layout, label, -1);754 cr = cr_real;
803755 cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
804 cxt = pango_layout_get_context(layout);756
805 pango_cairo_context_set_font_options(cxt, gdk_screen_get_font_options(screen));757 gtk_style_context_save(style_context);
806 pango_cairo_context_set_resolution(cxt, (float)dpi / (float)PANGO_SCALE);758
807 pango_layout_context_changed(layout);759 GtkWidgetPath* widget_path = gtk_widget_path_new();
808760 gtk_widget_path_append_type(widget_path, GTK_TYPE_MENU_BAR);
809 pango_layout_get_extents(layout, nullptr, &log_rect);761 gtk_widget_path_append_type(widget_path, GTK_TYPE_MENU_ITEM);
810 text_width = log_rect.width / PANGO_SCALE;762 gtk_widget_path_iter_set_name(widget_path, -1 , "UnityPanelWidget");
811 text_height = log_rect.height / PANGO_SCALE;763
812764 gtk_style_context_set_path(style_context, widget_path);
813 pango_font_description_free(desc);765 gtk_style_context_add_class(style_context, GTK_STYLE_CLASS_MENUBAR);
814 g_free(font_description);766 gtk_style_context_add_class(style_context, GTK_STYLE_CLASS_MENUITEM);
815 cairo_destroy(cr);767
816 g_object_unref(client);768 y += (geo.height - text_height) / 2;
817 }769
818770 pango_cairo_update_layout(cr, layout);
819 { // Draw the text771
820 GtkStyleContext* style_context = panel::Style::Instance().GetStyleContext();772 if (text_width > text_space)
821 text_space = width - x;773 {
822 cr = cr_real;774 int out_pixels = text_width - text_space;
823775 int fading_width = out_pixels < fading_pixels ? out_pixels : fading_pixels;
824 gtk_style_context_save(style_context);776
825777 cairo_push_group(cr);
826 GtkWidgetPath* widget_path = gtk_widget_path_new();778 gtk_render_layout(style_context, cr, x, y, layout);
827 gint pos = gtk_widget_path_append_type(widget_path, GTK_TYPE_WINDOW);779 cairo_pop_group_to_source(cr);
828 gtk_widget_path_iter_set_name(widget_path, pos, "UnityPanelWidget");780
829 gtk_widget_path_append_type(widget_path, GTK_TYPE_MENU_BAR);781 linpat = cairo_pattern_create_linear(geo.width - fading_width, y, geo.width, y);
830 gtk_widget_path_append_type(widget_path, GTK_TYPE_MENU_ITEM);782 cairo_pattern_add_color_stop_rgba(linpat, 0, 0, 0, 0, 1);
831783 cairo_pattern_add_color_stop_rgba(linpat, 1, 0, 0, 0, 0);
832 gtk_style_context_set_path(style_context, widget_path);784 cairo_mask(cr, linpat);
833 gtk_style_context_add_class(style_context, GTK_STYLE_CLASS_MENUBAR);785
834 gtk_style_context_add_class(style_context, GTK_STYLE_CLASS_MENUITEM);786 cairo_pattern_destroy(linpat);
835787 }
836 y += (height - text_height) / 2;788 else
837789 {
838 pango_cairo_update_layout(cr, layout);790 gtk_render_layout(style_context, cr, x, y, layout);
839791 }
840 if (text_width > text_space)792
841 {793 x += text_width;
842 int out_pixels = text_width - text_space;794
843 int fading_width = out_pixels < fading_pixels ? out_pixels : fading_pixels;795 gtk_widget_path_free(widget_path);
844796 gtk_style_context_restore(style_context);
845 cairo_push_group(cr);
846 gtk_render_layout(style_context, cr, x, y, layout);
847 cairo_pop_group_to_source(cr);
848
849 linpat = cairo_pattern_create_linear(width - fading_width, y, width, y);
850 cairo_pattern_add_color_stop_rgba(linpat, 0, 0, 0, 0, 1);
851 cairo_pattern_add_color_stop_rgba(linpat, 1, 0, 0, 0, 0);
852 cairo_mask(cr, linpat);
853
854 cairo_pattern_destroy(linpat);
855 }
856 else
857 {
858 gtk_render_layout(style_context, cr, x, y, layout);
859 }
860
861 x += text_width;
862
863 gtk_widget_path_free(widget_path);
864 gtk_style_context_restore(style_context);
865 }
866
867 if (layout)
868 g_object_unref(layout);
869}797}
870798
871void799void PanelMenuView::Refresh(bool force)
872PanelMenuView::Refresh()
873{800{
874 nux::Geometry geo = GetGeometry();801 nux::Geometry const& geo = GetGeometry();
875802
876 // We can get into a race that causes the geometry to be wrong as there hasn't been a803 // We can get into a race that causes the geometry to be wrong as there hasn't been a
877 // layout cycle before the first callback. This is to protect from that.804 // layout cycle before the first callback. This is to protect from that.
878 if (geo.width > _monitor_geo.width)805 if (geo.width > _monitor_geo.width)
879 return;806 return;
880807
881 int x = 0;808 auto win_manager = WindowManager::Default();
882 int y = 0;809 std::string new_title;
883 int width = geo.width;810
884 int height = geo.height;811 if (win_manager->IsScaleActive())
885812 {
886 nux::CairoGraphics cairo_graphics(CAIRO_FORMAT_ARGB32, width, height);813 if (win_manager->IsScaleActiveForGroup())
814 new_title = GetActiveViewName(true);
815 else if (_we_control_active)
816 new_title = DESKTOP_NAME;
817 }
818 else if (win_manager->IsExpoActive())
819 {
820 new_title = DESKTOP_NAME;
821 }
822 else if (!_we_control_active)
823 {
824 new_title = "";
825 }
826 else if (!_switcher_showing && !_launcher_keynav)
827 {
828 new_title = GetActiveViewName();
829 _window_buttons->SetControlledWindow(_active_xid);
830 }
831
832 if (!_switcher_showing && !_launcher_keynav)
833 {
834 if (_panel_title != new_title)
835 {
836 _panel_title = new_title;
837 }
838 else if (!force && _last_geo == geo && _title_texture)
839 {
840 // No need to redraw the title, let's save some CPU time!
841 return;
842 }
843 }
844
845 if (_panel_title.empty())
846 {
847 _title_texture = nullptr;
848 return;
849 }
850
851 nux::CairoGraphics cairo_graphics(CAIRO_FORMAT_ARGB32, geo.width, geo.height);
887 cairo_t* cr = cairo_graphics.GetContext();852 cairo_t* cr = cairo_graphics.GetContext();
888 cairo_set_line_width(cr, 1);
889853
890 cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);854 cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);
891 cairo_paint(cr);855 cairo_paint(cr);
892856
893 cairo_set_operator(cr, CAIRO_OPERATOR_OVER);857 glib::String escaped(g_markup_escape_text(_panel_title.c_str(), -1));
894858
895 x = _padding;859 std::ostringstream bold_label;
896 y = 0;860 bold_label << "<b>" << escaped.Str() << "</b>";
897861
898 if (_panel_title)862 DrawTitle(cr, geo, bold_label.str());
899 {
900 DrawText(cr, x, y, width, height, nullptr, _panel_title);
901 }
902 else
903 {
904 char* title = GetActiveViewName();
905 DrawText(cr, x, y, width, height, nullptr, title);
906 g_free(title);
907 }
908863
909 cairo_destroy(cr);864 cairo_destroy(cr);
910865
911 nux::BaseTexture* texture2D = texture_from_cairo_graphics(cairo_graphics);866 _title_texture = texture_ptr_from_cairo_graphics(cairo_graphics);
912
913 if (_title_layer)
914 delete _title_layer;
915
916 nux::TexCoordXForm texxform;
917 texxform.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD);
918 texxform.SetWrap(nux::TEXWRAP_REPEAT, nux::TEXWRAP_REPEAT);
919
920 nux::ROPConfig rop;
921 rop.Blend = true;
922 rop.SrcBlend = GL_ONE;
923 rop.DstBlend = GL_ONE_MINUS_SRC_ALPHA;
924 _title_layer = new nux::TextureLayer(texture2D->GetDeviceTexture(),
925 texxform,
926 nux::color::White,
927 true,
928 rop);
929 texture2D->UnReference();
930}867}
931868
932void869void PanelMenuView::OnActiveChanged(PanelIndicatorEntryView* view, bool is_active)
933PanelMenuView::OnActiveChanged(PanelIndicatorEntryView* view,
934 bool is_active)
935{870{
936 if (is_active)871 if (is_active)
872 {
937 _last_active_view = view;873 _last_active_view = view;
874 }
938 else875 else
939 {876 {
940 if (_last_active_view == view)877 if (_last_active_view == view)
@@ -947,37 +884,36 @@
947 FullRedraw();884 FullRedraw();
948}885}
949886
950void887void PanelMenuView::OnEntryAdded(indicator::Entry::Ptr const& entry)
951PanelMenuView::OnEntryAdded(unity::indicator::Entry::Ptr const& entry)
952{888{
953 auto view = AddEntry(entry, 6, IndicatorEntryPosition::END, IndicatorEntryType::MENU);889 PanelIndicatorEntryView* view;
890
891 view = new PanelIndicatorEntryView(entry, MENU_ENTRIES_PADDING, IndicatorEntryType::MENU);
892 view->mouse_enter.connect(sigc::mem_fun(this, &PanelMenuView::OnPanelViewMouseEnter));
893 view->mouse_leave.connect(sigc::mem_fun(this, &PanelMenuView::OnPanelViewMouseLeave));
954894
955 entry->show_now_changed.connect(sigc::mem_fun(this, &PanelMenuView::UpdateShowNow));895 entry->show_now_changed.connect(sigc::mem_fun(this, &PanelMenuView::UpdateShowNow));
956
957 view->active_changed.connect(sigc::mem_fun(this, &PanelMenuView::OnActiveChanged));896 view->active_changed.connect(sigc::mem_fun(this, &PanelMenuView::OnActiveChanged));
958 view->mouse_enter.connect(sigc::mem_fun(this, &PanelMenuView::OnPanelViewMouseEnter));897
959 view->mouse_leave.connect(sigc::mem_fun(this, &PanelMenuView::OnPanelViewMouseLeave));898 AddEntryView(view, IndicatorEntryPosition::END);
960}899}
961900
962void901void PanelMenuView::NotifyAllMenusClosed()
963PanelMenuView::AllMenusClosed()
964{902{
965 auto mouse = nux::GetGraphicsDisplay()->GetMouseScreenCoord();
966 _is_inside = GetAbsoluteGeometry().IsPointInside(mouse.x, mouse.y);
967 _last_active_view = nullptr;903 _last_active_view = nullptr;
968904
905 auto mouse = nux::GetGraphicsDisplay()->GetMouseScreenCoord();
906 _is_inside = GetAbsoluteGeometry().IsInside(mouse);
969 FullRedraw();907 FullRedraw();
970}908}
971909
972void910void PanelMenuView::OnNameChanged(BamfView* bamf_view, gchar* new_name, gchar* old_name)
973PanelMenuView::OnNameChanged(BamfView* bamf_view, gchar* new_name, gchar* old_name)
974{911{
975 Refresh();912 Refresh();
976 FullRedraw();913 FullRedraw();
977}914}
978915
979gboolean916gboolean PanelMenuView::OnNewAppShow(PanelMenuView* self)
980PanelMenuView::OnNewAppShow(PanelMenuView* self)
981{917{
982 BamfApplication* active_app = bamf_matcher_get_active_application(self->_matcher);918 BamfApplication* active_app = bamf_matcher_get_active_application(self->_matcher);
983 self->_new_application = glib::Object<BamfApplication>(active_app, glib::AddRef());919 self->_new_application = glib::Object<BamfApplication>(active_app, glib::AddRef());
@@ -998,10 +934,9 @@
998 return FALSE;934 return FALSE;
999}935}
1000936
1001gboolean937gboolean PanelMenuView::OnNewAppHide(PanelMenuView* self)
1002PanelMenuView::OnNewAppHide(PanelMenuView* self)
1003{938{
1004 self->OnViewClosed(self->_matcher, BAMF_VIEW(self->_new_application.RawPtr()));939 self->OnApplicationClosed(self->_new_application);
1005 self->_new_app_hide_id = 0;940 self->_new_app_hide_id = 0;
1006 self->_new_app_menu_shown = true;941 self->_new_app_menu_shown = true;
1007 self->QueueDraw();942 self->QueueDraw();
@@ -1009,8 +944,7 @@
1009 return FALSE;944 return FALSE;
1010}945}
1011946
1012void947void PanelMenuView::OnViewOpened(BamfMatcher *matcher, BamfView *view)
1013PanelMenuView::OnViewOpened(BamfMatcher *matcher, BamfView *view)
1014{948{
1015 /* FIXME: here we should also check for if the view is also user_visible949 /* FIXME: here we should also check for if the view is also user_visible
1016 * but it seems that BAMF doesn't handle this correctly after some950 * but it seems that BAMF doesn't handle this correctly after some
@@ -1021,27 +955,48 @@
1021 _new_apps.push_front(glib::Object<BamfApplication>(BAMF_APPLICATION(view), glib::AddRef()));955 _new_apps.push_front(glib::Object<BamfApplication>(BAMF_APPLICATION(view), glib::AddRef()));
1022}956}
1023957
1024void958void PanelMenuView::OnApplicationClosed(BamfApplication* app)
1025PanelMenuView::OnViewClosed(BamfMatcher *matcher, BamfView *view)
1026{959{
1027 if (!BAMF_IS_APPLICATION(view))960 if (BAMF_IS_APPLICATION(app))
1028 return;
1029
1030 BamfApplication* app = BAMF_APPLICATION(view);
1031
1032 if (std::find(_new_apps.begin(), _new_apps.end(), app) != _new_apps.end())
1033 {961 {
1034 _new_apps.remove(glib::Object<BamfApplication>(app, glib::AddRef()));962 if (std::find(_new_apps.begin(), _new_apps.end(), app) != _new_apps.end())
1035963 {
1036 if (_new_application == app || _new_apps.empty())964 _new_apps.remove(glib::Object<BamfApplication>(app, glib::AddRef()));
965 }
966 else if (_new_apps.empty())
967 {
1037 _new_application = nullptr;968 _new_application = nullptr;
1038 }969 }
1039}970 }
1040971
1041void972 if (app == _new_application)
1042PanelMenuView::OnActiveAppChanged(BamfMatcher *matcher,973 {
1043 BamfApplication* old_app,974 _new_application = nullptr;
1044 BamfApplication* new_app)975 }
976}
977
978void PanelMenuView::OnViewClosed(BamfMatcher *matcher, BamfView *view)
979{
980 if (BAMF_IS_APPLICATION(view))
981 {
982 OnApplicationClosed(reinterpret_cast<BamfApplication*>(view));
983 }
984 else if (reinterpret_cast<BamfApplication*>(view) == _new_application)
985 {
986 _new_application = nullptr;
987 }
988 else if (BAMF_IS_WINDOW(view))
989 {
990 /* FIXME, this can be removed when window_unmapped WindowManager signal
991 * will emit the proper xid */
992 Window xid = bamf_window_get_xid(reinterpret_cast<BamfWindow*>(view));
993 OnWindowUnmapped(xid);
994 }
995}
996
997void PanelMenuView::OnActiveAppChanged(BamfMatcher *matcher,
998 BamfApplication* old_app,
999 BamfApplication* new_app)
1045{1000{
1046 if (BAMF_IS_APPLICATION(new_app))1001 if (BAMF_IS_APPLICATION(new_app))
1047 {1002 {
@@ -1078,15 +1033,14 @@
1078 }1033 }
10791034
1080 if (_new_application)1035 if (_new_application)
1081 OnViewClosed(matcher, BAMF_VIEW(_new_application.RawPtr()));1036 OnApplicationClosed(_new_application);
1082 }1037 }
1083 }1038 }
1084}1039}
10851040
1086void1041void PanelMenuView::OnActiveWindowChanged(BamfMatcher *matcher,
1087PanelMenuView::OnActiveWindowChanged(BamfMatcher *matcher,1042 BamfView* old_view,
1088 BamfView* old_view,1043 BamfView* new_view)
1089 BamfView* new_view)
1090{1044{
1091 _show_now_activated = false;1045 _show_now_activated = false;
1092 _is_maximized = false;1046 _is_maximized = false;
@@ -1100,15 +1054,16 @@
11001054
1101 if (BAMF_IS_WINDOW(new_view))1055 if (BAMF_IS_WINDOW(new_view))
1102 {1056 {
1103 BamfWindow* window = BAMF_WINDOW(new_view);1057 WindowManager *wm = WindowManager::Default();
1104 guint32 xid = _active_xid = bamf_window_get_xid(window);1058 BamfWindow* window = reinterpret_cast<BamfWindow*>(new_view);
1105 _is_maximized = WindowManager::Default()->IsWindowMaximized(xid);1059 guint32 xid = bamf_window_get_xid(window);
1106 nux::Geometry geo = WindowManager::Default()->GetWindowGeometry(xid);1060 _active_xid = xid;
1061 _is_maximized = wm->IsWindowMaximized(xid);
11071062
1108 if (bamf_window_get_window_type(window) == BAMF_WINDOW_DESKTOP)1063 if (bamf_window_get_window_type(window) == BAMF_WINDOW_DESKTOP)
1109 _we_control_active = true;1064 _we_control_active = true;
1110 else1065 else
1111 _we_control_active = UScreen::GetDefault()->GetMonitorGeometry(_monitor).IsPointInside(geo.x + (geo.width / 2), geo.y);1066 _we_control_active = IsWindowUnderOurControl(xid);
11121067
1113 if (_decor_map.find(xid) == _decor_map.end())1068 if (_decor_map.find(xid) == _decor_map.end())
1114 {1069 {
@@ -1117,9 +1072,9 @@
1117 // if we've just started tracking this window and it is maximized, let's1072 // if we've just started tracking this window and it is maximized, let's
1118 // make sure it's undecorated just in case it slipped by us earlier1073 // make sure it's undecorated just in case it slipped by us earlier
1119 // (I'm looking at you, Chromium!)1074 // (I'm looking at you, Chromium!)
1120 if (_is_maximized && WindowManager::Default ()->IsWindowDecorated(xid))1075 if (_is_maximized && wm->IsWindowDecorated(xid))
1121 {1076 {
1122 WindowManager::Default()->Undecorate(xid);1077 wm->Undecorate(xid);
1123 _maximized_set.insert(xid);1078 _maximized_set.insert(xid);
1124 }1079 }
1125 }1080 }
@@ -1130,103 +1085,128 @@
1130 // register callback for new view1085 // register callback for new view
1131 _view_name_changed_signal.Connect(new_view, "name-changed",1086 _view_name_changed_signal.Connect(new_view, "name-changed",
1132 sigc::mem_fun(this, &PanelMenuView::OnNameChanged));1087 sigc::mem_fun(this, &PanelMenuView::OnNameChanged));
1088
1089 _window_buttons->SetControlledWindow(_is_maximized ? _active_xid : 0);
1133 }1090 }
11341091
1135 Refresh();1092 Refresh();
1136 FullRedraw();1093 FullRedraw();
1137}1094}
11381095
1139void1096void PanelMenuView::OnSpreadInitiate()
1140PanelMenuView::OnSpreadInitiate()1097{
1141{1098 /*foreach (guint32 &xid, windows)
1142 /*foreach (guint32 &xid, windows)1099 {
1143 {1100 if (WindowManager::Default()->IsWindowMaximized(xid))
1144 if (WindowManager::Default ()->IsWindowMaximized (xid))1101 WindowManager::Default()->Decorate(xid);
1145 WindowManager::Default ()->Decorate (xid);1102 }*/
1146 }*/1103
1147}1104 Refresh();
11481105 QueueDraw();
1149void1106}
1150PanelMenuView::OnSpreadTerminate()1107
1151{1108void PanelMenuView::OnSpreadTerminate()
1152 /*foreach (guint32 &xid, windows)1109{
1153 {1110 /*foreach (guint32 &xid, windows)
1154 if (WindowManager::Default ()->IsWindowMaximized (xid))1111 {
1155 WindowManager::Default ()->Undecorate (xid);1112 if (WindowManager::Default()->IsWindowMaximized(xid))
1156 }*/1113 WindowManager::Default()->Undecorate(xid);
1157}1114 }*/
11581115
1159void1116 Refresh();
1160PanelMenuView::OnWindowMinimized(guint32 xid)1117 QueueDraw();
1161{1118}
1162 if (WindowManager::Default()->IsWindowMaximized(xid))1119
1163 {1120void PanelMenuView::OnExpoInitiate()
1164 WindowManager::Default()->Decorate(xid);1121{
1165 _maximized_set.erase(xid);1122 Refresh();
1166 }1123 QueueDraw();
1167}1124}
11681125
1169void1126void PanelMenuView::OnExpoTerminate()
1170PanelMenuView::OnWindowUnminimized(guint32 xid)1127{
1171{1128 Refresh();
1172 if (WindowManager::Default()->IsWindowMaximized(xid))1129 QueueDraw();
1173 {1130}
1174 WindowManager::Default()->Undecorate(xid);1131
1175 _maximized_set.insert(xid);1132void PanelMenuView::OnWindowMinimized(guint32 xid)
1176 }1133{
1177}1134 if (WindowManager::Default()->IsWindowMaximized(xid))
11781135 {
1179void1136 WindowManager::Default()->Decorate(xid);
1180PanelMenuView::OnWindowUnmapped(guint32 xid)1137 _maximized_set.erase(xid);
1181{1138
1182 if (WindowManager::Default()->IsWindowMaximized(xid))1139 Refresh();
1183 {1140 QueueDraw();
1184 WindowManager::Default()->Decorate(xid);1141 }
1185 _maximized_set.erase(xid);1142}
1186 }1143
1187}1144void PanelMenuView::OnWindowUnminimized(guint32 xid)
11881145{
1189void1146 if (WindowManager::Default()->IsWindowMaximized(xid))
1190PanelMenuView::OnWindowMapped(guint32 xid)1147 {
1191{1148 WindowManager::Default()->Undecorate(xid);
1192 if (WindowManager::Default()->IsWindowMaximized(xid))1149 _maximized_set.insert(xid);
1193 {1150
1194 WindowManager::Default()->Undecorate(xid);1151 Refresh();
1195 _maximized_set.insert(xid);1152 QueueDraw();
1196 }1153 }
1197}1154}
11981155
1199void1156void PanelMenuView::OnWindowUnmapped(guint32 xid)
1200PanelMenuView::OnWindowDecorated(guint32 xid)1157{
1158 // FIXME: compiz doesn't give us a valid xid (is always 0 on unmap)
1159 // we need to do this again on BamfView closed signal.
1160 if (_maximized_set.find(xid) != _maximized_set.end())
1161 {
1162 WindowManager::Default()->Decorate(xid);
1163 _maximized_set.erase(xid);
1164 _decor_map.erase(xid);
1165
1166 Refresh();
1167 QueueDraw();
1168 }
1169}
1170
1171void PanelMenuView::OnWindowMapped(guint32 xid)
1172{
1173 if (WindowManager::Default()->IsWindowMaximized(xid))
1174 {
1175 WindowManager::Default()->Undecorate(xid);
1176 _maximized_set.insert(xid);
1177
1178 Refresh();
1179 QueueDraw();
1180 }
1181}
1182
1183void PanelMenuView::OnWindowDecorated(guint32 xid)
1201{1184{
1202 _decor_map[xid] = true;1185 _decor_map[xid] = true;
12031186
1204 if (_maximized_set.find(xid) != _maximized_set.end ())1187 if (_maximized_set.find(xid) != _maximized_set.end ())
1205 {1188 {
1206 WindowManager::Default ()->Undecorate(xid);1189 WindowManager::Default()->Undecorate(xid);
1207 }1190 }
1208}1191}
12091192
1210void1193void PanelMenuView::OnWindowUndecorated(guint32 xid)
1211PanelMenuView::OnWindowUndecorated(guint32 xid)
1212{1194{
1213 _decor_map[xid] = false;1195 _decor_map[xid] = false;
1214}1196}
12151197
1216void1198void PanelMenuView::OnWindowMaximized(guint xid)
1217PanelMenuView::OnWindowMaximized(guint xid)
1218{1199{
1219 BamfWindow* window;
1220 bool updated = false;1200 bool updated = false;
1201 bool is_active = (_active_xid == xid);
12211202
1222 window = bamf_matcher_get_active_window(_matcher);1203 if (is_active)
1223 if (BAMF_IS_WINDOW(window) && bamf_window_get_xid(window) == xid)
1224 {1204 {
1205 // We need to update the _is_inside state in the case of maximization by grab
1206 auto mouse = nux::GetGraphicsDisplay()->GetMouseScreenCoord();
1207 _is_inside = GetAbsoluteGeometry().IsInside(mouse);
1208
1225 _is_maximized = true;1209 _is_maximized = true;
1226
1227 // We need to update the _is_inside state in the case of maximization by grab
1228 auto mouse = nux::GetGraphicsDisplay()->GetMouseScreenCoord();
1229 _is_inside = GetAbsoluteGeometry().IsPointInside(mouse.x, mouse.y);
1230 updated = true;1210 updated = true;
1231 }1211 }
12321212
@@ -1245,16 +1225,12 @@
1245 }1225 }
1246}1226}
12471227
1248void1228void PanelMenuView::OnWindowRestored(guint xid)
1249PanelMenuView::OnWindowRestored(guint xid)
1250{1229{
1251 BamfWindow* window;
1252
1253 if (_maximized_set.find(xid) == _maximized_set.end())1230 if (_maximized_set.find(xid) == _maximized_set.end())
1254 return;1231 return;
12551232
1256 window = bamf_matcher_get_active_window(_matcher);1233 if (_active_xid == xid)
1257 if (BAMF_IS_WINDOW(window) && bamf_window_get_xid(window) == xid)
1258 {1234 {
1259 _is_maximized = false;1235 _is_maximized = false;
1260 _is_grabbed = false;1236 _is_grabbed = false;
@@ -1269,193 +1245,272 @@
1269 FullRedraw();1245 FullRedraw();
1270}1246}
12711247
1272gboolean1248gboolean PanelMenuView::UpdateActiveWindowPosition(PanelMenuView* self)
1273PanelMenuView::UpdateActiveWindowPosition(PanelMenuView* self)
1274{1249{
1275 auto window_geo = WindowManager::Default()->GetWindowGeometry(self->_active_xid);1250 bool we_control_window = self->IsWindowUnderOurControl(self->_active_xid);
1276 auto monitor_geo = UScreen::GetDefault()->GetMonitorGeometry(self->_monitor);1251
1277 auto intersect = monitor_geo.Intersect(window_geo);1252 if (we_control_window != self->_we_control_active)
12781253 {
1279 self->_we_control_active = (intersect.width > window_geo.width/4 &&1254 self->_we_control_active = we_control_window;
1280 intersect.height > window_geo.height/4);1255
1256 self->Refresh();
1257 self->QueueDraw();
1258 }
12811259
1282 self->_active_moved_id = 0;1260 self->_active_moved_id = 0;
1283 self->QueueDraw();
12841261
1285 return FALSE;1262 return FALSE;
1286}1263}
12871264
1288void1265void PanelMenuView::OnWindowMoved(guint xid)
1289PanelMenuView::OnWindowMoved(guint xid)
1290{1266{
1291 if (_active_xid == xid)1267 if (_active_xid == xid)
1292 {1268 {
1293 if (_active_moved_id)1269 /* When moving the active window, if the current panel is controlling
1294 g_source_remove(_active_moved_id);1270 * the active window, then we postpone the timeout function every movement
12951271 * that we have, setting a longer timeout.
1296 if (!_we_control_active)1272 * Otherwise, if the moved window is not controlled by the current panel
1297 UpdateActiveWindowPosition(this);1273 * every few millisecond we check the new window position */
1298 else1274
1299 _active_moved_id = g_timeout_add(250, (GSourceFunc)PanelMenuView::UpdateActiveWindowPosition, this);1275 unsigned int timeout = 250;
1300 }1276
1301}1277 if (_we_control_active)
13021278 {
1303void1279 if (_active_moved_id)
1304PanelMenuView::OnCloseClicked()1280 g_source_remove(_active_moved_id);
1305{1281 }
1306 if (_places_showing)1282 else
1307 {1283 {
1308 ubus_server_send_message(ubus_server_get_default(), UBUS_PLACE_VIEW_CLOSE_REQUEST, nullptr);1284 timeout = 60;
1309 }1285
1310 else1286 if (_active_moved_id)
1311 {1287 return;
1312 BamfWindow* window;1288 }
13131289
1314 window = bamf_matcher_get_active_window(_matcher);1290 _active_moved_id = g_timeout_add(timeout, (GSourceFunc)UpdateActiveWindowPosition, this);
1315 if (BAMF_IS_WINDOW(window))1291 }
1316 {1292}
1317 WindowManager::Default()->Close(bamf_window_get_xid(window));1293
1318 NeedRedraw();1294bool PanelMenuView::IsWindowUnderOurControl(Window xid) const
1319 }1295{
1320 }1296 if (UScreen::GetDefault()->GetMonitors().size() > 1)
1321}1297 {
13221298 auto wm = WindowManager::Default();
1323void1299 nux::Geometry const& window_geo = wm->GetWindowGeometry(xid);
1324PanelMenuView::OnMinimizeClicked()1300 nux::Geometry const& intersect = _monitor_geo.Intersect(window_geo);
1325{1301
1326 if (_places_showing)1302 /* We only care of the horizontal window portion */
1327 {1303 return (intersect.width > window_geo.width/2 && intersect.height > 0);
1328 // no action when dash is opened, LP bug #8388751304 }
1329 return;1305
1330 }1306 return true;
1331 else1307}
1332 {1308
1333 BamfWindow* window;1309bool PanelMenuView::IsValidWindow(Window xid) const
13341310{
1335 window = bamf_matcher_get_active_window(_matcher);1311 auto wm = WindowManager::Default();
1336 if (BAMF_IS_WINDOW(window))1312 std::vector<Window> const& our_xids = nux::XInputWindow::NativeHandleList();
1337 {1313
1338 WindowManager::Default()->Minimize(bamf_window_get_xid(window));1314 if (wm->IsWindowOnCurrentDesktop(xid) && !wm->IsWindowObscured(xid) &&
1339 NeedRedraw();1315 wm->IsWindowVisible(xid) && IsWindowUnderOurControl(xid) &&
1340 }1316 std::find(our_xids.begin(), our_xids.end(), xid) == our_xids.end())
1341 }1317 {
1342}1318 return true;
13431319 }
1344void1320
1345PanelMenuView::OnRestoreClicked()1321 return false;
1346{1322}
1347 if (_places_showing)1323
1348 {1324Window PanelMenuView::GetMaximizedWindow() const
1349 if (dash::Settings::Instance().GetFormFactor() == dash::FormFactor::DESKTOP)1325{
1350 dash::Settings::Instance().SetFormFactor(dash::FormFactor::NETBOOK);1326 Window window_xid = 0;
1351 else
1352 dash::Settings::Instance().SetFormFactor(dash::FormFactor::DESKTOP);
1353 }
1354 else
1355 {
1356 BamfWindow* window;
1357
1358 window = bamf_matcher_get_active_window(_matcher);
1359 if (BAMF_IS_WINDOW(window))
1360 {
1361 WindowManager::Default()->Restore(bamf_window_get_xid(window));
1362 NeedRedraw();
1363 }
1364 }
1365}
1366
1367guint32
1368PanelMenuView::GetMaximizedWindow()
1369{
1370 guint32 window_xid = 0;
1371 nux::Geometry monitor = UScreen::GetDefault()->GetMonitorGeometry(_monitor);
13721327
1373 // Find the front-most of the maximized windows we are controlling1328 // Find the front-most of the maximized windows we are controlling
1374 for (auto xid : _maximized_set)1329 for (auto xid : _maximized_set)
1375 {1330 {
1376 // We can safely assume only the front-most is visible1331 // We can safely assume only the front-most is visible
1377 if (WindowManager::Default()->IsWindowOnCurrentDesktop(xid)1332 if (IsValidWindow(xid))
1378 && !WindowManager::Default()->IsWindowObscured(xid))1333 {
1379 {1334 window_xid = xid;
1380 nux::Geometry geo = WindowManager::Default()->GetWindowGeometry(xid);1335 break;
1381 if (monitor.IsPointInside(geo.x + (geo.width / 2), geo.y))1336 }
1337 }
1338
1339 return window_xid;
1340}
1341
1342Window PanelMenuView::GetTopWindow() const
1343{
1344 Window window_xid = 0;
1345 GList* windows = bamf_matcher_get_window_stack_for_monitor(_matcher, _monitor);
1346
1347 for (GList* l = windows; l; l = l->next)
1348 {
1349 if (!BAMF_IS_WINDOW(l->data))
1350 continue;
1351
1352 Window xid = bamf_window_get_xid(static_cast<BamfWindow*>(l->data));
1353 bool visible = bamf_view_user_visible(static_cast<BamfView*>(l->data));
1354
1355 if (visible && IsValidWindow(xid))
1356 {
1357 window_xid = xid;
1358 }
1359 }
1360
1361 g_list_free(windows);
1362
1363 return window_xid;
1364}
1365
1366BamfWindow* PanelMenuView::GetBamfWindowForXid(Window xid) const
1367{
1368 BamfWindow* window = nullptr;
1369
1370 if (xid != 0)
1371 {
1372 GList* windows = bamf_matcher_get_windows(_matcher);
1373
1374 for (GList* l = windows; l; l = l->next)
1375 {
1376 if (!BAMF_IS_WINDOW(l->data))
1377 continue;
1378
1379 auto win = static_cast<BamfWindow*>(l->data);
1380
1381 if (bamf_window_get_xid(win) == xid)
1382 {1382 {
1383 window_xid = xid;1383 window = win;
1384 break;1384 break;
1385 }1385 }
1386 }1386 }
1387 }1387
1388 return window_xid;1388 g_list_free(windows);
1389}1389 }
13901390
1391void1391 return window;
1392PanelMenuView::OnMaximizedGrabStart(int x, int y, unsigned long button_flags, unsigned long)1392}
1393{1393
1394 Window maximized_win;1394void PanelMenuView::OnMaximizedActivate(int x, int y)
1395 if (nux::GetEventButton(button_flags) != 1 || _places_showing)1395{
1396 return;1396 Window maximized = GetMaximizedWindow();
13971397
1398 // When Start dragging the panelmenu of a maximized window, change cursor1398 if (maximized != 0)
1399 // to simulate the dragging, waiting to go out of the panel area.1399 {
1400 //1400 WindowManager::Default()->Activate(maximized);
1401 // This is a workaround to avoid that the grid plugin would be fired1401 }
1402 // showing the window shape preview effect. See bug #8389231402}
14031403
1404 maximized_win = GetMaximizedWindow ();1404void PanelMenuView::OnMaximizedRestore(int x, int y)
14051405{
1406 if (maximized_win != 0)1406 if (_overlay_showing)
1407 return;
1408
1409 Window maximized = GetMaximizedWindow();
1410
1411 if (maximized != 0)
1412 {
1413 WindowManager::Default()->Restore(maximized);
1414 _is_inside = true;
1415 }
1416}
1417
1418void PanelMenuView::OnMaximizedLower(int x, int y)
1419{
1420 if (_overlay_showing)
1421 return;
1422
1423 Window maximized = GetMaximizedWindow();
1424
1425 if (maximized != 0)
1426 {
1427 WindowManager::Default()->Lower(maximized);
1428 }
1429}
1430
1431void PanelMenuView::OnMaximizedGrabStart(int x, int y)
1432{
1433 /* When Start dragging the panelmenu of a maximized window, change cursor
1434 * to simulate the dragging, waiting to go out of the panel area.
1435 *
1436 * This is a workaround to avoid that the grid plugin would be fired
1437 * showing the window shape preview effect. See bug #838923 */
1438
1439 Window maximized = GetMaximizedWindow();
1440
1441 if (maximized != 0)
1407 {1442 {
1408 /* Always activate the window in case it is on another monitor */1443 /* Always activate the window in case it is on another monitor */
1409 WindowManager::Default ()->Activate (maximized_win);1444 WindowManager::Default()->Activate(maximized);
1410 _panel_titlebar_grab_area->SetGrabbed(true);1445 _titlebar_grab_area->SetGrabbed(true);
1411 }1446 }
1412}1447}
14131448
1414void1449void PanelMenuView::OnMaximizedGrabMove(int x, int y)
1415PanelMenuView::OnMaximizedGrabMove(int x, int y, int, int, unsigned long button_flags, unsigned long)
1416{1450{
1417// FIXME nux doesn't export it with drag event.
1418// if (nux::GetEventButton(button_flags) != 1)
1419// return;
1420
1421 // We use this, due to the problem above
1422 if (!_panel_titlebar_grab_area->IsGrabbed())
1423 return;
1424
1425 auto panel = static_cast<nux::BaseWindow*>(GetTopLevelViewWindow());1451 auto panel = static_cast<nux::BaseWindow*>(GetTopLevelViewWindow());
14261452
1427 if (!panel)1453 if (!panel)
1428 return;1454 return;
14291455
1430 x += _panel_titlebar_grab_area->GetAbsoluteX();1456 /* Adjusting the x, y coordinates to get the absolute values */
1431 y += _panel_titlebar_grab_area->GetAbsoluteY();1457 x += _titlebar_grab_area->GetAbsoluteX();
14321458 y += _titlebar_grab_area->GetAbsoluteY();
1433 guint32 window_xid = GetMaximizedWindow();1459
14341460 Window maximized = GetMaximizedWindow();
1435 // When the drag goes out from the Panel, start the real movement.1461
1436 //1462 /* When the drag goes out from the Panel, start the real movement.
1437 // This is a workaround to avoid that the grid plugin would be fired1463 *
1438 // showing the window shape preview effect. See bug #8389231464 * This is a workaround to avoid that the grid plugin would be fired
1439 if (window_xid != 0 && panel && !panel->GetAbsoluteGeometry().IsPointInside(x, y))1465 * showing the window shape preview effect. See bug #838923 */
1466 if (maximized != 0 && panel)
1440 {1467 {
1441 _panel_titlebar_grab_area->SetGrabbed(false);1468 nux::Geometry const& panel_geo = panel->GetAbsoluteGeometry();
14421469
1443 WindowManager::Default()->Activate(window_xid);1470 if (!panel_geo.IsPointInside(x, y))
1444 _is_inside = true;1471 {
1445 _is_grabbed = true;1472 auto wm = WindowManager::Default();
1446 Refresh();1473 nux::Geometry const& restored_geo = wm->GetWindowSavedGeometry(maximized);
1447 FullRedraw();1474 nux::Geometry const& workarea_geo = wm->GetWorkAreaGeometry(maximized);
1448 WindowManager::Default()->StartMove(window_xid, x, y);1475
1476 /* By default try to restore the window horizontally-centered respect to the
1477 * pointer position, if it doesn't fit on that area try to keep it into the
1478 * current workarea as much as possible, but giving priority to the left border
1479 * that shouldn't be never put out of the workarea */
1480 int restore_x = x - (restored_geo.width * x / panel_geo.width);
1481 int restore_y = y;
1482
1483 if (restore_x + restored_geo.width > workarea_geo.x + workarea_geo.width)
1484 {
1485 restore_x = workarea_geo.x + workarea_geo.width - restored_geo.width;
1486 }
1487
1488 if (restore_x < workarea_geo.x)
1489 {
1490 restore_x = workarea_geo.x;
1491 }
1492
1493 wm->Activate(maximized);
1494 wm->RestoreAt(maximized, restore_x, restore_y);
1495
1496 _is_inside = true;
1497 _is_grabbed = true;
1498 Refresh();
1499 FullRedraw();
1500
1501 /* Ungrab the pointer and start the X move, to make the decorator handle it */
1502 _titlebar_grab_area->SetGrabbed(false);
1503 wm->StartMove(maximized, x, y);
1504 }
1449 }1505 }
1450}1506}
14511507
1452void1508void PanelMenuView::OnMaximizedGrabEnd(int x, int y)
1453PanelMenuView::OnMaximizedGrabEnd(int x, int y, unsigned long, unsigned long)
1454{1509{
1455 _panel_titlebar_grab_area->SetGrabbed(false);1510 _titlebar_grab_area->SetGrabbed(false);
14561511
1457 x += _panel_titlebar_grab_area->GetAbsoluteX();1512 x += _titlebar_grab_area->GetAbsoluteX();
1458 y += _panel_titlebar_grab_area->GetAbsoluteY();1513 y += _titlebar_grab_area->GetAbsoluteY();
1459 _is_inside = GetAbsoluteGeometry().IsPointInside(x, y);1514 _is_inside = GetAbsoluteGeometry().IsPointInside(x, y);
14601515
1461 if (!_is_inside)1516 if (!_is_inside)
@@ -1465,115 +1520,108 @@
1465 FullRedraw();1520 FullRedraw();
1466}1521}
14671522
1468void
1469PanelMenuView::OnMouseDoubleClicked(int x, int y, unsigned long button_flags, unsigned long)
1470{
1471 if (nux::GetEventButton(button_flags) != 1 || _places_showing)
1472 return;
1473
1474 guint32 window_xid = GetMaximizedWindow();
1475
1476 if (window_xid != 0)
1477 {
1478 WindowManager::Default()->Restore(window_xid);
1479 _is_inside = true;
1480 }
1481}
1482
1483void
1484PanelMenuView::OnMouseClicked(int x, int y, unsigned long button_flags, unsigned long)
1485{
1486 if (nux::GetEventButton(button_flags) != 1 || _places_showing)
1487 return;
1488
1489 guint32 window_xid = GetMaximizedWindow();
1490
1491 if (window_xid != 0)
1492 {
1493 WindowManager::Default()->Raise(window_xid);
1494 }
1495}
1496
1497void
1498PanelMenuView::OnMouseMiddleClicked(int x, int y, unsigned long button_flags, unsigned long)
1499{
1500 if (nux::GetEventButton(button_flags) != 2 || _places_showing)
1501 return;
1502
1503 guint32 window_xid = GetMaximizedWindow();
1504
1505 if (window_xid != 0)
1506 {
1507 WindowManager::Default()->Lower(window_xid);
1508 }
1509}
1510
1511// Introspectable1523// Introspectable
1512std::string1524std::string
1513PanelMenuView::GetName() const1525PanelMenuView::GetName() const
1514{1526{
1515 return "";1527 return "MenuView";
1516}1528}
15171529
1518void PanelMenuView::AddProperties(GVariantBuilder* builder)1530void PanelMenuView::AddProperties(GVariantBuilder* builder)
1519{1531{
1520}1532 PanelIndicatorsView::AddProperties(builder);
15211533
1522void PanelMenuView::OnPlaceViewShown(GVariant* data, PanelMenuView* self)1534 variant::BuilderWrapper(builder)
1523{1535 .add("mouse_inside", _is_inside)
1524 self->_places_showing = true;1536 .add("grabbed", _is_grabbed)
1525 self->QueueDraw();1537 .add("active_win_maximized", _is_maximized)
1526}1538 .add("panel_title", _panel_title)
15271539 .add("monitor", _monitor)
1528void PanelMenuView::OnPlaceViewHidden(GVariant* data, PanelMenuView* self)1540 .add("active_window", _active_xid)
1529{1541 .add("draw_menus", DrawMenus())
1530 self->_places_showing = false;1542 .add("draw_window_buttons", DrawWindowButtons())
1531 self->QueueDraw();1543 .add("controls_active_window", _we_control_active);
1532}1544}
15331545
1534void PanelMenuView::OnSwitcherShown(GVariant* data, PanelMenuView* self)1546void PanelMenuView::OnSwitcherShown(GVariant* data)
1535{1547{
1536 if (!self || !data)1548 if (!data)
1537 return;1549 return;
15381550
1539 self->_switcher_showing = g_variant_get_boolean(data);1551 bool switcher_shown;
15401552 int monitor;
1541 if (!self->_switcher_showing)1553 g_variant_get(data, "(bi)", &switcher_shown, &monitor);
1554
1555 if (switcher_shown == _switcher_showing || monitor != _monitor)
1556 return;
1557
1558 _switcher_showing = switcher_shown;
1559
1560 if (!_switcher_showing)
1542 {1561 {
1543 auto mouse = nux::GetGraphicsDisplay()->GetMouseScreenCoord();1562 auto mouse = nux::GetGraphicsDisplay()->GetMouseScreenCoord();
1544 self->_is_inside = self->GetAbsoluteGeometry().IsPointInside(mouse.x, mouse.y);1563 _is_inside = GetAbsoluteGeometry().IsInside(mouse);
1545
1546 if (self->_panel_title)
1547 {
1548 g_free(self->_panel_title);
1549 self->_panel_title = nullptr;
1550 }
1551 }1564 }
1552 else1565 else
1553 {1566 {
1554 self->_show_now_activated = false;1567 _show_now_activated = false;
1555 }1568 }
15561569
1557 self->Refresh();1570 Refresh();
1558 self->QueueDraw();1571 QueueDraw();
1559}1572}
15601573
1561void PanelMenuView::OnSwitcherSelectionChanged(GVariant* data, PanelMenuView* self)1574void PanelMenuView::OnSwitcherSelectionChanged(GVariant* data)
1562{1575{
1563 if (!self || !data)1576 if (!data || !_switcher_showing)
1564 return;1577 return;
15651578
1566 if (self->_panel_title)1579 const gchar *title = g_variant_get_string(data, 0);
1567 g_free(self->_panel_title);1580 _panel_title = (title ? title : "");
15681581
1569 self->_panel_title = g_strdup(g_variant_get_string(data, 0));1582 Refresh();
15701583 QueueDraw();
1571 self->Refresh();1584}
1572 self->QueueDraw();1585
1573}1586void PanelMenuView::OnLauncherKeyNavStarted(GVariant* data)
15741587{
1575gboolean1588 if (_launcher_keynav)
1576PanelMenuView::UpdateShowNowWithDelay(PanelMenuView *self)1589 return;
1590
1591
1592 if (!data || (data && g_variant_get_int32(data) == _monitor))
1593 {
1594 _launcher_keynav = true;
1595 }
1596}
1597
1598void PanelMenuView::OnLauncherKeyNavEnded(GVariant* data)
1599{
1600 if (!_launcher_keynav)
1601 return;
1602
1603 _launcher_keynav = false;
1604
1605 auto mouse = nux::GetGraphicsDisplay()->GetMouseScreenCoord();
1606 _is_inside = GetAbsoluteGeometry().IsInside(mouse);
1607
1608 Refresh();
1609 QueueDraw();
1610}
1611
1612void PanelMenuView::OnLauncherSelectionChanged(GVariant* data)
1613{
1614 if (!data || !_launcher_keynav)
1615 return;
1616
1617 const gchar *title = g_variant_get_string(data, 0);
1618 _panel_title = (title ? title : "");
1619
1620 Refresh();
1621 QueueDraw();
1622}
1623
1624gboolean PanelMenuView::UpdateShowNowWithDelay(PanelMenuView *self)
1577{1625{
1578 bool active = false;1626 bool active = false;
15791627
@@ -1597,8 +1645,7 @@
1597 return FALSE;1645 return FALSE;
1598}1646}
15991647
1600void1648void PanelMenuView::UpdateShowNow(bool status)
1601PanelMenuView::UpdateShowNow(bool status)
1602{1649{
1603 /* When we get a show now event, if we are requested to show the menus,1650 /* When we get a show now event, if we are requested to show the menus,
1604 * we take the last incoming event and we wait for small delay (to avoid the1651 * we take the last incoming event and we wait for small delay (to avoid the
@@ -1610,6 +1657,7 @@
1610 {1657 {
1611 _show_now_activated = false;1658 _show_now_activated = false;
1612 QueueDraw();1659 QueueDraw();
1660 return;
1613 }1661 }
16141662
1615 if (_update_show_now_id != 0)1663 if (_update_show_now_id != 0)
@@ -1626,27 +1674,55 @@
1626 }1674 }
1627}1675}
16281676
1629void1677void PanelMenuView::SetMonitor(int monitor)
1630PanelMenuView::SetMonitor(int monitor)
1631{1678{
1632 _monitor = monitor;1679 _monitor = monitor;
1633 _monitor_geo = UScreen::GetDefault()->GetMonitorGeometry(_monitor);1680 _monitor_geo = UScreen::GetDefault()->GetMonitorGeometry(_monitor);
1681
1682 _maximized_set.clear();
1683 GList* windows = bamf_matcher_get_window_stack_for_monitor(_matcher, _monitor);
1684
1685 for (GList* l = windows; l; l = l->next)
1686 {
1687 if (!BAMF_IS_WINDOW(l->data))
1688 continue;
1689
1690 auto window = static_cast<BamfWindow*>(l->data);
1691 auto view = static_cast<BamfView*>(l->data);
1692
1693 if (bamf_view_is_active(view))
1694 {
1695 _active_xid = bamf_window_get_xid(window);
1696 }
1697
1698 if (bamf_window_maximized(window) == BAMF_WINDOW_MAXIMIZED)
1699 {
1700 Window xid = bamf_window_get_xid(window);
1701
1702 _decor_map[xid] = WindowManager::Default()->IsWindowDecorated(xid);
1703
1704 if (_decor_map[xid])
1705 WindowManager::Default()->Undecorate(xid);
1706
1707 _maximized_set.insert(xid);
1708 }
1709 }
1710
1711 Window maximized = GetMaximizedWindow();
1712 Window buttons_win = (maximized == _active_xid) ? maximized : 0;
1713
1714 _window_buttons->SetMonitor(_monitor);
1715 _window_buttons->SetControlledWindow(buttons_win);
1716
1717 g_list_free(windows);
1634}1718}
16351719
1636bool1720bool PanelMenuView::GetControlsActive() const
1637PanelMenuView::GetControlsActive()
1638{1721{
1639 return _we_control_active;1722 return _we_control_active;
1640}1723}
16411724
1642bool1725void PanelMenuView::OnPanelViewMouseEnter(int x, int y, unsigned long mouse_button_state, unsigned long special_keys_state)
1643PanelMenuView::HasOurWindowFocused()
1644{
1645 return _is_own_window;
1646}
1647
1648void
1649PanelMenuView::OnPanelViewMouseEnter(int x, int y, unsigned long mouse_button_state, unsigned long special_keys_state)
1650{1726{
1651 if (!_is_inside)1727 if (!_is_inside)
1652 {1728 {
@@ -1659,8 +1735,7 @@
1659 }1735 }
1660}1736}
16611737
1662void1738void PanelMenuView::OnPanelViewMouseLeave(int x, int y, unsigned long mouse_button_state, unsigned long special_keys_state)
1663PanelMenuView::OnPanelViewMouseLeave(int x, int y, unsigned long mouse_button_state, unsigned long special_keys_state)
1664{1739{
1665 if (_is_inside)1740 if (_is_inside)
1666 {1741 {
16671742
=== modified file 'plugins/unityshell/src/PanelMenuView.h'
--- plugins/unityshell/src/PanelMenuView.h 2012-03-21 12:31:11 +0000
+++ plugins/unityshell/src/PanelMenuView.h 2012-04-05 23:42:20 +0000
@@ -1,6 +1,6 @@
1// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-1// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
2/*2/*
3 * Copyright (C) 2010 Canonical Ltd3 * Copyright (C) 2010-2012 Canonical Ltd
4 *4 *
5 * This program is free software: you can redistribute it and/or modify5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as6 * it under the terms of the GNU General Public License version 3 as
@@ -15,14 +15,15 @@
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *16 *
17 * Authored by: Neil Jagdish Patel <neil.patel@canonical.com>17 * Authored by: Neil Jagdish Patel <neil.patel@canonical.com>
18 * Marco Trevisan <3v1n0@ubuntu.com>
18 */19 */
1920
20#ifndef PANEL_MENU_VIEW_H21#ifndef PANEL_MENU_VIEW_H
21#define PANEL_MENU_VIEW_H22#define PANEL_MENU_VIEW_H
2223
23#include <Nux/View.h>24#include <UnityCore/GLibWrapper.h>
24#include <map>25#include <UnityCore/GLibSignal.h>
25#include <set>26#include <libbamf/libbamf.h>
2627
27#include "PanelIndicatorsView.h"28#include "PanelIndicatorsView.h"
28#include "StaticCairoText.h"29#include "StaticCairoText.h"
@@ -30,10 +31,7 @@
30#include "PanelTitlebarGrabAreaView.h"31#include "PanelTitlebarGrabAreaView.h"
31#include "PluginAdapter.h"32#include "PluginAdapter.h"
32#include "Animator.h"33#include "Animator.h"
3334#include "UBusWrapper.h"
34#include <UnityCore/GLibWrapper.h>
35#include <UnityCore/GLibSignal.h>
36#include <libbamf/libbamf.h>
3735
38namespace unity36namespace unity
39{37{
@@ -41,41 +39,50 @@
41class PanelMenuView : public PanelIndicatorsView39class PanelMenuView : public PanelIndicatorsView
42{40{
43public:41public:
44 // This contains all the menubar logic for the Panel. Mainly it contains42 PanelMenuView();
45 // the following states:
46 // 1. Unmaximized window + no mouse hover
47 // 2. Unmaximized window + mouse hover
48 // 3. Unmaximized window + active menu (Alt+F/arrow key nav)
49 // 4. Maximized window + no mouse hover
50 // 5. Maximized window + mouse hover
51 // 6. Maximized window + active menu
52 //
53 // It also deals with undecorating maximized windows (and redecorating them
54 // on unmaximize)
55
56 PanelMenuView(int padding = 6);
57 ~PanelMenuView();43 ~PanelMenuView();
5844
59 void SetMenuShowTimings(int fadein, int fadeout, int discovery,45 void SetMenuShowTimings(int fadein, int fadeout, int discovery,
60 int discovery_fadein, int discovery_fadeout);46 int discovery_fadein, int discovery_fadeout);
6147
62 void FullRedraw();48 void SetMousePosition(int x, int y);
49 void SetMonitor(int monitor);
50
51 Window GetTopWindow() const;
52 Window GetMaximizedWindow() const;
53 bool GetControlsActive() const;
54
55 void NotifyAllMenusClosed();
56
57 virtual void AddIndicator(indicator::Indicator::Ptr const& indicator);
58
59 virtual void OverlayShown();
60 virtual void OverlayHidden();
61
62protected:
63 std::string GetName() const;
64 void AddProperties(GVariantBuilder* builder);
6365
64 virtual void Draw(nux::GraphicsEngine& GfxContext, bool force_draw);66 virtual void Draw(nux::GraphicsEngine& GfxContext, bool force_draw);
65 virtual void DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw);67 virtual void DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw);
66 virtual long PostLayoutManagement(long LayoutResult);68 virtual void PreLayoutManagement();
6769 virtual nux::Area* FindAreaUnderMouse(const nux::Point& mouse_position,
68 void SetMousePosition(int x, int y);70 nux::NuxEventType event_type);
6971 virtual void OnEntryAdded(indicator::Entry::Ptr const& entry);
72
73private:
70 void OnActiveChanged(PanelIndicatorEntryView* view, bool is_active);74 void OnActiveChanged(PanelIndicatorEntryView* view, bool is_active);
71 void OnViewOpened(BamfMatcher* matcher, BamfView* view);75 void OnViewOpened(BamfMatcher* matcher, BamfView* view);
72 void OnViewClosed(BamfMatcher* matcher, BamfView* view);76 void OnViewClosed(BamfMatcher* matcher, BamfView* view);
77 void OnApplicationClosed(BamfApplication* app);
73 void OnActiveWindowChanged(BamfMatcher* matcher, BamfView* old_view, BamfView* new_view);78 void OnActiveWindowChanged(BamfMatcher* matcher, BamfView* old_view, BamfView* new_view);
74 void OnActiveAppChanged(BamfMatcher* matcher, BamfApplication* old_app, BamfApplication* new_app);79 void OnActiveAppChanged(BamfMatcher* matcher, BamfApplication* old_app, BamfApplication* new_app);
75 void OnNameChanged(BamfView* bamf_view, gchar* new_name, gchar* old_name);80 void OnNameChanged(BamfView* bamf_view, gchar* new_name, gchar* old_name);
7681
77 void OnSpreadInitiate();82 void OnSpreadInitiate();
78 void OnSpreadTerminate();83 void OnSpreadTerminate();
84 void OnExpoInitiate();
85 void OnExpoTerminate();
79 void OnWindowMinimized(guint32 xid);86 void OnWindowMinimized(guint32 xid);
80 void OnWindowUnminimized(guint32 xid);87 void OnWindowUnminimized(guint32 xid);
81 void OnWindowUnmapped(guint32 xid);88 void OnWindowUnmapped(guint32 xid);
@@ -86,42 +93,30 @@
86 void OnWindowDecorated(guint32 xid);93 void OnWindowDecorated(guint32 xid);
87 void OnWindowUndecorated(guint32 xid);94 void OnWindowUndecorated(guint32 xid);
8895
89 guint32 GetMaximizedWindow();96 void OnMaximizedActivate(int x, int y);
9097 void OnMaximizedRestore(int x, int y);
91 void OnMaximizedGrabStart(int, int, unsigned long, unsigned long);98 void OnMaximizedLower(int x, int y);
92 void OnMaximizedGrabMove(int, int, int, int, unsigned long, unsigned long);99 void OnMaximizedGrabStart(int x, int y);
93 void OnMaximizedGrabEnd(int, int, unsigned long, unsigned long);100 void OnMaximizedGrabMove(int x, int y);
94 void OnMouseDoubleClicked(int, int, unsigned long, unsigned long);101 void OnMaximizedGrabEnd(int x, int y);
95 void OnMouseClicked(int, int, unsigned long, unsigned long);102
96 void OnMouseMiddleClicked(int, int, unsigned long, unsigned long);103 void FullRedraw();
97104 void Refresh(bool force = false);
98 void Refresh();105 void DrawTitle(cairo_t *cr_real, nux::Geometry const& geo, std::string const& label) const;
99 void AllMenusClosed();106
100
101 void OnCloseClicked();
102 void OnMinimizeClicked();
103 void OnRestoreClicked();
104 void SetMonitor(int monitor);
105 bool GetControlsActive();
106
107 bool HasOurWindowFocused();
108
109protected:
110 std::string GetName() const;
111 void AddProperties(GVariantBuilder* builder);
112
113 virtual nux::Area* FindAreaUnderMouse(const nux::Point& mouse_position, nux::NuxEventType event_type);
114 void OnPanelViewMouseEnter(int x, int y, unsigned long mouse_button_state, unsigned long special_keys_state);107 void OnPanelViewMouseEnter(int x, int y, unsigned long mouse_button_state, unsigned long special_keys_state);
115 void OnPanelViewMouseLeave(int x, int y, unsigned long mouse_button_state, unsigned long special_keys_state);108 void OnPanelViewMouseLeave(int x, int y, unsigned long mouse_button_state, unsigned long special_keys_state);
116 void OnPanelViewMouseMove(int x, int y, int dx, int dy, unsigned long mouse_button_state, unsigned long special_keys_state);109 void OnPanelViewMouseMove(int x, int y, int dx, int dy, unsigned long mouse_button_state, unsigned long special_keys_state);
117 virtual void OnEntryAdded(unity::indicator::Entry::Ptr const& entry);110
118111 BamfWindow* GetBamfWindowForXid(Window xid) const;
119private:112
120 gchar* GetActiveViewName();113 std::string GetActiveViewName(bool use_appname = false) const;
121 static void OnPlaceViewShown(GVariant* data, PanelMenuView* self);114
122 static void OnPlaceViewHidden(GVariant* data, PanelMenuView* self);115 void OnSwitcherShown(GVariant* data);
123 static void OnSwitcherShown(GVariant* data, PanelMenuView* self);116 void OnSwitcherSelectionChanged(GVariant* data);
124 static void OnSwitcherSelectionChanged(GVariant* data, PanelMenuView* self);117 void OnLauncherKeyNavStarted(GVariant* data);
118 void OnLauncherKeyNavEnded(GVariant* data);
119 void OnLauncherSelectionChanged(GVariant* data);
125120
126 void UpdateShowNow(bool ignore);121 void UpdateShowNow(bool ignore);
127122
@@ -130,53 +125,47 @@
130 static gboolean OnNewAppShow(PanelMenuView* self);125 static gboolean OnNewAppShow(PanelMenuView* self);
131 static gboolean OnNewAppHide(PanelMenuView* self);126 static gboolean OnNewAppHide(PanelMenuView* self);
132127
133 void DrawText(cairo_t *cr_real,128 bool IsValidWindow(Window xid) const;
134 int &x, int y, int width, int height,129 bool IsWindowUnderOurControl(Window xid) const;
135 const char* font_desc,
136 const char* label,
137 int increase_size=0
138 );
139130
140 bool DrawMenus();131 bool DrawMenus() const;
141 bool DrawWindowButtons();132 bool DrawWindowButtons() const;
142133
143 void OnFadeInChanged(double);134 void OnFadeInChanged(double);
144 void OnFadeOutChanged(double);135 void OnFadeOutChanged(double);
145136
146private:
147 glib::Object<BamfMatcher> _matcher;137 glib::Object<BamfMatcher> _matcher;
148138
149 nux::TextureLayer* _title_layer;139 nux::TextureLayer* _title_layer;
150 nux::HLayout* _menu_layout;140 nux::HLayout* _menu_layout;
151 nux::CairoGraphics _util_cg;141 nux::ObjectPtr<nux::BaseTexture> _title_texture;
152 nux::ObjectPtr<nux::IOpenGLBaseTexture> _gradient_texture;142 nux::ObjectPtr<nux::IOpenGLBaseTexture> _gradient_texture;
153143
154 bool _is_inside;144 bool _is_inside;
155 bool _is_grabbed;145 bool _is_grabbed;
156 bool _is_maximized;146 bool _is_maximized;
157 bool _is_own_window;147
158 PanelIndicatorEntryView* _last_active_view;148 PanelIndicatorEntryView* _last_active_view;
149 WindowButtons* _window_buttons;
150 PanelTitlebarGrabArea* _titlebar_grab_area;
159 glib::Object<BamfApplication> _new_application;151 glib::Object<BamfApplication> _new_application;
160152
161 WindowButtons* _window_buttons;153 std::map<Window, bool> _decor_map;
162 PanelTitlebarGrabArea* _panel_titlebar_grab_area;154 std::set<Window> _maximized_set;
163
164 std::map<guint32, bool> _decor_map;
165 std::set<guint32> _maximized_set;
166 std::list<glib::Object<BamfApplication>> _new_apps;155 std::list<glib::Object<BamfApplication>> _new_apps;
167156 std::string _panel_title;
168 int _padding;157 nux::Geometry _last_geo;
169 int _last_width;158
170 int _last_height;159 bool _overlay_showing;
171
172 bool _places_showing;
173 bool _switcher_showing;160 bool _switcher_showing;
161 bool _launcher_keynav;
174 bool _show_now_activated;162 bool _show_now_activated;
175 bool _we_control_active;163 bool _we_control_active;
176 bool _new_app_menu_shown;164 bool _new_app_menu_shown;
177165
178 int _monitor;166 int _monitor;
179 guint32 _active_xid;167 Window _active_xid;
168
180 guint32 _active_moved_id;169 guint32 _active_moved_id;
181 guint32 _update_show_now_id;170 guint32 _update_show_now_id;
182 guint32 _new_app_show_id;171 guint32 _new_app_show_id;
@@ -188,8 +177,9 @@
188 glib::Signal<void, BamfMatcher*, BamfView*, BamfView*> _active_win_changed_signal;177 glib::Signal<void, BamfMatcher*, BamfView*, BamfView*> _active_win_changed_signal;
189 glib::Signal<void, BamfMatcher*, BamfApplication*, BamfApplication*> _active_app_changed_signal;178 glib::Signal<void, BamfMatcher*, BamfApplication*, BamfApplication*> _active_app_changed_signal;
190 glib::Signal<void, BamfView*, gchar*, gchar*> _view_name_changed_signal;179 glib::Signal<void, BamfView*, gchar*, gchar*> _view_name_changed_signal;
180 sigc::connection _style_changed_connection;
191181
192 std::vector<unsigned int> _ubus_interests;182 UBusManager _ubus_manager;
193183
194 int _menus_fadein;184 int _menus_fadein;
195 int _menus_fadeout;185 int _menus_fadeout;
@@ -197,10 +187,8 @@
197 int _menus_discovery_fadein;187 int _menus_discovery_fadein;
198 int _menus_discovery_fadeout;188 int _menus_discovery_fadeout;
199189
200 gchar* _panel_title;190 Animator _fade_in_animator;
201191 Animator _fade_out_animator;
202 Animator* _fade_in_animator;
203 Animator* _fade_out_animator;
204};192};
205193
206}194}
207195
=== modified file 'plugins/unityshell/src/PanelTitlebarGrabAreaView.cpp'
--- plugins/unityshell/src/PanelTitlebarGrabAreaView.cpp 2012-02-25 16:19:39 +0000
+++ plugins/unityshell/src/PanelTitlebarGrabAreaView.cpp 2012-04-05 23:42:20 +0000
@@ -1,6 +1,6 @@
1// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-1// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
2/*2/*
3 * Copyright (C) 2010-2011 Canonical Ltd3 * Copyright (C) 2010-2012 Canonical Ltd
4 *4 *
5 * This program is free software: you can redistribute it and/or modify5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as6 * it under the terms of the GNU General Public License version 3 as
@@ -27,17 +27,41 @@
27#include <UnityCore/Variant.h>27#include <UnityCore/Variant.h>
28#include <X11/cursorfont.h>28#include <X11/cursorfont.h>
2929
30namespace unity
31{
32namespace
33{
34 unsigned int MOUSE_DOWN_TIMEOUT = 150;
35 unsigned int MOUSE_MOVEMENT_TOLERANCE = 4;
36}
37
30PanelTitlebarGrabArea::PanelTitlebarGrabArea()38PanelTitlebarGrabArea::PanelTitlebarGrabArea()
31 : InputArea(NUX_TRACKER_LOCATION)39 : InputArea(NUX_TRACKER_LOCATION)
32 , _grab_cursor(None)40 , grab_cursor_(None)
41 , grab_started_(false)
42 , mouse_down_timer_(0)
43 , mouse_down_button_(0)
33{44{
34 EnableDoubleClick(true);45 EnableDoubleClick(true);
46
47 mouse_down.connect(sigc::mem_fun(this, &PanelTitlebarGrabArea::OnMouseDown));
48 mouse_up.connect(sigc::mem_fun(this, &PanelTitlebarGrabArea::OnMouseUp));
49 mouse_drag.connect(sigc::mem_fun(this, &PanelTitlebarGrabArea::OnGrabMove));
50
51 mouse_double_click.connect([&] (int x, int y, unsigned long button_flags, unsigned long)
52 {
53 if (nux::GetEventButton(button_flags) == 1)
54 restore_request.emit(x, y);
55 });
35}56}
3657
37PanelTitlebarGrabArea::~PanelTitlebarGrabArea()58PanelTitlebarGrabArea::~PanelTitlebarGrabArea()
38{59{
39 if (_grab_cursor)60 if (grab_cursor_)
40 XFreeCursor(nux::GetGraphicsDisplay()->GetX11Display(), _grab_cursor);61 XFreeCursor(nux::GetGraphicsDisplay()->GetX11Display(), grab_cursor_);
62
63 if (mouse_down_timer_)
64 g_source_remove(mouse_down_timer_);
41}65}
4266
43void PanelTitlebarGrabArea::SetGrabbed(bool enabled)67void PanelTitlebarGrabArea::SetGrabbed(bool enabled)
@@ -48,32 +72,120 @@
48 if (!panel_window || !display)72 if (!panel_window || !display)
49 return;73 return;
5074
51 if (enabled && !_grab_cursor)75 if (enabled && !grab_cursor_)
52 {76 {
53 _grab_cursor = XCreateFontCursor(display, XC_fleur);77 grab_cursor_ = XCreateFontCursor(display, XC_fleur);
54 XDefineCursor(display, panel_window->GetInputWindowId(), _grab_cursor);78 XDefineCursor(display, panel_window->GetInputWindowId(), grab_cursor_);
55 }79 }
56 else if (!enabled && _grab_cursor)80 else if (!enabled && grab_cursor_)
57 {81 {
58 XUndefineCursor(display, panel_window->GetInputWindowId());82 XUndefineCursor(display, panel_window->GetInputWindowId());
59 XFreeCursor(display, _grab_cursor);83 XFreeCursor(display, grab_cursor_);
60 _grab_cursor = None;84 grab_cursor_ = None;
61 }85 }
62}86}
6387
64bool PanelTitlebarGrabArea::IsGrabbed()88bool PanelTitlebarGrabArea::IsGrabbed()
65{89{
66 return (_grab_cursor != None);90 return (grab_cursor_ != None);
91}
92
93void PanelTitlebarGrabArea::OnMouseDown(int x, int y, unsigned long button_flags, unsigned long)
94{
95 mouse_down_button_ = nux::GetEventButton(button_flags);
96
97 if (mouse_down_button_ == 2)
98 {
99 lower_request.emit(x, y);
100 }
101 else if (mouse_down_button_ == 1)
102 {
103 mouse_down_point_.x = x;
104 mouse_down_point_.y = y;
105
106 mouse_down_timer_ =
107 g_timeout_add(MOUSE_DOWN_TIMEOUT, [] (gpointer data) -> gboolean {
108 auto self = static_cast<PanelTitlebarGrabArea*>(data);
109
110 if (!self->grab_started_)
111 {
112 nux::Point const& mouse = nux::GetGraphicsDisplay()->GetMouseScreenCoord();
113 self->grab_started.emit(mouse.x - self->GetAbsoluteX(), mouse.y - self->GetAbsoluteY());
114 self->grab_started_ = true;
115 }
116
117 self->mouse_down_timer_ = 0;
118 return FALSE;
119 }, this);
120 }
121}
122
123void PanelTitlebarGrabArea::OnMouseUp(int x, int y, unsigned long button_flags, unsigned long)
124{
125 int button = nux::GetEventButton(button_flags);
126
127 if (button == 1)
128 {
129 if (mouse_down_timer_)
130 {
131 g_source_remove(mouse_down_timer_);
132 mouse_down_timer_ = 0;
133
134 activate_request.emit(x, y);
135 }
136
137 if (grab_started_)
138 {
139 grab_end.emit(x, y);
140 grab_started_ = false;
141 }
142 }
143
144 mouse_down_button_ = 0;
145 mouse_down_point_.x = 0;
146 mouse_down_point_.y = 0;
147}
148
149void PanelTitlebarGrabArea::OnGrabMove(int x, int y, int, int, unsigned long button_flags, unsigned long)
150{
151 if (mouse_down_button_ != 1)
152 return;
153
154 if (mouse_down_timer_)
155 {
156 if (abs(mouse_down_point_.x - x) <= MOUSE_MOVEMENT_TOLERANCE &&
157 abs(mouse_down_point_.y - y) <= MOUSE_MOVEMENT_TOLERANCE)
158 {
159 return;
160 }
161
162 g_source_remove(mouse_down_timer_);
163 mouse_down_timer_ = 0;
164 }
165
166 if (!grab_started_)
167 {
168 grab_started.emit(x, y);
169 grab_started_ = true;
170 }
171 else
172 {
173 grab_move.emit(x, y);
174 }
67}175}
68176
69std::string177std::string
70PanelTitlebarGrabArea::GetName() const178PanelTitlebarGrabArea::GetName() const
71{179{
72 return "panel-titlebar-grab-area";180 return "GrabArea";
73}181}
74182
75void183void
76PanelTitlebarGrabArea::AddProperties(GVariantBuilder* builder)184PanelTitlebarGrabArea::AddProperties(GVariantBuilder* builder)
77{185{
78 unity::variant::BuilderWrapper(builder).add(GetGeometry());186 unity::variant::BuilderWrapper(builder)
187 .add(GetGeometry())
188 .add("grabbed", IsGrabbed());
189}
190
79}191}
80192
=== modified file 'plugins/unityshell/src/PanelTitlebarGrabAreaView.h'
--- plugins/unityshell/src/PanelTitlebarGrabAreaView.h 2012-02-25 16:19:39 +0000
+++ plugins/unityshell/src/PanelTitlebarGrabAreaView.h 2012-04-05 23:42:20 +0000
@@ -1,6 +1,6 @@
1// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-1// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
2/*2/*
3 * Copyright (C) 2010-2011 Canonical Ltd3 * Copyright (C) 2010-2012 Canonical Ltd
4 *4 *
5 * This program is free software: you can redistribute it and/or modify5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as6 * it under the terms of the GNU General Public License version 3 as
@@ -27,10 +27,13 @@
2727
28#include "Introspectable.h"28#include "Introspectable.h"
2929
30namespace unity
31{
32
30class PanelTitlebarGrabArea : public nux::InputArea, public unity::debug::Introspectable33class PanelTitlebarGrabArea : public nux::InputArea, public unity::debug::Introspectable
31{34{
32 /* This acts a bit like a titlebar, it can be grabbed (such that we can pull35 /* This acts a bit like a decorator, it can be clicked or grabbed (such that
33 * the window down) */36 * we can pull the window down) */
3437
35public:38public:
36 PanelTitlebarGrabArea();39 PanelTitlebarGrabArea();
@@ -39,11 +42,29 @@
39 void SetGrabbed(bool enabled);42 void SetGrabbed(bool enabled);
40 bool IsGrabbed();43 bool IsGrabbed();
4144
45 sigc::signal<void, int, int> lower_request;
46 sigc::signal<void, int, int> activate_request;
47 sigc::signal<void, int, int> restore_request;
48 sigc::signal<void, int, int> grab_started;
49 sigc::signal<void, int, int> grab_move;
50 sigc::signal<void, int, int> grab_end;
51
52protected:
53 std::string GetName() const;
54 void AddProperties(GVariantBuilder* builder);
55
42private:56private:
43 std::string GetName() const;57 void OnMouseDown(int x, int y, unsigned long button_flags, unsigned long);
44 void AddProperties(GVariantBuilder* builder);58 void OnMouseUp(int x, int y, unsigned long button_flags, unsigned long);
59 void OnGrabMove(int x, int y, int, int, unsigned long button_flags, unsigned long);
4560
46 Cursor _grab_cursor;61 Cursor grab_cursor_;
62 bool grab_started_;
63 guint mouse_down_timer_;
64 nux::Point mouse_down_point_;
65 unsigned int mouse_down_button_;
47};66};
4867
68} // NAMESPACE
69
49#endif70#endif
5071
=== modified file 'plugins/unityshell/src/PanelTray.cpp'
--- plugins/unityshell/src/PanelTray.cpp 2012-03-21 12:31:11 +0000
+++ plugins/unityshell/src/PanelTray.cpp 2012-04-05 23:42:20 +0000
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright (C) 2010 Canonical Ltd2 * Copyright (C) 2010-2012 Canonical Ltd
3 *3 *
4 * This program is free software: you can redistribute it and/or modify4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 3 as5 * it under the terms of the GNU General Public License version 3 as
@@ -14,11 +14,14 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *15 *
16 * Authored by: Neil Jagdish Patel <neil.patel@canonical.com>16 * Authored by: Neil Jagdish Patel <neil.patel@canonical.com>
17 * Marco Trevisan (Treviño) <3v1n0@ubuntu.com>
17 */18 */
1819
19#include "PanelTray.h"20#include "PanelTray.h"
21#include "PanelStyle.h"
2022
21#include <NuxCore/Logger.h>23#include <NuxCore/Logger.h>
24#include <UnityCore/Variant.h>
2225
23namespace26namespace
24{27{
@@ -31,137 +34,118 @@
31{34{
3235
33PanelTray::PanelTray()36PanelTray::PanelTray()
34 : View(NUX_TRACKER_LOCATION),37 : View(NUX_TRACKER_LOCATION)
35 _window(0),38 , settings_(g_settings_new(SETTINGS_NAME.c_str()))
36 _tray(NULL),39 , window_(gtk_window_new(GTK_WINDOW_TOPLEVEL))
37 _last_x(0),40 , whitelist_(g_settings_get_strv(settings_, "systray-whitelist"))
38 _last_y(0),41{
39 _tray_icon_added_id(0)42 int panel_height = panel::Style::Instance().panel_height;
40{43
41 _settings = g_settings_new(SETTINGS_NAME.c_str());44 whitelist_changed_.Connect(settings_, "changed::systray-whitelist", [&] (GSettings*, gchar*) {
42 _whitelist = g_settings_get_strv(_settings, "systray-whitelist");45 g_strfreev(whitelist_);
4346 whitelist_ = g_settings_get_strv(settings_, "systray-whitelist");
44 RealInit();47 });
45}48
4649 auto gtkwindow = glib::object_cast<GtkWindow>(window_);
47unsigned int50 gtk_window_set_type_hint(gtkwindow, GDK_WINDOW_TYPE_HINT_DOCK);
48PanelTray::xid ()51 gtk_window_set_has_resize_grip(gtkwindow, FALSE);
49{52 gtk_window_set_keep_above(gtkwindow, TRUE);
50 if (!_window)53 gtk_window_set_skip_pager_hint(gtkwindow, TRUE);
51 return 0;54 gtk_window_set_skip_taskbar_hint(gtkwindow, TRUE);
5255 gtk_window_resize(gtkwindow, 1, panel_height);
53 return gdk_x11_window_get_xid (gtk_widget_get_window (_window));56 gtk_window_move(gtkwindow, -panel_height,-panel_height);
54}57 gtk_widget_set_name(window_, "UnityPanelApplet");
5558
56void PanelTray::RealInit()59 gtk_widget_set_visual(window_, gdk_screen_get_rgba_visual(gdk_screen_get_default()));
57{60 gtk_widget_realize(window_);
58 _window = gtk_window_new(GTK_WINDOW_TOPLEVEL);61 gtk_widget_set_app_paintable(window_, TRUE);
59 gtk_window_set_type_hint(GTK_WINDOW(_window), GDK_WINDOW_TYPE_HINT_DOCK);62 draw_signal_.Connect(window_, "draw", sigc::mem_fun(this, &PanelTray::OnTrayDraw));
60 gtk_window_set_has_resize_grip(GTK_WINDOW(_window), FALSE);
61 gtk_window_set_keep_above(GTK_WINDOW(_window), TRUE);
62 gtk_window_set_skip_pager_hint(GTK_WINDOW(_window), TRUE);
63 gtk_window_set_skip_taskbar_hint(GTK_WINDOW(_window), TRUE);
64 gtk_window_resize(GTK_WINDOW(_window), 1, 24);
65 gtk_window_move(GTK_WINDOW(_window), -24,-24);
66 gtk_widget_set_name(_window, "UnityPanelApplet");
67
68 gtk_widget_set_visual(_window, gdk_screen_get_rgba_visual(gdk_screen_get_default()));
69 gtk_widget_realize(_window);
70 gtk_widget_set_app_paintable(_window, TRUE);
71 _tray_expose_id = g_signal_connect(_window, "draw", G_CALLBACK(PanelTray::OnTrayDraw), this);
7263
73 if (!g_getenv("UNITY_PANEL_TRAY_DISABLE"))64 if (!g_getenv("UNITY_PANEL_TRAY_DISABLE"))
74 {65 {
75 _tray = na_tray_new_for_screen(gdk_screen_get_default(),66 tray_ = na_tray_new_for_screen(gdk_screen_get_default(),
76 GTK_ORIENTATION_HORIZONTAL,67 GTK_ORIENTATION_HORIZONTAL,
77 (NaTrayFilterCallback)FilterTrayCallback,68 (NaTrayFilterCallback)FilterTrayCallback,
78 this);69 this);
79 na_tray_set_icon_size(_tray, 24);70 na_tray_set_icon_size(tray_, panel_height);
8071
81 _tray_icon_added_id = g_signal_connect(na_tray_get_manager(_tray), "tray_icon_removed",72 icon_removed_signal_.Connect(na_tray_get_manager(tray_), "tray_icon_removed",
82 G_CALLBACK(PanelTray::OnTrayIconRemoved), this);73 sigc::mem_fun(this, &PanelTray::OnTrayIconRemoved));
8374
84 gtk_container_add(GTK_CONTAINER(_window), GTK_WIDGET(_tray));75 gtk_container_add(GTK_CONTAINER(window_.RawPtr()), GTK_WIDGET(tray_.RawPtr()));
85 gtk_widget_show(GTK_WIDGET(_tray));76 gtk_widget_show(GTK_WIDGET(tray_.RawPtr()));
86 }77 }
8778
88 SetMinMaxSize(1, 24);79 SetMinMaxSize(1, panel_height);
89
90}80}
9181
92PanelTray::~PanelTray()82PanelTray::~PanelTray()
93{83{
94 if (_tray)
95 {
96 g_signal_handler_disconnect(na_tray_get_manager(_tray), _tray_icon_added_id);
97 _tray = NULL;
98 }
99
100 g_idle_remove_by_data(this);84 g_idle_remove_by_data(this);
10185 g_strfreev(whitelist_);
102 if (_tray_expose_id)86
103 g_signal_handler_disconnect(_window, _tray_expose_id);87 if (gtk_widget_get_realized(window_))
10488 gtk_widget_destroy(window_);
105 gtk_widget_destroy(_window);89}
106 g_strfreev(_whitelist);90
107 g_object_unref(_settings);91Window PanelTray::xid()
108}92{
10993 if (!window_)
110void94 return 0;
111PanelTray::Draw(nux::GraphicsEngine& gfx_context, bool force_draw)95
112{96 return gdk_x11_window_get_xid(gtk_widget_get_window(window_));
113 nux::Geometry geo(GetAbsoluteGeometry());97}
98
99void PanelTray::Draw(nux::GraphicsEngine& gfx_context, bool force_draw)
100{
101 nux::Geometry const& geo = GetAbsoluteGeometry();
114102
115 gfx_context.PushClippingRectangle(geo);103 gfx_context.PushClippingRectangle(geo);
116 nux::GetPainter().PaintBackground(gfx_context, geo);104 nux::GetPainter().PaintBackground(gfx_context, geo);
117 gfx_context.PopClippingRectangle();105 gfx_context.PopClippingRectangle();
118106
119 if (geo.x != _last_x || geo.y != _last_y)107 if (geo != last_geo_)
120 {108 {
121 _last_x = geo.x;109 last_geo_ = geo;
122 _last_y = geo.y;110 gtk_window_move(GTK_WINDOW(window_.RawPtr()), geo.x + PADDING, geo.y);
123
124 gtk_window_move(GTK_WINDOW(_window), geo.x + PADDING, geo.y);
125 }111 }
126}112}
127113
128void114void PanelTray::Sync()
129PanelTray::Sync()
130{115{
131 if (_tray)116 if (tray_)
132 {117 {
133 SetMinMaxSize(WidthOfTray() + (PADDING * 2), 24);118 SetMinMaxSize(WidthOfTray() + (PADDING * 2), panel::Style::Instance().panel_height);
134 QueueRelayout();119 QueueRelayout();
135 QueueDraw();120 QueueDraw();
136121
137 if (_children.size())122 if (!children_.empty())
138 gtk_widget_show(_window);123 gtk_widget_show(window_);
139 else124 else
The diff has been truncated for viewing.