Merge lp:~3v1n0/unity/panel-gradient-scaling into lp:unity

Proposed by Marco Trevisan (Treviño)
Status: Superseded
Proposed branch: lp:~3v1n0/unity/panel-gradient-scaling
Merge into: lp:unity
Diff against target: 2941 lines (+1320/-450)
59 files modified
CMakeLists.txt (+11/-1)
debian/control (+22/-20)
debian/libunity-core-6.0-9.install (+3/-2)
debian/unity-services.install (+4/-1)
debian/unity-services.links (+13/-0)
debian/unity.install (+3/-0)
decorations/DecoratedWindow.cpp (+2/-9)
decorations/DecorationsMenuLayout.cpp (+35/-37)
decorations/DecorationsMenuLayout.h (+3/-2)
decorations/DecorationsPriv.h (+0/-1)
launcher/EdgeBarrierController.cpp (+32/-115)
launcher/EdgeBarrierControllerPrivate.h (+1/-6)
lockscreen/KylinLockScreenShield.cpp (+1/-1)
lockscreen/LockScreenBaseShield.cpp (+0/-2)
lockscreen/LockScreenBaseShield.h (+3/-4)
lockscreen/LockScreenController.cpp (+7/-3)
lockscreen/LockScreenController.h (+4/-2)
lockscreen/LockScreenPanel.cpp (+25/-56)
lockscreen/LockScreenPanel.h (+5/-9)
lockscreen/LockScreenShield.cpp (+7/-6)
lockscreen/LockScreenShield.h (+4/-3)
lockscreen/LockScreenShieldFactory.cpp (+2/-2)
lockscreen/LockScreenShieldFactory.h (+3/-3)
panel/PanelIndicatorEntryView.cpp (+10/-0)
panel/PanelMenuView.cpp (+1/-7)
panel/PanelMenuView.h (+0/-2)
panel/PanelView.cpp (+6/-118)
panel/PanelView.h (+3/-12)
plugins/unityshell/src/unityshell.h (+2/-0)
services/CMakeLists.txt (+31/-0)
services/unity-panel-service-lockscreen.override (+1/-0)
services/unity-panel-service-lockscreen.service.in (+7/-0)
services/unity-panel-service.override (+1/-0)
services/unity-panel-service.service.in (+9/-0)
services/unity-screen-locked.target (+4/-0)
tests/CMakeLists.txt (+1/-0)
tests/test_edge_barrier_controller.cpp (+2/-0)
tests/test_lockscreen_controller.cpp (+7/-4)
tests/test_panel_controller.cpp (+2/-0)
tests/test_panel_view.cpp (+2/-0)
tests/test_systemd_wrapper.cpp (+111/-0)
tools/CMakeLists.txt (+3/-0)
tools/unity-compiz-profile-select.in (+25/-0)
unity-shared/CMakeLists.txt (+2/-0)
unity-shared/InputMonitor.cpp (+414/-0)
unity-shared/InputMonitor.h (+67/-0)
unity-shared/MenuManager.cpp (+162/-1)
unity-shared/MenuManager.h (+4/-0)
unity-shared/SigcSlotHash.h (+70/-0)
unity-shared/StandaloneWindowManager.cpp (+3/-0)
unity-shared/StandaloneWindowManager.h (+1/-0)
unity-shared/SystemdWrapper.cpp (+103/-0)
unity-shared/SystemdWrapper.h (+55/-0)
unity-shared/WindowManager.h (+1/-0)
unity-shared/XWindowManager.cpp (+6/-0)
unity-shared/XWindowManager.h (+1/-0)
unity7.conf.in (+1/-21)
unity7.override (+1/-0)
unity7.service.in (+11/-0)
To merge this branch: bzr merge lp:~3v1n0/unity/panel-gradient-scaling
Reviewer Review Type Date Requested Status
Unity Team Pending
Review via email: mp+304384@code.launchpad.net

This proposal has been superseded by a proposal from 2016-08-30.

Commit message

PanelView: scale gradient refinement properly

To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CMakeLists.txt'
2--- CMakeLists.txt 2016-07-21 13:01:59 +0000
3+++ CMakeLists.txt 2016-08-30 14:38:39 +0000
4@@ -429,5 +429,15 @@
5 #
6 # Upstart
7 #
8-configure_file(unity7.conf.in ${CMAKE_CURRENT_BINARY_DIR}/unity7.conf)
9+
10+configure_file(unity7.conf.in ${CMAKE_CURRENT_BINARY_DIR}/unity7.conf @ONLY)
11 install(FILES ${CMAKE_CURRENT_BINARY_DIR}/unity7.conf DESTINATION ${CMAKE_INSTALL_DATADIR}/upstart/sessions)
12+
13+#
14+# Systemd
15+#
16+
17+configure_file(unity7.service.in ${CMAKE_CURRENT_BINARY_DIR}/unity7.service @ONLY)
18+pkg_get_variable(SYSTEMD_USER_DIR systemd systemduserunitdir)
19+install(FILES ${CMAKE_CURRENT_BINARY_DIR}/unity7.service DESTINATION ${SYSTEMD_USER_DIR})
20+install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/unity7.override DESTINATION ${CMAKE_INSTALL_DATADIR}/upstart/systemd-session/upstart)
21
22=== modified file 'debian/control'
23--- debian/control 2016-07-25 18:20:16 +0000
24+++ debian/control 2016-08-30 14:38:39 +0000
25@@ -53,6 +53,7 @@
26 python3 (>= 3.4),
27 python-setuptools,
28 quilt,
29+ systemd,
30 xserver-xorg-video-dummy,
31 xsltproc,
32 Standards-Version: 3.9.5
33@@ -81,12 +82,31 @@
34 libxfixes3 (>= 1:5.0.1-1),
35 libxi6 (>= 2:1.7.1.901),
36 unity-scope-home,
37-Provides: indicator-renderer
38 Recommends: unity-control-center,
39 ${unity-default-masterscopes}
40 nautilus,
41 gnome-disk-utility,
42- indicator-appmenu (>= 15.02.0),
43+ hud,
44+ session-shortcuts,
45+Breaks: unity-lens-applications (<< 5.12.0-0ubuntu2),
46+ unity-lens-files (<< 5.10.0-0ubuntu2),
47+ unity-lens-music (<< 6.0.0),
48+ unity-lens-video (<< 0.3.6-0ubuntu2),
49+Description: Interface designed for efficiency of space and interaction.
50+ Unity is a desktop experience that sings. Designed by Canonical and the Ayatana
51+ community, Unity is all about the combination of familiarity and the future. We
52+ bring together visual design, analysis of user experience testing, modern
53+ graphics technologies and a deep understanding of the free software landscape
54+ to produce what we hope will be the lightest, most elegant and most delightful
55+ way to use your PC.
56+
57+Package: unity-services
58+Architecture: any
59+Depends: ${shlibs:Depends},
60+ ${misc:Depends},
61+ indicator-common,
62+Provides: indicator-renderer
63+Recommends: indicator-appmenu (>= 15.02.0),
64 indicator-application,
65 indicator-sound,
66 indicator-bluetooth,
67@@ -96,24 +116,6 @@
68 indicator-printers,
69 indicator-power,
70 indicator-session,
71- hud,
72- session-shortcuts,
73-Breaks: unity-lens-applications (<< 5.12.0-0ubuntu2),
74- unity-lens-files (<< 5.10.0-0ubuntu2),
75- unity-lens-music (<< 6.0.0),
76- unity-lens-video (<< 0.3.6-0ubuntu2),
77-Description: Interface designed for efficiency of space and interaction.
78- Unity is a desktop experience that sings. Designed by Canonical and the Ayatana
79- community, Unity is all about the combination of familiarity and the future. We
80- bring together visual design, analysis of user experience testing, modern
81- graphics technologies and a deep understanding of the free software landscape
82- to produce what we hope will be the lightest, most elegant and most delightful
83- way to use your PC.
84-
85-Package: unity-services
86-Architecture: any
87-Depends: ${shlibs:Depends},
88- ${misc:Depends},
89 Description: Services for the Unity interface
90 Unity is a desktop experience that sings. Designed by Canonical and the Ayatana
91 community, Unity is all about the combination of familiarity and the future. We
92
93=== modified file 'debian/libunity-core-6.0-9.install'
94--- debian/libunity-core-6.0-9.install 2016-07-26 16:45:34 +0000
95+++ debian/libunity-core-6.0-9.install 2016-08-30 14:38:39 +0000
96@@ -2,8 +2,9 @@
97 usr/lib/*/unity/*.py
98 usr/share/ccsm
99 usr/share/gnome-control-center/
100-usr/share/unity
101-usr/share/upstart/sessions/unity7.conf
102+usr/share/unity/icons
103+usr/share/unity/themes
104 debian/unity-crashdb.conf etc/apport/crashdb.conf.d/
105 debian/source_unity.py usr/share/apport/package-hooks
106 tools/convert-files/* usr/lib/compiz/migration/
107+usr/share/upstart/sessions/unity7.conf
108
109=== modified file 'debian/unity-services.install'
110--- debian/unity-services.install 2016-07-26 13:58:14 +0000
111+++ debian/unity-services.install 2016-08-30 14:38:39 +0000
112@@ -1,3 +1,6 @@
113 usr/lib/*/unity/*service
114-usr/share/upstart/sessions/unity-panel-service*.conf
115+usr/share/upstart/sessions/unity-panel*
116+usr/share/upstart/systemd-session/upstart/unity-panel*
117+usr/lib/systemd/user/unity-panel*
118+usr/lib/systemd/user/unity-screen-locked.target
119 usr/share/man/*/unity-panel-service.1
120
121=== added file 'debian/unity-services.links'
122--- debian/unity-services.links 1970-01-01 00:00:00 +0000
123+++ debian/unity-services.links 2016-08-30 14:38:39 +0000
124@@ -0,0 +1,13 @@
125+/usr/lib/systemd/user/indicator-application.service /usr/lib/systemd/user/unity-panel-service.service.wants/indicator-application.service
126+/usr/lib/systemd/user/indicator-bluetooth.service /usr/lib/systemd/user/unity-panel-service.service.wants/indicator-bluetooth.service
127+/usr/lib/systemd/user/indicator-datetime.service /usr/lib/systemd/user/unity-panel-service.service.wants/indicator-datetime.service
128+/usr/lib/systemd/user/indicator-keyboard.service /usr/lib/systemd/user/unity-panel-service.service.wants/indicator-keyboard.service
129+/usr/lib/systemd/user/indicator-messages.service /usr/lib/systemd/user/unity-panel-service.service.wants/indicator-messages.service
130+/usr/lib/systemd/user/indicator-power.service /usr/lib/systemd/user/unity-panel-service.service.wants/indicator-power.service
131+/usr/lib/systemd/user/indicator-session.service /usr/lib/systemd/user/unity-panel-service.service.wants/indicator-session.service
132+/usr/lib/systemd/user/indicator-sound.service /usr/lib/systemd/user/unity-panel-service.service.wants/indicator-sound.service
133+/usr/lib/systemd/user/indicator-datetime.service /usr/lib/systemd/user/unity-panel-service-lockscreen.service.wants/indicator-datetime.service
134+/usr/lib/systemd/user/indicator-keyboard.service /usr/lib/systemd/user/unity-panel-service-lockscreen.service.wants/indicator-keyboard.service
135+/usr/lib/systemd/user/indicator-power.service /usr/lib/systemd/user/unity-panel-service-lockscreen.service.wants/indicator-power.service
136+/usr/lib/systemd/user/indicator-session.service /usr/lib/systemd/user/unity-panel-service-lockscreen.service.wants/indicator-session.service
137+/usr/lib/systemd/user/indicator-sound.service /usr/lib/systemd/user/unity-panel-service-lockscreen.service.wants/indicator-sound.service
138
139=== modified file 'debian/unity.install'
140--- debian/unity.install 2016-07-26 16:45:34 +0000
141+++ debian/unity.install 2016-08-30 14:38:39 +0000
142@@ -2,6 +2,9 @@
143 usr/bin
144 usr/lib/*/compiz/libunity*.so
145 usr/lib/*/unity/unity-active-plugins-safety-check
146+usr/lib/*/unity/unity-compiz-profile-select
147 usr/share/man/*/unity.1
148 usr/share/compiz
149 usr/share/locale
150+usr/lib/systemd/user/unity7.service
151+usr/share/upstart/systemd-session/upstart/unity7.override
152
153=== modified file 'decorations/DecoratedWindow.cpp'
154--- decorations/DecoratedWindow.cpp 2016-08-06 16:24:45 +0000
155+++ decorations/DecoratedWindow.cpp 2016-08-30 14:38:39 +0000
156@@ -37,7 +37,6 @@
157 {
158 namespace
159 {
160-const std::string MENUS_PANEL_NAME = "WindowLIM";
161 const int SHADOW_BLUR_MARGIN_FACTOR = 2;
162 }
163
164@@ -55,7 +54,6 @@
165 , deco_elements_(cu::DecorationElement::NONE)
166 , last_mwm_decor_(win_->mwmDecor())
167 , last_actions_(win_->actions())
168- , panel_id_(MENUS_PANEL_NAME + std::to_string(win_->id()))
169 , cv_(Settings::Instance().em())
170 {
171 active.changed.connect([this] (bool active) {
172@@ -932,18 +930,13 @@
173 sliding_layout->mouse_owner = grab_edge_->mouse_owner();
174 }
175
176-inline std::string const& Window::Impl::GetMenusPanelID() const
177-{
178- return panel_id_;
179-}
180-
181 void Window::Impl::UnsetAppMenu()
182 {
183 if (!menus_)
184 return;
185
186 auto const& indicators = manager_->impl_->menu_manager_->Indicators();
187- indicators->SyncGeometries(GetMenusPanelID(), indicator::EntryLocationMap());
188+ indicators->SyncGeometries(menus_->MenubarId(), indicator::EntryLocationMap());
189 sliding_layout_->SetInputItem(nullptr);
190 grab_mouse_changed_->disconnect();
191 }
192@@ -956,7 +949,7 @@
193 auto const& indicators = manager_->impl_->menu_manager_->Indicators();
194 indicator::EntryLocationMap map;
195 menus_->ChildrenGeometries(map);
196- indicators->SyncGeometries(GetMenusPanelID(), map);
197+ indicators->SyncGeometries(menus_->MenubarId(), map);
198 }
199
200 bool Window::Impl::ActivateMenu(std::string const& entry_id)
201
202=== modified file 'decorations/DecorationsMenuLayout.cpp'
203--- decorations/DecorationsMenuLayout.cpp 2015-02-03 10:04:17 +0000
204+++ decorations/DecorationsMenuLayout.cpp 2016-08-30 14:38:39 +0000
205@@ -25,6 +25,10 @@
206 {
207 namespace decoration
208 {
209+namespace
210+{
211+const std::string MENUS_PANEL_NAME = "WindowLIM";
212+}
213
214 using namespace indicator;
215
216@@ -33,8 +37,8 @@
217 , show_now(false)
218 , menu_manager_(menu)
219 , win_(win)
220- , last_pointer_(-1, -1)
221 , dropdown_(std::make_shared<MenuDropdown>(menu_manager_->Indicators(), win))
222+ , menubar_id_(MENUS_PANEL_NAME + std::to_string(win_->id()))
223 {
224 visible = false;
225 }
226@@ -91,6 +95,11 @@
227 Relayout();
228 }
229
230+std::string const& MenuLayout::MenubarId() const
231+{
232+ return menubar_id_;
233+}
234+
235 bool MenuLayout::ActivateMenu(std::string const& entry_id)
236 {
237 MenuEntry::Ptr target;
238@@ -117,16 +126,29 @@
239 if (!activated)
240 activated = dropdown_->ActivateChild(target);
241
242- if (activated)
243- {
244- // Since this generally happens on keyboard activation we need to avoid that
245- // the mouse position would interfere with this
246- last_pointer_.set(pointerX, pointerY);
247- }
248-
249 return activated;
250 }
251
252+bool MenuLayout::ActivateMenu(CompPoint const& pos)
253+{
254+ if (!Geometry().contains(pos))
255+ return false;
256+
257+ for (auto const& item : items_)
258+ {
259+ if (!item->visible() || !item->sensitive())
260+ continue;
261+
262+ if (item->Geometry().contains(pos))
263+ {
264+ std::static_pointer_cast<MenuEntry>(item)->ShowMenu(1);
265+ return true;
266+ }
267+ }
268+
269+ return false;
270+}
271+
272 void MenuLayout::OnEntryMouseOwnershipChanged(bool owner)
273 {
274 mouse_owner = owner;
275@@ -154,39 +176,15 @@
276 {
277 active = actived;
278
279- if (active && !pointer_tracker_ && items_.size() > 1)
280+ if (active && items_.size() > 1)
281 {
282- pointer_tracker_.reset(new glib::Timeout(16));
283- pointer_tracker_->Run([this] {
284- Window win;
285- int i, x, y;
286- unsigned int ui;
287-
288- XQueryPointer(screen->dpy(), screen->root(), &win, &win, &x, &y, &i, &i, &ui);
289-
290- if (last_pointer_.x() != x || last_pointer_.y() != y)
291- {
292- last_pointer_.set(x, y);
293-
294- for (auto const& item : items_)
295- {
296- if (!item->visible() || !item->sensitive())
297- continue;
298-
299- if (item->Geometry().contains(last_pointer_))
300- {
301- std::static_pointer_cast<MenuEntry>(item)->ShowMenu(1);
302- break;
303- }
304- }
305- }
306-
307- return true;
308- });
309+ menu_manager_->RegisterTracker(menubar_id_, (sigc::track_obj([this] (int x, int y, double speed) {
310+ ActivateMenu(CompPoint(x, y));
311+ }, *this)));
312 }
313 else if (!active)
314 {
315- pointer_tracker_.reset();
316+ menu_manager_->UnregisterTracker(menubar_id_);
317 }
318 }
319
320
321=== modified file 'decorations/DecorationsMenuLayout.h'
322--- decorations/DecorationsMenuLayout.h 2014-02-13 03:01:30 +0000
323+++ decorations/DecorationsMenuLayout.h 2016-08-30 14:38:39 +0000
324@@ -42,7 +42,9 @@
325
326 void Setup();
327 bool ActivateMenu(std::string const& entry_id);
328+ bool ActivateMenu(CompPoint const&);
329 void ChildrenGeometries(indicator::EntryLocationMap&) const;
330+ std::string const& MenubarId() const;
331
332 protected:
333 void DoRelayout() override;
334@@ -55,10 +57,9 @@
335
336 menu::Manager::Ptr menu_manager_;
337 CompWindow* win_;
338- CompPoint last_pointer_;
339- glib::Source::UniquePtr pointer_tracker_;
340 glib::Source::UniquePtr show_now_timeout_;
341 std::shared_ptr<MenuDropdown> dropdown_;
342+ std::string menubar_id_;
343 };
344
345 } // decoration namespace
346
347=== modified file 'decorations/DecorationsPriv.h'
348--- decorations/DecorationsPriv.h 2016-08-06 16:24:45 +0000
349+++ decorations/DecorationsPriv.h 2016-08-30 14:38:39 +0000
350@@ -162,7 +162,6 @@
351 connection::Wrapper dpi_changed_;
352 connection::Wrapper grab_mouse_changed_;
353 std::string last_title_;
354- std::string panel_id_;
355 std::vector<cu::SimpleTextureQuad> bg_textures_;
356 cu::PixmapTexture::Ptr shaped_shadow_pixmap_;
357 std::shared_ptr<ForceQuitDialog> force_quit_;
358
359=== modified file 'launcher/EdgeBarrierController.cpp'
360--- launcher/EdgeBarrierController.cpp 2015-12-23 09:29:24 +0000
361+++ launcher/EdgeBarrierController.cpp 2016-08-30 14:38:39 +0000
362@@ -25,6 +25,7 @@
363 #include <NuxCore/Logger.h>
364 #include "unity-shared/UnitySettings.h"
365 #include "unity-shared/UScreen.h"
366+#include "unity-shared/InputMonitor.h"
367 #include "UnityCore/GLibSource.h"
368
369 namespace unity
370@@ -36,50 +37,12 @@
371 {
372 int const Y_BREAK_BUFFER = 20;
373 int const X_BREAK_BUFFER = 20;
374- int const MAJOR = 2;
375- int const MINOR = 3;
376 }
377
378 DECLARE_LOGGER(logger, "unity.edge_barrier_controller");
379
380-int GetXI2OpCode()
381-{
382- Display *dpy = nux::GetGraphicsDisplay()->GetX11Display();
383-
384- int opcode, event_base, error_base;
385- if (!XQueryExtension(dpy, "XFIXES",
386- &opcode,
387- &event_base,
388- &error_base))
389- {
390- LOG_ERROR(logger) << "Missing XFixes";
391- return -1;
392- }
393-
394- if (!XQueryExtension (dpy, "XInputExtension",
395- &opcode,
396- &event_base,
397- &error_base))
398- {
399- LOG_ERROR(logger) << "Missing XInput";
400- return -1;
401- }
402-
403- int maj = MAJOR;
404- int min = MINOR;
405-
406- if (XIQueryVersion(dpy, &maj, &min) == BadRequest)
407- {
408- LOG_ERROR(logger) << "Need XInput version 2.3";
409- return -1;
410- }
411-
412- return opcode;
413-}
414-
415 EdgeBarrierController::Impl::Impl(EdgeBarrierController *parent)
416- : xi2_opcode_(-1)
417- , edge_overcome_pressure_(0)
418+ : edge_overcome_pressure_(0)
419 , parent_(parent)
420 {
421 UScreen *uscreen = UScreen::GetDefault();
422@@ -119,8 +82,6 @@
423 options->option_changed.connect(sigc::mem_fun(this, &EdgeBarrierController::Impl::OnOptionsChanged));
424 SetupBarriers(UScreen::GetDefault()->GetMonitors());
425 });
426-
427- xi2_opcode_ = GetXI2OpCode();
428 }
429
430 EdgeBarrierController::Impl::~Impl()
431@@ -202,36 +163,30 @@
432 }
433 }
434
435-void SetupXI2Events()
436-{
437- Display *dpy = nux::GetGraphicsDisplay()->GetX11Display();
438-
439- unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 };
440- XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits };
441-
442- XISetMask(mask.mask, XI_BarrierHit);
443- XISetMask(mask.mask, XI_BarrierLeave);
444- XISelectEvents (dpy, DefaultRootWindow(dpy), &mask, 1);
445-}
446-
447 void EdgeBarrierController::Impl::SetupBarriers(std::vector<nux::Geometry> const& layout)
448 {
449 if (parent_->force_disable())
450 return;
451
452+ size_t monitors_size = layout.size();
453+ auto launcher_position = Settings::Instance().launcher_position();
454 bool edge_resist = parent_->sticky_edges();
455- auto launcher_position = Settings::Instance().launcher_position();
456-
457- for (unsigned i = 0; i < layout.size(); i++)
458+ bool needs_barrier = edge_resist && monitors_size > 1;
459+ bool needs_vertical_barrier = needs_barrier;
460+
461+ if (parent_->options()->hide_mode() != launcher::LauncherHideMode::LAUNCHER_HIDE_NEVER)
462+ needs_vertical_barrier = true;
463+
464+ for (unsigned i = 0; i < layout.size(); ++i)
465 {
466- auto vertical_barrier = vertical_barriers_[i];
467- auto horizontal_barrier = horizontal_barriers_[i];
468- auto monitor = layout[i];
469+ auto const& vertical_barrier = vertical_barriers_[i];
470+ auto const& horizontal_barrier = horizontal_barriers_[i];
471+ auto const& monitor = layout[i];
472
473 vertical_barrier->DestroyBarrier();
474 horizontal_barrier->DestroyBarrier();
475
476- if (edge_resist)
477+ if (needs_barrier)
478 {
479 horizontal_barrier->x1 = monitor.x;
480 horizontal_barrier->x2 = monitor.x + monitor.width;
481@@ -246,7 +201,7 @@
482 horizontal_barrier->ConstructBarrier();
483 }
484
485- if (!edge_resist && parent_->options()->hide_mode() == launcher::LauncherHideMode::LAUNCHER_HIDE_NEVER)
486+ if (!needs_vertical_barrier)
487 continue;
488
489 if (launcher_position == LauncherPosition::LEFT)
490@@ -273,8 +228,10 @@
491 vertical_barrier->ConstructBarrier();
492 }
493
494- SetupXI2Events();
495- AddEventFilter();
496+ if (needs_barrier || needs_vertical_barrier)
497+ input::Monitor::Get().RegisterClient(input::Events::BARRIER, sigc::mem_fun(this, &Impl::HandleEvent));
498+ else
499+ input::Monitor::Get().UnregisterClient(sigc::mem_fun(this, &Impl::HandleEvent));
500
501 float decay_responsiveness_mult = ((parent_->options()->edge_responsiveness() - 1) * .3f) + 1;
502 decaymulator_.rate_of_decay = parent_->options()->edge_decay_rate() * decay_responsiveness_mult;
503@@ -283,65 +240,25 @@
504 edge_overcome_pressure_ = parent_->options()->edge_overcome_pressure() * overcome_responsiveness_mult;
505 }
506
507-void EdgeBarrierController::Impl::AddEventFilter()
508-{
509- // Remove an old one, if it exists
510- nux::GetGraphicsDisplay()->RemoveEventFilter(this);
511-
512- nux::GraphicsDisplay::EventFilterArg event_filter;
513- event_filter.filter = &HandleEventCB;
514- event_filter.data = this;
515-
516- nux::GetGraphicsDisplay()->AddEventFilter(event_filter);
517-}
518-
519-bool EdgeBarrierController::Impl::HandleEvent(XEvent xevent)
520-{
521- Display *dpy = nux::GetGraphicsDisplay()->GetX11Display();
522- XGenericEventCookie *cookie = &xevent.xcookie;
523- bool ret = false;
524-
525- switch (cookie->evtype)
526- {
527- case (XI_BarrierHit):
528- {
529- if (XGetEventData(dpy, cookie))
530- {
531- XIBarrierEvent* barrier_event = (XIBarrierEvent*)cookie->data;
532- PointerBarrierWrapper::Ptr wrapper = FindBarrierEventOwner(barrier_event);
533-
534- if (wrapper)
535- ret = wrapper->HandleBarrierEvent(barrier_event);
536- }
537-
538- XFreeEventData(dpy, cookie);
539- break;
540- }
541- default:
542- break;
543- }
544-
545- return ret;
546-}
547-
548-bool EdgeBarrierController::Impl::HandleEventCB(XEvent xevent, void* data)
549-{
550- auto edge_barrier_controller = static_cast<EdgeBarrierController::Impl*>(data);
551- int const xi2_opcode = edge_barrier_controller->xi2_opcode_;
552-
553- if (xevent.type != GenericEvent || xevent.xcookie.extension != xi2_opcode)
554- return false;
555-
556- return edge_barrier_controller->HandleEvent(xevent);
557+void EdgeBarrierController::Impl::HandleEvent(XEvent const& xevent)
558+{
559+ if (xevent.xcookie.evtype != XI_BarrierHit)
560+ return;
561+
562+ auto* barrier_event = reinterpret_cast<XIBarrierEvent*>(xevent.xcookie.data);
563+ PointerBarrierWrapper::Ptr const& wrapper = FindBarrierEventOwner(barrier_event);
564+
565+ if (wrapper)
566+ wrapper->HandleBarrierEvent(barrier_event);
567 }
568
569 PointerBarrierWrapper::Ptr EdgeBarrierController::Impl::FindBarrierEventOwner(XIBarrierEvent* barrier_event)
570 {
571- for (auto barrier : vertical_barriers_)
572+ for (auto const& barrier : vertical_barriers_)
573 if (barrier->OwnsBarrierEvent(barrier_event->barrier))
574 return barrier;
575
576- for (auto barrier : horizontal_barriers_)
577+ for (auto const& barrier : horizontal_barriers_)
578 if (barrier->OwnsBarrierEvent(barrier_event->barrier))
579 return barrier;
580
581
582=== modified file 'launcher/EdgeBarrierControllerPrivate.h'
583--- launcher/EdgeBarrierControllerPrivate.h 2015-12-23 09:29:24 +0000
584+++ launcher/EdgeBarrierControllerPrivate.h 2016-08-30 14:38:39 +0000
585@@ -53,12 +53,8 @@
586 bool EventIsInsideYBreakZone(BarrierEvent::Ptr const& event);
587 bool EventIsInsideXBreakZone(BarrierEvent::Ptr const& event);
588
589- void AddEventFilter();
590-
591 PointerBarrierWrapper::Ptr FindBarrierEventOwner(XIBarrierEvent* barrier_event);
592-
593- static bool HandleEventCB(XEvent event, void* data);
594- bool HandleEvent(XEvent event);
595+ void HandleEvent(XEvent const&);
596
597 std::vector<PointerBarrierWrapper::Ptr> vertical_barriers_;
598 std::vector<PointerBarrierWrapper::Ptr> horizontal_barriers_;
599@@ -68,7 +64,6 @@
600
601 Decaymulator decaymulator_;
602 glib::Source::UniquePtr release_timeout_;
603- int xi2_opcode_;
604 float edge_overcome_pressure_;
605 EdgeBarrierController* parent_;
606 };
607
608=== modified file 'lockscreen/KylinLockScreenShield.cpp'
609--- lockscreen/KylinLockScreenShield.cpp 2015-12-07 03:09:28 +0000
610+++ lockscreen/KylinLockScreenShield.cpp 2016-08-30 14:38:39 +0000
611@@ -37,7 +37,7 @@
612 Accelerators::Ptr const& accelerators,
613 nux::ObjectPtr<AbstractUserPromptView> const& prompt_view,
614 int monitor_num, bool is_primary)
615- : BaseShield(session_manager, nullptr, accelerators, prompt_view, monitor_num, is_primary)
616+ : BaseShield(session_manager, accelerators, prompt_view, monitor_num, is_primary)
617 {
618 is_primary ? ShowPrimaryView() : ShowSecondaryView();
619 EnableInputWindow(true);
620
621=== modified file 'lockscreen/LockScreenBaseShield.cpp'
622--- lockscreen/LockScreenBaseShield.cpp 2015-12-03 14:13:10 +0000
623+++ lockscreen/LockScreenBaseShield.cpp 2016-08-30 14:38:39 +0000
624@@ -38,7 +38,6 @@
625 }
626
627 BaseShield::BaseShield(session::Manager::Ptr const& session,
628- indicator::Indicators::Ptr const& indicators,
629 Accelerators::Ptr const& accelerators,
630 nux::ObjectPtr<AbstractUserPromptView> const& prompt_view,
631 int monitor_num, bool is_primary)
632@@ -47,7 +46,6 @@
633 , monitor(monitor_num)
634 , scale(1.0)
635 , session_manager_(session)
636- , indicators_(indicators)
637 , accelerators_(accelerators)
638 , prompt_view_(prompt_view)
639 , bg_settings_(std::make_shared<BackgroundSettings>())
640
641=== modified file 'lockscreen/LockScreenBaseShield.h'
642--- lockscreen/LockScreenBaseShield.h 2016-03-31 09:51:33 +0000
643+++ lockscreen/LockScreenBaseShield.h 2016-08-30 14:38:39 +0000
644@@ -21,8 +21,8 @@
645 #define UNITY_LOCKSCREEN_BASE_SHIELD_H
646
647 #include <NuxCore/Property.h>
648+#include "UnityCore/ConnectionManager.h"
649 #include "UnityCore/SessionManager.h"
650-#include "UnityCore/Indicators.h"
651 #include "UnityCore/GLibSource.h"
652 #include "unity-shared/MockableBaseWindow.h"
653
654@@ -39,8 +39,8 @@
655 class BaseShield : public MockableBaseWindow
656 {
657 public:
658- BaseShield(session::Manager::Ptr const&, indicator::Indicators::Ptr const&,
659- Accelerators::Ptr const&, nux::ObjectPtr<AbstractUserPromptView> const&,
660+ BaseShield(session::Manager::Ptr const&, Accelerators::Ptr const&,
661+ nux::ObjectPtr<AbstractUserPromptView> const&,
662 int monitor_num, bool is_primary);
663
664 nux::Property<bool> primary;
665@@ -69,7 +69,6 @@
666 void UpdateScale();
667
668 session::Manager::Ptr session_manager_;
669- indicator::Indicators::Ptr indicators_;
670 Accelerators::Ptr accelerators_;
671 nux::ObjectPtr<AbstractUserPromptView> prompt_view_;
672 std::shared_ptr<BackgroundSettings> bg_settings_;
673
674=== modified file 'lockscreen/LockScreenController.cpp'
675--- lockscreen/LockScreenController.cpp 2016-07-04 12:45:06 +0000
676+++ lockscreen/LockScreenController.cpp 2016-08-30 14:38:39 +0000
677@@ -56,6 +56,7 @@
678 Controller::Controller(DBusManager::Ptr const& dbus_manager,
679 session::Manager::Ptr const& session_manager,
680 key::Grabber::Ptr const& key_grabber,
681+ SystemdWrapper::Ptr const& systemd_wrapper,
682 UpstartWrapper::Ptr const& upstart_wrapper,
683 ShieldFactoryInterface::Ptr const& shield_factory,
684 bool test_mode)
685@@ -63,6 +64,7 @@
686 , dbus_manager_(dbus_manager)
687 , session_manager_(session_manager)
688 , key_grabber_(key_grabber)
689+ , systemd_wrapper_(systemd_wrapper)
690 , upstart_wrapper_(upstart_wrapper)
691 , shield_factory_(shield_factory)
692 , suspend_inhibitor_manager_(std::make_shared<SuspendInhibitorManager>())
693@@ -129,8 +131,9 @@
694 shields_.clear();
695
696 upstart_wrapper_->Emit("desktop-unlock");
697+ systemd_wrapper_->Stop("unity-screen-locked.target");
698 accelerator_controller_.reset();
699- indicators_.reset();
700+ menu_manager_.reset();
701 }
702 else if (!prompt_activation_)
703 {
704@@ -252,7 +255,7 @@
705
706 if (i >= shields_size)
707 {
708- shield = shield_factory_->CreateShield(session_manager_, indicators_, accelerator_controller_->GetAccelerators(), prompt_view, i, i == primary);
709+ shield = shield_factory_->CreateShield(session_manager_, menu_manager_, accelerator_controller_->GetAccelerators(), prompt_view, i, i == primary);
710 is_new = true;
711 }
712
713@@ -462,8 +465,9 @@
714
715 void Controller::LockScreen()
716 {
717- indicators_ = std::make_shared<indicator::LockScreenDBusIndicators>();
718+ menu_manager_ = std::make_shared<menu::Manager>(std::make_shared<indicator::LockScreenDBusIndicators>(), key_grabber_);
719 upstart_wrapper_->Emit("desktop-lock");
720+ systemd_wrapper_->Stop("unity-screen-locked.target");
721
722 accelerator_controller_ = std::make_shared<AcceleratorController>(key_grabber_);
723 auto activate_key = WindowManager::Default().activate_indicators_key();
724
725=== modified file 'lockscreen/LockScreenController.h'
726--- lockscreen/LockScreenController.h 2016-06-21 01:28:26 +0000
727+++ lockscreen/LockScreenController.h 2016-08-30 14:38:39 +0000
728@@ -30,7 +30,7 @@
729 #include "SuspendInhibitorManager.h"
730 #include "ScreenSaverDBusManager.h"
731 #include "unity-shared/BackgroundEffectHelper.h"
732-#include "unity-shared/KeyGrabber.h"
733+#include "unity-shared/SystemdWrapper.h"
734 #include "unity-shared/UpstartWrapper.h"
735
736 namespace unity
737@@ -46,6 +46,7 @@
738 typedef std::shared_ptr<Controller> Ptr;
739
740 Controller(DBusManager::Ptr const&, session::Manager::Ptr const&, key::Grabber::Ptr const&,
741+ SystemdWrapper::Ptr const& systemd_wrapper = std::make_shared<SystemdWrapper>(),
742 UpstartWrapper::Ptr const& upstart_wrapper = std::make_shared<UpstartWrapper>(),
743 ShieldFactoryInterface::Ptr const& shield_factory = std::make_shared<ShieldFactory>(),
744 bool test_mode = false);
745@@ -85,9 +86,10 @@
746
747 DBusManager::Ptr dbus_manager_;
748 session::Manager::Ptr session_manager_;
749+ menu::Manager::Ptr menu_manager_;
750 key::Grabber::Ptr key_grabber_;
751- indicator::Indicators::Ptr indicators_;
752 AcceleratorController::Ptr accelerator_controller_;
753+ SystemdWrapper::Ptr systemd_wrapper_;
754 UpstartWrapper::Ptr upstart_wrapper_;
755 ShieldFactoryInterface::Ptr shield_factory_;
756 SuspendInhibitorManager::Ptr suspend_inhibitor_manager_;
757
758=== modified file 'lockscreen/LockScreenPanel.cpp'
759--- lockscreen/LockScreenPanel.cpp 2015-11-05 14:55:54 +0000
760+++ lockscreen/LockScreenPanel.cpp 2016-08-30 14:38:39 +0000
761@@ -24,7 +24,7 @@
762
763 #include "LockScreenSettings.h"
764 #include "panel/PanelIndicatorsView.h"
765-#include "unity-shared/CairoTexture.h"
766+#include "unity-shared/InputMonitor.h"
767 #include "unity-shared/StaticCairoText.h"
768 #include "unity-shared/PanelStyle.h"
769 #include "unity-shared/RawPixel.h"
770@@ -38,24 +38,24 @@
771 namespace
772 {
773 const RawPixel PADDING = 5_em;
774+const nux::Color BG_COLOR(0.1, 0.1, 0.1, 0.4);
775 }
776
777 using namespace indicator;
778 using namespace panel;
779
780-Panel::Panel(int monitor_, Indicators::Ptr const& indicators, session::Manager::Ptr const& session_manager)
781+Panel::Panel(int monitor_, menu::Manager::Ptr const& menu_manager, session::Manager::Ptr const& session_manager)
782 : nux::View(NUX_TRACKER_LOCATION)
783 , active(false)
784 , monitor(monitor_)
785- , indicators_(indicators)
786+ , menu_manager_(menu_manager)
787 , needs_geo_sync_(true)
788 {
789 double scale = unity::Settings::Instance().em(monitor)->DPIScale();
790 auto* layout = new nux::HLayout();
791 layout->SetLeftAndRightPadding(PADDING.CP(scale), 0);
792 SetLayout(layout);
793-
794- BuildTexture();
795+ UpdateSize();
796
797 // Add setting
798 auto *hostname = new StaticCairoText(session_manager->HostName());
799@@ -72,34 +72,33 @@
800 indicators_view_->on_indicator_updated.connect(sigc::mem_fun(this, &Panel::OnIndicatorViewUpdated));
801 layout->AddView(indicators_view_, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL);
802
803- for (auto const& indicator : indicators_->GetIndicators())
804+ auto indicators = menu_manager_->Indicators();
805+ menu_manager_->RegisterTracker(GetPanelName(), (sigc::track_obj([this] (int x, int y, double speed) {
806+ indicators_view_->ActivateEntryAt(x, y);
807+ }, *this)));
808+
809+ for (auto const& indicator : indicators->GetIndicators())
810 AddIndicator(indicator);
811
812- indicators_->on_object_added.connect(sigc::mem_fun(this, &Panel::AddIndicator));
813- indicators_->on_object_removed.connect(sigc::mem_fun(this, &Panel::RemoveIndicator));
814- indicators_->on_entry_show_menu.connect(sigc::mem_fun(this, &Panel::OnEntryShowMenu));
815- indicators_->on_entry_activated.connect(sigc::mem_fun(this, &Panel::OnEntryActivated));
816- indicators_->on_entry_activate_request.connect(sigc::mem_fun(this, &Panel::OnEntryActivateRequest));
817+ indicators->on_object_added.connect(sigc::mem_fun(this, &Panel::AddIndicator));
818+ indicators->on_object_removed.connect(sigc::mem_fun(this, &Panel::RemoveIndicator));
819+ indicators->on_entry_show_menu.connect(sigc::mem_fun(this, &Panel::OnEntryShowMenu));
820+ indicators->on_entry_activated.connect(sigc::mem_fun(this, &Panel::OnEntryActivated));
821+ indicators->on_entry_activate_request.connect(sigc::mem_fun(this, &Panel::OnEntryActivateRequest));
822
823 monitor.changed.connect([this, hostname] (int monitor) {
824 double scale = unity::Settings::Instance().em(monitor)->DPIScale();
825 hostname->SetScale(scale);
826 static_cast<nux::HLayout*>(GetLayout())->SetLeftAndRightPadding(PADDING.CP(scale), 0);
827 indicators_view_->SetMonitor(monitor);
828- BuildTexture();
829+ UpdateSize();
830 QueueRelayout();
831 });
832 }
833
834-void Panel::BuildTexture()
835+void Panel::UpdateSize()
836 {
837 int height = panel::Style::Instance().PanelHeight(monitor);
838- nux::CairoGraphics context(CAIRO_FORMAT_ARGB32, 1, height);
839- auto* cr = context.GetInternalContext();
840- cairo_set_source_rgb(cr, 0.1, 0.1, 0.1);
841- cairo_paint_with_alpha(cr, 0.4);
842- bg_texture_ = texture_ptr_from_cairo_graphics(context);
843-
844 view_layout_->SetMinimumHeight(height);
845 view_layout_->SetMaximumHeight(height);
846 }
847@@ -165,12 +164,7 @@
848 if (!GetInputEventSensitivity())
849 return;
850
851- if (!active)
852- {
853- // This is ugly... But Nux fault!
854- WindowManager::Default().UnGrabMousePointer(CurrentTime, button, x, y);
855- active = true;
856- }
857+ active = true;
858 }
859
860 void Panel::OnEntryActivateRequest(std::string const& entry_id)
861@@ -184,36 +178,16 @@
862 if (!GetInputEventSensitivity() || (!panel.empty() && panel != GetPanelName()))
863 return;
864
865- bool active = !entry_id.empty();
866+ bool valid_entry = !entry_id.empty();
867
868- if (active && !WindowManager::Default().IsScreenGrabbed())
869+ if (valid_entry && !WindowManager::Default().IsScreenGrabbed())
870 {
871 // The menu didn't grab the keyboard, let's take it back.
872 nux::GetWindowCompositor().GrabKeyboardAdd(static_cast<nux::BaseWindow*>(GetTopLevelViewWindow()));
873 }
874
875- if (active && !track_menu_pointer_timeout_)
876- {
877- track_menu_pointer_timeout_.reset(new glib::Timeout(16));
878- track_menu_pointer_timeout_->Run([this] {
879- nux::Point const& mouse = nux::GetGraphicsDisplay()->GetMouseScreenCoord();
880- if (tracked_pointer_pos_ != mouse)
881- {
882- if (GetAbsoluteGeometry().IsPointInside(mouse.x, mouse.y))
883- indicators_view_->ActivateEntryAt(mouse.x, mouse.y);
884-
885- tracked_pointer_pos_ = mouse;
886- }
887-
888- return true;
889- });
890- }
891- else if (!active)
892- {
893- track_menu_pointer_timeout_.reset();
894- tracked_pointer_pos_ = {-1, -1};
895- this->active = false;
896- }
897+ if (!valid_entry)
898+ active = valid_entry;
899 }
900
901 void Panel::Draw(nux::GraphicsEngine& graphics_engine, bool force_draw)
902@@ -227,12 +201,7 @@
903 graphics_engine.PushClippingRectangle(geo);
904 nux::GetPainter().PaintBackground(graphics_engine, geo);
905
906- nux::TexCoordXForm texxform;
907- texxform.SetWrap(nux::TEXWRAP_REPEAT, nux::TEXWRAP_CLAMP);
908- graphics_engine.QRP_1Tex(geo.x, geo.y, geo.width, geo.height,
909- bg_texture_->GetDeviceTexture(), texxform,
910- nux::color::White);
911-
912+ graphics_engine.QRP_Color(geo.x, geo.y, geo.width, geo.height, BG_COLOR);
913 view_layout_->ProcessDraw(graphics_engine, force_draw);
914
915 graphics_engine.PopClippingRectangle();
916@@ -242,7 +211,7 @@
917 {
918 EntryLocationMap locations;
919 indicators_view_->GetGeometryForSync(locations);
920- indicators_->SyncGeometries(GetPanelName(), locations);
921+ menu_manager_->Indicators()->SyncGeometries(GetPanelName(), locations);
922 needs_geo_sync_ = false;
923 }
924 }
925
926=== modified file 'lockscreen/LockScreenPanel.h'
927--- lockscreen/LockScreenPanel.h 2016-03-31 09:51:33 +0000
928+++ lockscreen/LockScreenPanel.h 2016-08-30 14:38:39 +0000
929@@ -22,9 +22,9 @@
930
931 #include <Nux/Nux.h>
932 #include <Nux/View.h>
933-#include "UnityCore/Indicators.h"
934 #include "UnityCore/GLibSource.h"
935 #include "UnityCore/SessionManager.h"
936+#include "unity-shared/MenuManager.h"
937
938 namespace unity
939 {
940@@ -39,7 +39,7 @@
941 class Panel : public nux::View
942 {
943 public:
944- Panel(int monitor, indicator::Indicators::Ptr const&, session::Manager::Ptr const&);
945+ Panel(int monitor, menu::Manager::Ptr const&, session::Manager::Ptr const&);
946
947 nux::Property<bool> active;
948 nux::Property<int> monitor;
949@@ -55,20 +55,16 @@
950 void AddIndicator(indicator::Indicator::Ptr const&);
951 void RemoveIndicator(indicator::Indicator::Ptr const&);
952 void OnIndicatorViewUpdated();
953- void OnEntryActivated(std::string const& panel, std::string const& entry_id, nux::Rect const& geo);
954+ void OnEntryActivated(std::string const& panel, std::string const& entry_id, nux::Rect const&);
955 void OnEntryShowMenu(std::string const& entry_id, unsigned xid, int x, int y, unsigned button);
956 void OnEntryActivateRequest(std::string const& entry_id);
957
958- void BuildTexture();
959+ void UpdateSize();
960 std::string GetPanelName() const;
961
962- indicator::Indicators::Ptr indicators_;
963+ menu::Manager::Ptr menu_manager_;
964 panel::PanelIndicatorsView* indicators_view_;
965- nux::ObjectPtr<nux::BaseTexture> bg_texture_;
966-
967 bool needs_geo_sync_;
968- nux::Point tracked_pointer_pos_;
969- glib::Source::UniquePtr track_menu_pointer_timeout_;
970 };
971
972 } // lockscreen namespace
973
974=== modified file 'lockscreen/LockScreenShield.cpp'
975--- lockscreen/LockScreenShield.cpp 2015-12-03 14:13:10 +0000
976+++ lockscreen/LockScreenShield.cpp 2016-08-30 14:38:39 +0000
977@@ -32,11 +32,12 @@
978 {
979
980 Shield::Shield(session::Manager::Ptr const& session_manager,
981- indicator::Indicators::Ptr const& indicators,
982+ menu::Manager::Ptr const& menu_manager,
983 Accelerators::Ptr const& accelerators,
984 nux::ObjectPtr<AbstractUserPromptView> const& prompt_view,
985 int monitor_num, bool is_primary)
986- : BaseShield(session_manager, indicators, accelerators, prompt_view, monitor_num, is_primary)
987+ : BaseShield(session_manager, accelerators, prompt_view, monitor_num, is_primary)
988+ , menu_manager_(menu_manager)
989 , panel_view_(nullptr)
990 {
991 is_primary ? ShowPrimaryView() : ShowSecondaryView();
992@@ -91,11 +92,11 @@
993
994 Panel* Shield::CreatePanel()
995 {
996- if (!indicators_ || !session_manager_)
997+ if (!menu_manager_ || !session_manager_)
998 return nullptr;
999
1000- panel_view_ = new Panel(monitor, indicators_, session_manager_);
1001- panel_active_conn_ = panel_view_->active.changed.connect([this] (bool active) {
1002+ panel_view_ = new Panel(monitor, menu_manager_, session_manager_);
1003+ panel_view_->active.changed.connect(sigc::track_obj([this] (bool active) {
1004 if (primary())
1005 {
1006 if (active)
1007@@ -109,7 +110,7 @@
1008 GrabScreen(false);
1009 }
1010 }
1011- });
1012+ }, *this));
1013
1014 return panel_view_;
1015 }
1016
1017=== modified file 'lockscreen/LockScreenShield.h'
1018--- lockscreen/LockScreenShield.h 2015-12-03 14:13:10 +0000
1019+++ lockscreen/LockScreenShield.h 2016-08-30 14:38:39 +0000
1020@@ -20,8 +20,9 @@
1021 #ifndef UNITY_LOCKSCREEN_SHIELD_H
1022 #define UNITY_LOCKSCREEN_SHIELD_H
1023
1024-#include <UnityCore/ConnectionManager.h>
1025 #include "LockScreenBaseShield.h"
1026+#include "unity-shared/MenuManager.h"
1027+
1028
1029 namespace unity
1030 {
1031@@ -35,7 +36,7 @@
1032 {
1033 public:
1034 Shield(session::Manager::Ptr const&,
1035- indicator::Indicators::Ptr const&,
1036+ menu::Manager::Ptr const&,
1037 Accelerators::Ptr const&,
1038 nux::ObjectPtr<AbstractUserPromptView> const&,
1039 int monitor, bool is_primary);
1040@@ -50,7 +51,7 @@
1041 void ShowPrimaryView() override;
1042 Panel* CreatePanel();
1043
1044- connection::Wrapper panel_active_conn_;
1045+ menu::Manager::Ptr menu_manager_;
1046 Panel* panel_view_;
1047 };
1048
1049
1050=== modified file 'lockscreen/LockScreenShieldFactory.cpp'
1051--- lockscreen/LockScreenShieldFactory.cpp 2015-12-04 08:17:46 +0000
1052+++ lockscreen/LockScreenShieldFactory.cpp 2016-08-30 14:38:39 +0000
1053@@ -28,7 +28,7 @@
1054 {
1055
1056 nux::ObjectPtr<BaseShield> ShieldFactory::CreateShield(session::Manager::Ptr const& session_manager,
1057- indicator::Indicators::Ptr const& indicators,
1058+ menu::Manager::Ptr const& menu_manager,
1059 Accelerators::Ptr const& accelerators,
1060 nux::ObjectPtr<AbstractUserPromptView> const& prompt_view,
1061 int monitor, bool is_primary)
1062@@ -38,7 +38,7 @@
1063 if (Settings::Instance().desktop_type() == DesktopType::UBUNTUKYLIN)
1064 shield = new KylinShield(session_manager, accelerators, prompt_view, monitor, is_primary);
1065 else
1066- shield = new Shield(session_manager, indicators, accelerators, prompt_view, monitor, is_primary);
1067+ shield = new Shield(session_manager, menu_manager, accelerators, prompt_view, monitor, is_primary);
1068
1069 return shield;
1070 }
1071
1072=== modified file 'lockscreen/LockScreenShieldFactory.h'
1073--- lockscreen/LockScreenShieldFactory.h 2016-03-31 09:51:33 +0000
1074+++ lockscreen/LockScreenShieldFactory.h 2016-08-30 14:38:39 +0000
1075@@ -22,7 +22,7 @@
1076
1077 #include <NuxCore/NuxCore.h>
1078 #include "UnityCore/SessionManager.h"
1079-#include "UnityCore/Indicators.h"
1080+#include "unity-shared/MenuManager.h"
1081 #include "LockScreenAccelerators.h"
1082
1083 namespace unity
1084@@ -41,7 +41,7 @@
1085 virtual ~ShieldFactoryInterface() = default;
1086
1087 virtual nux::ObjectPtr<BaseShield> CreateShield(session::Manager::Ptr const&,
1088- indicator::Indicators::Ptr const&,
1089+ menu::Manager::Ptr const&,
1090 Accelerators::Ptr const&,
1091 nux::ObjectPtr<AbstractUserPromptView> const&,
1092 int monitor, bool is_primary) = 0;
1093@@ -50,7 +50,7 @@
1094 struct ShieldFactory : ShieldFactoryInterface
1095 {
1096 nux::ObjectPtr<BaseShield> CreateShield(session::Manager::Ptr const&,
1097- indicator::Indicators::Ptr const&,
1098+ menu::Manager::Ptr const&,
1099 Accelerators::Ptr const&,
1100 nux::ObjectPtr<AbstractUserPromptView> const&,
1101 int monitor, bool is_primary) override;
1102
1103=== modified file 'panel/PanelIndicatorEntryView.cpp'
1104--- panel/PanelIndicatorEntryView.cpp 2016-02-17 13:14:37 +0000
1105+++ panel/PanelIndicatorEntryView.cpp 2016-08-30 14:38:39 +0000
1106@@ -33,6 +33,8 @@
1107 #include "unity-shared/RawPixel.h"
1108 #include "unity-shared/WindowManager.h"
1109 #include "unity-shared/ThemeSettings.h"
1110+#include "unity-shared/UBusWrapper.h"
1111+#include "unity-shared/UBusMessages.h"
1112 #include "unity-shared/UnitySettings.h"
1113
1114 namespace unity
1115@@ -117,6 +119,9 @@
1116 }
1117 else
1118 {
1119+ if (overlay_showing_)
1120+ UBusManager::SendMessage(UBUS_OVERLAY_CLOSE_REQUEST);
1121+
1122 WindowManager& wm = WindowManager::Default();
1123
1124 if (wm.IsExpoActive())
1125@@ -140,6 +145,11 @@
1126 wm.TerminateScale();
1127 }
1128
1129+ // This is ugly... But Nux fault!
1130+ auto const& abs_geo = GetAbsoluteGeometry();
1131+ guint64 timestamp = nux::GetGraphicsDisplay()->GetCurrentEvent().x11_timestamp;
1132+ WindowManager::Default().UnGrabMousePointer(timestamp, button, abs_geo.x, abs_geo.y);
1133+
1134 Activate(button);
1135 }
1136 }
1137
1138=== modified file 'panel/PanelMenuView.cpp'
1139--- panel/PanelMenuView.cpp 2015-12-16 15:12:05 +0000
1140+++ panel/PanelMenuView.cpp 2016-08-30 14:38:39 +0000
1141@@ -102,7 +102,6 @@
1142 , ignore_menu_visibility_(false)
1143 , integrated_menus_(menu_manager_->integrated_menus())
1144 , always_show_menus_(menu_manager_->always_show_menus())
1145- , ignore_leave_events_(false)
1146 , desktop_name_(get_current_desktop())
1147 {
1148 if (ApplicationWindowPtr const& win = ApplicationManager::Default().GetActiveWindow())
1149@@ -1814,14 +1813,9 @@
1150 }
1151 }
1152
1153-void PanelMenuView::IgnoreLeaveEvents(bool ignore)
1154-{
1155- ignore_leave_events_ = ignore;
1156-}
1157-
1158 void PanelMenuView::OnPanelViewMouseLeave(int x, int y, unsigned long mouse_button_state, unsigned long special_keys_state)
1159 {
1160- if (always_show_menus_ || ignore_leave_events_)
1161+ if (always_show_menus_)
1162 return;
1163
1164 if (is_inside_)
1165
1166=== modified file 'panel/PanelMenuView.h'
1167--- panel/PanelMenuView.h 2015-11-05 14:54:13 +0000
1168+++ panel/PanelMenuView.h 2016-08-30 14:38:39 +0000
1169@@ -56,7 +56,6 @@
1170 bool HasKeyActivableMenus() const;
1171
1172 void NotifyAllMenusClosed();
1173- void IgnoreLeaveEvents(bool);
1174
1175 virtual void AddIndicator(indicator::Indicator::Ptr const& indicator);
1176
1177@@ -192,7 +191,6 @@
1178 bool ignore_menu_visibility_;
1179 bool integrated_menus_;
1180 bool always_show_menus_;
1181- bool ignore_leave_events_;
1182
1183 nux::Geometry monitor_geo_;
1184 const std::string desktop_name_;
1185
1186=== modified file 'panel/PanelView.cpp'
1187--- panel/PanelView.cpp 2016-08-12 13:57:19 +0000
1188+++ panel/PanelView.cpp 2016-08-30 14:38:39 +0000
1189@@ -42,7 +42,8 @@
1190 namespace
1191 {
1192 const RawPixel TRIANGLE_THRESHOLD = 5_em;
1193-const int refine_gradient_midpoint = 959;
1194+const double SCRUB_VELOCITY_THRESHOLD = 0.05;
1195+const RawPixel REFINE_GRADIENT_MIDPOINT = 959;
1196 }
1197
1198
1199@@ -113,10 +114,9 @@
1200
1201 remote_->on_object_added.connect(sigc::mem_fun(this, &PanelView::OnObjectAdded));
1202 remote_->on_object_removed.connect(sigc::mem_fun(this, &PanelView::OnObjectRemoved));
1203- remote_->on_entry_activated.connect(sigc::mem_fun(this, &PanelView::OnEntryActivated));
1204- remote_->on_entry_show_menu.connect(sigc::mem_fun(this, &PanelView::OnEntryShowMenu));
1205 menus->key_activate_entry.connect(sigc::mem_fun(this, &PanelView::ActivateEntry));
1206 menus->open_first.connect(sigc::mem_fun(this, &PanelView::ActivateFirstSensitive));
1207+ menus->RegisterTracker(GetPanelName(), sigc::mem_fun(this, &PanelView::OnMenuPointerMoved));
1208
1209 ubus_manager_.RegisterInterest(UBUS_OVERLAY_HIDDEN, sigc::mem_fun(this, &PanelView::OnOverlayHidden));
1210 ubus_manager_.RegisterInterest(UBUS_OVERLAY_SHOWN, sigc::mem_fun(this, &PanelView::OnOverlayShown));
1211@@ -374,7 +374,7 @@
1212 GfxContext.GetRenderStates().SetBlend(true, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1213 nux::TexCoordXForm refine_texxform;
1214
1215- int refine_x_pos = geo.x + (stored_dash_width_ - refine_gradient_midpoint);
1216+ int refine_x_pos = geo.x + (stored_dash_width_ - REFINE_GRADIENT_MIDPOINT.CP(Settings::Instance().em(monitor_)));
1217
1218 if (Settings::Instance().launcher_position() == LauncherPosition::LEFT)
1219 refine_x_pos += unity::Settings::Instance().LauncherSize(monitor_);
1220@@ -473,7 +473,7 @@
1221
1222 nux::Geometry refine_geo = geo;
1223
1224- int refine_x_pos = geo.x + (stored_dash_width_ - refine_gradient_midpoint);
1225+ int refine_x_pos = geo.x + (stored_dash_width_ - REFINE_GRADIENT_MIDPOINT.CP(Settings::Instance().em(monitor_)));
1226 if (Settings::Instance().launcher_position() == LauncherPosition::LEFT)
1227 refine_x_pos += unity::Settings::Instance().LauncherSize(monitor_);
1228
1229@@ -627,7 +627,7 @@
1230 QueueDraw();
1231 }
1232
1233-void PanelView::OnMenuPointerMoved(int x, int y)
1234+void PanelView::OnMenuPointerMoved(int x, int y, double speed)
1235 {
1236 nux::Geometry const& geo = GetAbsoluteGeometry();
1237
1238@@ -648,116 +648,6 @@
1239 }
1240 }
1241
1242-static bool PointInTriangle(nux::Point const& p, nux::Point const& t0, nux::Point const& t1, nux::Point const& t2)
1243-{
1244- int s = t0.y * t2.x - t0.x * t2.y + (t2.y - t0.y) * p.x + (t0.x - t2.x) * p.y;
1245- int t = t0.x * t1.y - t0.y * t1.x + (t0.y - t1.y) * p.x + (t1.x - t0.x) * p.y;
1246-
1247- if ((s < 0) != (t < 0))
1248- return false;
1249-
1250- int A = -t1.y * t2.x + t0.y * (t2.x - t1.x) + t0.x * (t1.y - t2.y) + t1.x * t2.y;
1251- if (A < 0)
1252- {
1253- s = -s;
1254- t = -t;
1255- A = -A;
1256- }
1257-
1258- return s > 0 && t > 0 && (s + t) < A;
1259-}
1260-
1261-static double GetMouseVelocity(nux::Point const& p0, nux::Point const& p1, util::Timer &timer)
1262-{
1263- int dx, dy;
1264- double speed;
1265- auto millis = timer.ElapsedMicroSeconds();
1266-
1267- if (millis == 0)
1268- return 1;
1269-
1270- dx = p0.x - p1.x;
1271- dy = p0.y - p1.y;
1272-
1273- speed = sqrt(dx * dx + dy * dy) / millis * 1000;
1274-
1275- return speed;
1276-}
1277-
1278-bool PanelView::TrackMenuPointer()
1279-{
1280- nux::Point const& mouse = nux::GetGraphicsDisplay()->GetMouseScreenCoord();
1281- double speed = GetMouseVelocity(mouse, tracked_pointer_pos_, mouse_tracker_timer_);
1282-
1283- mouse_tracker_timer_.Reset();
1284- tracked_pointer_pos_ = mouse;
1285-
1286- double scale = Settings::Instance().em(monitor_)->DPIScale();
1287- if (speed > 0 && PointInTriangle(mouse,
1288- nux::Point(triangle_top_corner_.x, std::max(triangle_top_corner_.y - TRIANGLE_THRESHOLD.CP(scale), 0)),
1289- nux::Point(menu_geo_.x, menu_geo_.y),
1290- nux::Point(menu_geo_.x + menu_geo_.width, menu_geo_.y)))
1291- {
1292- return true;
1293- }
1294-
1295- if (mouse != triangle_top_corner_)
1296- {
1297- triangle_top_corner_ = mouse;
1298- OnMenuPointerMoved(mouse.x, mouse.y);
1299- }
1300-
1301- return true;
1302-}
1303-
1304-void PanelView::OnEntryActivated(std::string const& panel, std::string const& entry_id, nux::Rect const& menu_geo)
1305-{
1306- if (!panel.empty() && panel != GetPanelName())
1307- return;
1308-
1309- menu_geo_ = menu_geo;
1310-
1311- bool active = !entry_id.empty();
1312- if (active && !track_menu_pointer_timeout_)
1313- {
1314- //
1315- // Track menus being scrubbed at 60Hz (about every 16 millisec)
1316- // It might sound ugly, but it's far nicer (and more responsive) than the
1317- // code it replaces which used to capture motion events in another process
1318- // (unity-panel-service) and send them to us over dbus.
1319- // NOTE: The reason why we have to use a timer instead of tracking motion
1320- // events is because the motion events will never be delivered to this
1321- // process. All the motion events will go to unity-panel-service while
1322- // scrubbing because the active panel menu has (needs) the pointer grab.
1323- //
1324- mouse_tracker_timer_.Reset();
1325- triangle_top_corner_ = nux::GetGraphicsDisplay()->GetMouseScreenCoord();
1326- track_menu_pointer_timeout_.reset(new glib::Timeout(16));
1327- track_menu_pointer_timeout_->Run(sigc::mem_fun(this, &PanelView::TrackMenuPointer));
1328- }
1329- else if (!active)
1330- {
1331- track_menu_pointer_timeout_.reset();
1332- menu_view_->NotifyAllMenusClosed();
1333- tracked_pointer_pos_ = {-1, -1};
1334- }
1335-
1336- if (overlay_is_open_)
1337- ubus_manager_.SendMessage(UBUS_OVERLAY_CLOSE_REQUEST);
1338-}
1339-
1340-void PanelView::OnEntryShowMenu(std::string const& entry_id, unsigned xid,
1341- int x, int y, unsigned button)
1342-{
1343- if (!track_menu_pointer_timeout_)
1344- {
1345- // This is ugly... But Nux fault!
1346- menu_view_->IgnoreLeaveEvents(true);
1347- WindowManager::Default().UnGrabMousePointer(CurrentTime, button, x, y);
1348- menu_view_->IgnoreLeaveEvents(false);
1349- }
1350-}
1351-
1352 bool PanelView::ActivateFirstSensitive()
1353 {
1354 if (!IsActive())
1355@@ -768,7 +658,6 @@
1356 {
1357 // Since this only happens on keyboard events, we need to prevent that the
1358 // pointer tracker would select another entry.
1359- tracked_pointer_pos_ = nux::GetGraphicsDisplay()->GetMouseScreenCoord();
1360 return true;
1361 }
1362
1363@@ -785,7 +674,6 @@
1364 {
1365 // Since this only happens on keyboard events, we need to prevent that the
1366 // pointer tracker would select another entry.
1367- tracked_pointer_pos_ = nux::GetGraphicsDisplay()->GetMouseScreenCoord();
1368 return true;
1369 }
1370
1371
1372=== modified file 'panel/PanelView.h'
1373--- panel/PanelView.h 2016-03-30 18:18:07 +0000
1374+++ panel/PanelView.h 2016-08-30 14:38:39 +0000
1375@@ -35,7 +35,6 @@
1376 #include "unity-shared/Introspectable.h"
1377 #include "unity-shared/MenuManager.h"
1378 #include "unity-shared/MockableBaseWindow.h"
1379-#include "unity-shared/Timer.h"
1380 #include "PanelMenuView.h"
1381 #include "PanelTray.h"
1382 #include "PanelIndicatorsView.h"
1383@@ -88,9 +87,6 @@
1384 void OnObjectAdded(indicator::Indicator::Ptr const& proxy);
1385 void OnObjectRemoved(indicator::Indicator::Ptr const& proxy);
1386 void OnIndicatorViewUpdated();
1387- void OnMenuPointerMoved(int x, int y);
1388- void OnEntryActivated(std::string const& panel, std::string const& entry_id, nux::Rect const& geo);
1389- void OnEntryShowMenu(std::string const& entry_id, unsigned xid, int x, int y, unsigned button);
1390
1391 private:
1392 std::string GetPanelName() const;
1393@@ -100,6 +96,8 @@
1394 void OnSpreadInitiate();
1395 void OnSpreadTerminate();
1396 void OnLowGfxChanged();
1397+ void OnMenuPointerMoved(int x, int y, double speed);
1398+ void OnActiveEntryEvent(XEvent const&);
1399 void EnableOverlayMode(bool);
1400 void LoadTextures();
1401
1402@@ -109,7 +107,6 @@
1403 bool IsTransparent();
1404 void UpdateBackground();
1405 void ForceUpdateBackground();
1406- bool TrackMenuPointer();
1407 void SyncGeometries();
1408 void AddPanelView(PanelIndicatorsView* child, unsigned int stretchFactor);
1409
1410@@ -133,10 +130,6 @@
1411 BaseTexturePtr bg_refine_single_column_tex_;
1412 std::unique_ptr<nux::AbstractPaintLayer> bg_refine_single_column_layer_;
1413
1414- std::string active_overlay_;
1415- nux::Point tracked_pointer_pos_, triangle_top_corner_;
1416- util::Timer mouse_tracker_timer_;
1417-
1418 bool is_dirty_;
1419 bool opacity_maximized_toggle_;
1420 bool needs_geo_sync_;
1421@@ -144,15 +137,13 @@
1422 float opacity_;
1423 int monitor_;
1424 int stored_dash_width_;
1425-
1426- nux::Geometry menu_geo_;
1427+ std::string active_overlay_;
1428
1429 connection::Manager on_indicator_updated_connections_;
1430 connection::Manager maximized_opacity_toggle_connections_;
1431 BackgroundEffectHelper bg_effect_helper_;
1432 nux::ObjectPtr<nux::IOpenGLBaseTexture> bg_blur_texture_;
1433 UBusManager ubus_manager_;
1434- glib::Source::UniquePtr track_menu_pointer_timeout_;
1435 };
1436
1437 } // namespace panel
1438
1439=== modified file 'plugins/unityshell/src/unityshell.h'
1440--- plugins/unityshell/src/unityshell.h 2016-08-12 11:21:48 +0000
1441+++ plugins/unityshell/src/unityshell.h 2016-08-30 14:38:39 +0000
1442@@ -56,6 +56,7 @@
1443 #include "DashStyle.h"
1444 #include "EdgeBarrierController.h"
1445 #include "FavoriteStoreGSettings.h"
1446+#include "InputMonitor.h"
1447 #include "ShortcutController.h"
1448 #include "LauncherController.h"
1449 #include "LockScreenController.h"
1450@@ -317,6 +318,7 @@
1451 internal::FavoriteStoreGSettings favorite_store_;
1452 ThumbnailGenerator thumbnail_generator_;
1453 lockscreen::Settings lockscreen_settings_;
1454+ input::Monitor input_monitor_;
1455
1456 /* The window thread should be the last thing removed, as c++ does it in reverse order */
1457 std::unique_ptr<nux::WindowThread> wt;
1458
1459=== modified file 'services/CMakeLists.txt'
1460--- services/CMakeLists.txt 2016-02-09 01:26:22 +0000
1461+++ services/CMakeLists.txt 2016-08-30 14:38:39 +0000
1462@@ -58,3 +58,34 @@
1463
1464 configure_file(unity-panel-service-lockscreen.conf.in ${CMAKE_CURRENT_BINARY_DIR}/unity-panel-service-lockscreen.conf)
1465 install(FILES ${CMAKE_CURRENT_BINARY_DIR}/unity-panel-service-lockscreen.conf DESTINATION ${CMAKE_INSTALL_DATADIR}/upstart/sessions)
1466+
1467+##
1468+## Systemd Unit Files
1469+##
1470+
1471+# where to install
1472+# Uncomment when we drop Vivid
1473+# pkg_get_variable(SYSTEMD_USER_DIR systemd systemduserunitdir)
1474+set (SYSTEMD_USER_DIR "/usr/lib/systemd/user")
1475+message (STATUS "${SYSTEMD_USER_DIR} is the systemd user unit file install dir")
1476+
1477+configure_file (unity-panel-service.service.in "${CMAKE_CURRENT_BINARY_DIR}/unity-panel-service.service")
1478+configure_file (unity-panel-service-lockscreen.service.in "${CMAKE_CURRENT_BINARY_DIR}/unity-panel-service-lockscreen.service")
1479+
1480+install( FILES
1481+ "${CMAKE_CURRENT_BINARY_DIR}/unity-panel-service.service"
1482+ "${CMAKE_CURRENT_BINARY_DIR}/unity-panel-service-lockscreen.service"
1483+ "${CMAKE_CURRENT_SOURCE_DIR}/unity-screen-locked.target"
1484+ DESTINATION "${SYSTEMD_USER_DIR}")
1485+
1486+##
1487+## Upstart systemd override Job File
1488+##
1489+
1490+set (UPSTART_SYSTEMD_OVERRIDE_DIR "${CMAKE_INSTALL_FULL_DATADIR}/upstart/systemd-session/upstart")
1491+message (STATUS "${UPSTART_SYSTEMD_OVERRIDE_DIR} is the Upstart override Job File for systemd dir")
1492+
1493+install (FILES
1494+ unity-panel-service.override
1495+ unity-panel-service-lockscreen.override
1496+ DESTINATION "${UPSTART_SYSTEMD_OVERRIDE_DIR}")
1497
1498=== added file 'services/unity-panel-service-lockscreen.override'
1499--- services/unity-panel-service-lockscreen.override 1970-01-01 00:00:00 +0000
1500+++ services/unity-panel-service-lockscreen.override 2016-08-30 14:38:39 +0000
1501@@ -0,0 +1,1 @@
1502+manual
1503
1504=== added file 'services/unity-panel-service-lockscreen.service.in'
1505--- services/unity-panel-service-lockscreen.service.in 1970-01-01 00:00:00 +0000
1506+++ services/unity-panel-service-lockscreen.service.in 2016-08-30 14:38:39 +0000
1507@@ -0,0 +1,7 @@
1508+[Unit]
1509+Description=Backing Service for the Unity Panel in Lockscreen mode
1510+PartOf=unity-screen-locked.target
1511+
1512+[Service]
1513+ExecStart=${CMAKE_INSTALL_FULL_LIBDIR}/unity/unity-panel-service --lockscreen-mode
1514+Restart=on-failure
1515
1516=== added file 'services/unity-panel-service.override'
1517--- services/unity-panel-service.override 1970-01-01 00:00:00 +0000
1518+++ services/unity-panel-service.override 2016-08-30 14:38:39 +0000
1519@@ -0,0 +1,1 @@
1520+manual
1521
1522=== added file 'services/unity-panel-service.service.in'
1523--- services/unity-panel-service.service.in 1970-01-01 00:00:00 +0000
1524+++ services/unity-panel-service.service.in 2016-08-30 14:38:39 +0000
1525@@ -0,0 +1,9 @@
1526+[Unit]
1527+Description=Backing Service for the Unity Panel
1528+After=unity7.service
1529+PartOf=graphical-session.target
1530+BindsTo=indicators-pre.target
1531+
1532+[Service]
1533+ExecStart=${CMAKE_INSTALL_FULL_LIBDIR}/unity/unity-panel-service
1534+Restart=on-failure
1535
1536=== added file 'services/unity-screen-locked.target'
1537--- services/unity-screen-locked.target 1970-01-01 00:00:00 +0000
1538+++ services/unity-screen-locked.target 2016-08-30 14:38:39 +0000
1539@@ -0,0 +1,4 @@
1540+[Unit]
1541+Description=A target that, when running, represents the screen being locked
1542+Wants=ubuntu-panel-service-lock.service
1543+PartOf=graphical-session.target
1544
1545=== modified file 'tests/CMakeLists.txt'
1546--- tests/CMakeLists.txt 2015-12-17 22:32:37 +0000
1547+++ tests/CMakeLists.txt 2016-08-30 14:38:39 +0000
1548@@ -286,6 +286,7 @@
1549 test_switcher_controller_class.cpp
1550 test_switcher_model.cpp
1551 test_switcher_view.cpp
1552+ test_systemd_wrapper.cpp
1553 test_tabiterator.cpp
1554 test_texture_cache.cpp
1555 test_text_input.cpp
1556
1557=== modified file 'tests/test_edge_barrier_controller.cpp'
1558--- tests/test_edge_barrier_controller.cpp 2015-01-15 15:02:24 +0000
1559+++ tests/test_edge_barrier_controller.cpp 2016-08-30 14:38:39 +0000
1560@@ -25,6 +25,7 @@
1561
1562 #include "EdgeBarrierController.h"
1563 #include "EdgeBarrierControllerPrivate.h"
1564+#include "InputMonitor.h"
1565
1566 using namespace unity;
1567 using namespace unity::ui;
1568@@ -108,6 +109,7 @@
1569
1570 TestBarrierSubscriber horizontal_subscribers_[monitors::MAX];
1571 TestBarrierSubscriber vertical_subscribers_[monitors::MAX];
1572+ input::Monitor im;
1573 MockUScreen uscreen;
1574 EdgeBarrierController bc;
1575 };
1576
1577=== modified file 'tests/test_lockscreen_controller.cpp'
1578--- tests/test_lockscreen_controller.cpp 2016-06-21 14:40:26 +0000
1579+++ tests/test_lockscreen_controller.cpp 2016-08-30 14:38:39 +0000
1580@@ -55,7 +55,7 @@
1581 struct MockShield : BaseShield
1582 {
1583 MockShield()
1584- : BaseShield(nullptr, nullptr, nullptr, nux::ObjectPtr<AbstractUserPromptView>(), 0, false)
1585+ : BaseShield(nullptr, nullptr, nux::ObjectPtr<AbstractUserPromptView>(), 0, false)
1586 {}
1587
1588 MOCK_CONST_METHOD0(IsIndicatorOpen, bool());
1589@@ -67,7 +67,7 @@
1590 struct ShieldFactoryMock : ShieldFactoryInterface
1591 {
1592 nux::ObjectPtr<BaseShield> CreateShield(session::Manager::Ptr const&,
1593- indicator::Indicators::Ptr const&,
1594+ menu::Manager::Ptr const&,
1595 Accelerators::Ptr const&,
1596 nux::ObjectPtr<AbstractUserPromptView> const&,
1597 int, bool) override
1598@@ -83,9 +83,10 @@
1599 , session_manager(std::make_shared<NiceMock<session::MockManager>>())
1600 , key_grabber(std::make_shared<key::MockGrabber::Nice>())
1601 , dbus_manager(std::make_shared<DBusManager>(session_manager))
1602+ , systemd_wrapper(std::make_shared<SystemdWrapper>())
1603 , upstart_wrapper(std::make_shared<UpstartWrapper>())
1604 , shield_factory(std::make_shared<ShieldFactoryMock>())
1605- , controller(dbus_manager, session_manager, key_grabber, upstart_wrapper, shield_factory)
1606+ , controller(dbus_manager, session_manager, key_grabber, systemd_wrapper, upstart_wrapper, shield_factory)
1607 {}
1608
1609 struct ControllerWrap : Controller
1610@@ -93,9 +94,10 @@
1611 ControllerWrap(DBusManager::Ptr const& dbus_manager,
1612 session::Manager::Ptr const& session_manager,
1613 key::Grabber::Ptr const& key_grabber,
1614+ SystemdWrapper::Ptr const& systemd_wrapper,
1615 UpstartWrapper::Ptr const& upstart_wrapper,
1616 ShieldFactoryInterface::Ptr const& shield_factory)
1617- : Controller(dbus_manager, session_manager, key_grabber, upstart_wrapper, shield_factory, /* test_mode */ true)
1618+ : Controller(dbus_manager, session_manager, key_grabber, systemd_wrapper, upstart_wrapper, shield_factory, /* test_mode */ true)
1619 {}
1620
1621 using Controller::shields_;
1622@@ -112,6 +114,7 @@
1623 session::MockManager::Ptr session_manager;
1624 key::MockGrabber::Ptr key_grabber;
1625 DBusManager::Ptr dbus_manager;
1626+ unity::SystemdWrapper::Ptr systemd_wrapper;
1627 unity::UpstartWrapper::Ptr upstart_wrapper;
1628
1629 ShieldFactoryMock::Ptr shield_factory;
1630
1631=== modified file 'tests/test_panel_controller.cpp'
1632--- tests/test_panel_controller.cpp 2014-03-21 04:40:12 +0000
1633+++ tests/test_panel_controller.cpp 2016-08-30 14:38:39 +0000
1634@@ -19,6 +19,7 @@
1635
1636 #include <gmock/gmock.h>
1637
1638+#include "InputMonitor.h"
1639 #include "PanelController.h"
1640 #include "PanelStyle.h"
1641 #include "PanelView.h"
1642@@ -46,6 +47,7 @@
1643 menu::MockManager::Ptr menus;
1644 ui::EdgeBarrierController::Ptr edge_barriers;
1645 launcher::Options::Ptr options;
1646+ input::Monitor im;
1647 };
1648
1649 TEST_F(TestPanelController, Construction)
1650
1651=== modified file 'tests/test_panel_view.cpp'
1652--- tests/test_panel_view.cpp 2014-12-12 22:33:24 +0000
1653+++ tests/test_panel_view.cpp 2016-08-30 14:38:39 +0000
1654@@ -25,6 +25,7 @@
1655 #include "unity-shared/PanelStyle.h"
1656 #include "unity-shared/UBusMessages.h"
1657 #include "unity-shared/UBusWrapper.h"
1658+ #include "InputMonitor.h"
1659
1660 #include "mock_menu_manager.h"
1661 #include "test_standalone_wm.h"
1662@@ -43,6 +44,7 @@
1663 nux::ObjectPtr<MockableBaseWindow> window_;
1664 nux::ObjectPtr<PanelView> panel_view_;
1665 testwrapper::StandaloneWM WM;
1666+ input::Monitor im;
1667
1668 TestPanelView()
1669 : window_(new MockableBaseWindow())
1670
1671=== added file 'tests/test_systemd_wrapper.cpp'
1672--- tests/test_systemd_wrapper.cpp 1970-01-01 00:00:00 +0000
1673+++ tests/test_systemd_wrapper.cpp 2016-08-30 14:38:39 +0000
1674@@ -0,0 +1,111 @@
1675+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
1676+/*
1677+* Copyright (c) 2016 Canonical Ltd
1678+*
1679+* This program is free software: you can redistribute it and/or modify
1680+* it under the terms of the GNU General Public License version 3 as
1681+* published by the Free Software Foundation.
1682+*
1683+* This program is distributed in the hope that it will be useful,
1684+* but WITHOUT ANY WARRANTY; without even the implied warranty of
1685+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1686+* GNU General Public License for more details.
1687+*
1688+* You should have received a copy of the GNU General Public License
1689+* along with this program. If not, see <http://www.gnu.org/licenses/>.
1690+*
1691+* Authored by: Ted Gould <ted@canonical.com>
1692+*/
1693+
1694+#include <gtest/gtest.h>
1695+using namespace testing;
1696+
1697+#include "unity-shared/SystemdWrapper.h"
1698+
1699+#include <UnityCore/GLibDBusServer.h>
1700+#include <UnityCore/Variant.h>
1701+
1702+#include "test_utils.h"
1703+
1704+namespace
1705+{
1706+
1707+const std::string SYSTEMD =
1708+R"(<node>
1709+ <interface name="org.freedesktop.systemd1.Manager">
1710+ <method name="StartUnit">
1711+ <arg name="name" type="s" direction="in" />
1712+ <arg name="mode" type="s" direction="in" />
1713+ <arg name="job" type="o" direction="out" />
1714+ </method>
1715+ <method name="StopUnit">
1716+ <arg name="name" type="s" direction="in" />
1717+ <arg name="mode" type="s" direction="in" />
1718+ <arg name="job" type="o" direction="out" />
1719+ </method>
1720+ </interface>
1721+</node>)";
1722+
1723+struct MockSystemdWrapper : unity::SystemdWrapper {
1724+ MockSystemdWrapper()
1725+ : SystemdWrapper(SystemdWrapper::TestMode())
1726+ {}
1727+};
1728+
1729+struct TestSystemdWrapper : public Test
1730+{
1731+ TestSystemdWrapper()
1732+ {
1733+ systemd_server_ = std::make_shared<unity::glib::DBusServer>("com.canonical.Unity.Test.Systemd");
1734+ systemd_server_->AddObjects(SYSTEMD, "/org/freedesktop/systemd1");
1735+
1736+ Utils::WaitUntilMSec([this] { return systemd_server_->IsConnected(); });
1737+ Utils::WaitUntilMSec([this] { return systemd_wrapper_.IsConnected(); });
1738+ }
1739+
1740+ unity::glib::DBusServer::Ptr systemd_server_;
1741+ MockSystemdWrapper systemd_wrapper_;
1742+};
1743+
1744+
1745+TEST_F(TestSystemdWrapper, Start)
1746+{
1747+ bool start_sent = false;
1748+
1749+ systemd_server_->GetObjects().front()->SetMethodsCallsHandler([&] (std::string const& method, GVariant* par) -> GVariant* {
1750+ if (method == "StartUnit")
1751+ {
1752+ start_sent = true;
1753+
1754+ std::string event_name = glib::Variant(g_variant_get_child_value(par, 0)).GetString();
1755+ EXPECT_EQ("unity-screen-locked", event_name);
1756+ }
1757+
1758+ return nullptr;
1759+ });
1760+
1761+ systemd_wrapper_.Start("unity-screen-locked");
1762+ Utils::WaitUntil(start_sent);
1763+}
1764+
1765+TEST_F(TestSystemdWrapper, Stop)
1766+{
1767+ bool stop_sent = false;
1768+
1769+ systemd_server_->GetObjects().front()->SetMethodsCallsHandler([&] (std::string const& method, GVariant* par) -> GVariant* {
1770+ if (method == "StopUnit")
1771+ {
1772+ stop_sent = true;
1773+
1774+ std::string event_name = glib::Variant(g_variant_get_child_value(par, 0)).GetString();
1775+ EXPECT_EQ("unity-screen-locked", event_name);
1776+ }
1777+
1778+ return nullptr;
1779+ });
1780+
1781+ systemd_wrapper_.Stop("unity-screen-locked");
1782+ Utils::WaitUntil(stop_sent);
1783+}
1784+
1785+}
1786
1787=== modified file 'tools/CMakeLists.txt'
1788--- tools/CMakeLists.txt 2016-07-18 17:26:01 +0000
1789+++ tools/CMakeLists.txt 2016-08-30 14:38:39 +0000
1790@@ -28,3 +28,6 @@
1791 add_executable(unity-active-plugins-safety-check unity_active_plugins_safety_check.cpp)
1792 target_link_libraries(unity-active-plugins-safety-check ${LIBS})
1793 install(TARGETS unity-active-plugins-safety-check DESTINATION ${CMAKE_INSTALL_LIBDIR}/unity/)
1794+
1795+configure_file (${CMAKE_CURRENT_SOURCE_DIR}/unity-compiz-profile-select.in ${CMAKE_CURRENT_BINARY_DIR}/unity-compiz-profile-select @ONLY)
1796+install(FILES ${CMAKE_CURRENT_BINARY_DIR}/unity-compiz-profile-select DESTINATION ${CMAKE_INSTALL_LIBDIR}/unity/)
1797
1798=== added file 'tools/unity-compiz-profile-select.in'
1799--- tools/unity-compiz-profile-select.in 1970-01-01 00:00:00 +0000
1800+++ tools/unity-compiz-profile-select.in 2016-08-30 14:38:39 +0000
1801@@ -0,0 +1,25 @@
1802+#!/bin/bash
1803+
1804+set -e
1805+
1806+# If gnome-session is going to start compiz,
1807+# we don't want to be the ones doing it.
1808+
1809+if grep -q compiz /usr/share/gnome-session/sessions/ubuntu.session ; then
1810+ echo "GNOME Session is starting Compiz"
1811+ stop ; exit 0
1812+fi
1813+
1814+compiz_profile="ubuntu"
1815+
1816+if ! /usr/lib/nux/unity_support_test -p; then
1817+ compiz_profile="ubuntu-lowgfx"
1818+fi
1819+
1820+echo "Using compiz profile '$compiz_profile'"
1821+
1822+initctl set-env -g COMPIZ_CONFIG_PROFILE="$compiz_profile"
1823+systemctl set-environment --user COMPIZ_CONFIG_PROFILE="$compiz_profile"
1824+
1825+export COMPIZ_CONFIG_PROFILE="$compiz_profile"
1826+exec @CMAKE_INSTALL_LIBDIR@/unity/unity-active-plugins-safety-check
1827
1828=== modified file 'unity-shared/CMakeLists.txt'
1829--- unity-shared/CMakeLists.txt 2016-08-12 11:21:48 +0000
1830+++ unity-shared/CMakeLists.txt 2016-08-30 14:38:39 +0000
1831@@ -60,6 +60,7 @@
1832 SpreadFilter.cpp
1833 SpreadWidgets.cpp
1834 StaticCairoText.cpp
1835+ SystemdWrapper.cpp
1836 TextureCache.cpp
1837 TextInput.cpp
1838 TextureThumbnailProvider.cpp
1839@@ -82,6 +83,7 @@
1840 set (UNITY_SHARED_SOURCES
1841 XKeyboardUtil.cpp
1842 XWindowManager.cpp
1843+ InputMonitor.cpp
1844 ${UNITY_SHARED_SOURCES}
1845 )
1846 else()
1847
1848=== added file 'unity-shared/InputMonitor.cpp'
1849--- unity-shared/InputMonitor.cpp 1970-01-01 00:00:00 +0000
1850+++ unity-shared/InputMonitor.cpp 2016-08-30 14:38:39 +0000
1851@@ -0,0 +1,414 @@
1852+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
1853+/*
1854+ * Copyright (C) 2014 Canonical Ltd
1855+ *
1856+ * This program is free software: you can redistribute it and/or modify
1857+ * it under the terms of the GNU General Public License version 3 as
1858+ * published by the Free Software Foundation.
1859+ *
1860+ * This program is distributed in the hope that it will be useful,
1861+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1862+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1863+ * GNU General Public License for more details.
1864+ *
1865+ * You should have received a copy of the GNU General Public License
1866+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1867+ *
1868+ * Authored by: Marco Trevisan <marco.trevisan@canonical.com>
1869+ */
1870+
1871+#include "InputMonitor.h"
1872+#include "SigcSlotHash.h"
1873+
1874+#include <Nux/Nux.h>
1875+#include <NuxCore/Logger.h>
1876+#include <X11/extensions/XInput2.h>
1877+#include <UnityCore/GLibSource.h>
1878+#include <unordered_set>
1879+#include <gdk/gdkx.h>
1880+#include <glib.h>
1881+
1882+namespace unity
1883+{
1884+namespace input
1885+{
1886+namespace
1887+{
1888+DECLARE_LOGGER(logger, "unity.input.monitor");
1889+
1890+Monitor* instance_ = nullptr;
1891+
1892+const unsigned XINPUT_MAJOR_VERSION = 2;
1893+const unsigned XINPUT_MINOR_VERSION = 3;
1894+
1895+bool operator&(Events l, Events r)
1896+{
1897+ typedef std::underlying_type<Events>::type ut;
1898+ return static_cast<ut>(static_cast<ut>(l) & static_cast<ut>(r));
1899+}
1900+
1901+Events& operator|=(Events& l, Events r)
1902+{
1903+ typedef std::underlying_type<Events>::type ut;
1904+ return l = static_cast<Events>(static_cast<ut>(l) | static_cast<ut>(r));
1905+}
1906+
1907+template <typename EVENT>
1908+void initialize_event_common(EVENT* ev, XIDeviceEvent* xiev)
1909+{
1910+ ev->serial = xiev->serial;
1911+ ev->send_event = xiev->send_event;
1912+ ev->display = xiev->display;
1913+ ev->window = xiev->event;
1914+ ev->root = xiev->root;
1915+ ev->subwindow = xiev->child;
1916+ ev->time = xiev->time;
1917+ ev->x = std::round(xiev->event_x);
1918+ ev->y = std::round(xiev->event_y);
1919+ ev->x_root = std::round(xiev->root_x);
1920+ ev->y_root = std::round(xiev->root_y);
1921+ ev->state = xiev->mods.effective;
1922+ ev->same_screen = True;
1923+}
1924+
1925+template <typename EVENT_TYPE, typename NATIVE_TYPE>
1926+void initialize_event(XEvent* ev, NATIVE_TYPE* xiev);
1927+
1928+template <>
1929+void initialize_event<XButtonEvent>(XEvent* ev, XIDeviceEvent* xiev)
1930+{
1931+ XButtonEvent* bev = &ev->xbutton;
1932+ ev->type = (xiev->evtype == XI_ButtonPress) ? ButtonPress : ButtonRelease;
1933+ initialize_event_common(bev, xiev);
1934+ bev->button = xiev->detail;
1935+}
1936+
1937+template <>
1938+void initialize_event<XKeyEvent>(XEvent* ev, XIDeviceEvent* xiev)
1939+{
1940+ XKeyEvent* kev = &ev->xkey;
1941+ ev->type = (xiev->evtype == XI_KeyPress) ? KeyPress : KeyRelease;
1942+ initialize_event_common(kev, xiev);
1943+ kev->keycode = xiev->detail;
1944+}
1945+
1946+template <>
1947+void initialize_event<XMotionEvent>(XEvent* ev, XIDeviceEvent* xiev)
1948+{
1949+ XMotionEvent* mev = &ev->xmotion;
1950+ ev->type = MotionNotify;
1951+ initialize_event_common(mev, xiev);
1952+ mev->is_hint = NotifyNormal;
1953+
1954+ for (int i = 0; i < xiev->buttons.mask_len * 8; ++i)
1955+ {
1956+ if (XIMaskIsSet(xiev->buttons.mask, i))
1957+ {
1958+ mev->is_hint = NotifyHint;
1959+ break;
1960+ }
1961+ }
1962+}
1963+
1964+template <>
1965+void initialize_event<XGenericEventCookie>(XEvent* ev, XIBarrierEvent* xiev)
1966+{
1967+ XGenericEventCookie* cev = &ev->xcookie;
1968+ cev->type = GenericEvent;
1969+ cev->serial = xiev->serial;
1970+ cev->send_event = xiev->send_event;
1971+ cev->display = xiev->display;
1972+ cev->evtype = xiev->evtype;
1973+ cev->data = xiev;
1974+}
1975+}
1976+
1977+struct Monitor::Impl
1978+{
1979+#if __GNUC__ < 6
1980+ using EventCallbackSet = std::unordered_set<EventCallback>;
1981+#else
1982+ using EventCallbackSet = std::unordered_set<EventCallback, std::hash<sigc::slot_base>>;
1983+#endif
1984+
1985+ Impl()
1986+ : xi_opcode_(0)
1987+ , event_filter_set_(false)
1988+ , invoking_callbacks_(false)
1989+ {
1990+ Display *dpy = gdk_x11_get_default_xdisplay();
1991+ int event_base, error_base;
1992+
1993+ if (XQueryExtension(dpy, "XInputExtension", &xi_opcode_, &event_base, &error_base))
1994+ {
1995+ int maj = XINPUT_MAJOR_VERSION;
1996+ int min = XINPUT_MINOR_VERSION;
1997+
1998+ if (XIQueryVersion(dpy, &maj, &min) == BadRequest)
1999+ {
2000+ LOG_ERROR(logger) << "Need XInput version "<< maj << "." << min << ", "
2001+ << "impossible, to setup an InputMonitor";
2002+ }
2003+ }
2004+ else
2005+ {
2006+ LOG_ERROR(logger) << "Missing XInput, impossible to setup an InputMonitor";
2007+ }
2008+ }
2009+
2010+ ~Impl()
2011+ {
2012+ if (event_filter_set_)
2013+ {
2014+ pointer_callbacks_.clear();
2015+ key_callbacks_.clear();
2016+ barrier_callbacks_.clear();
2017+ UpdateEventMonitor();
2018+ }
2019+ }
2020+
2021+ bool RegisterClient(Events type, EventCallback const& cb)
2022+ {
2023+ bool added = false;
2024+
2025+ if (type & Events::POINTER)
2026+ added = pointer_callbacks_.insert(cb).second || added;
2027+
2028+ if (type & Events::KEYS)
2029+ added = key_callbacks_.insert(cb).second || added;
2030+
2031+ if (type & Events::BARRIER)
2032+ added = barrier_callbacks_.insert(cb).second || added;
2033+
2034+ if (added)
2035+ UpdateEventMonitor();
2036+
2037+ return added;
2038+ }
2039+
2040+ bool UnregisterClient(EventCallback const& cb)
2041+ {
2042+ if (invoking_callbacks_)
2043+ {
2044+ // Delay the event removal if we're currently invoking a callback
2045+ // not to break the callbacks loop
2046+ removal_queue_.insert(cb);
2047+ return false;
2048+ }
2049+
2050+ bool removed = false;
2051+ removed = pointer_callbacks_.erase(cb) > 0 || removed;
2052+ removed = key_callbacks_.erase(cb) > 0 || removed;
2053+ removed = barrier_callbacks_.erase(cb) > 0 || removed;
2054+
2055+ if (removed)
2056+ UpdateEventMonitor();
2057+
2058+ return removed;
2059+ }
2060+
2061+ Events RegisteredEvents(EventCallback const& cb) const
2062+ {
2063+ Events events = Events::NONE;
2064+
2065+ if (pointer_callbacks_.find(cb) != end(pointer_callbacks_))
2066+ events |= Events::POINTER;
2067+
2068+ if (key_callbacks_.find(cb) != end(key_callbacks_))
2069+ events |= Events::KEYS;
2070+
2071+ if (barrier_callbacks_.find(cb) != end(barrier_callbacks_))
2072+ events |= Events::BARRIER;
2073+
2074+ return events;
2075+ }
2076+
2077+ void UpdateEventMonitor()
2078+ {
2079+ auto* dpy = nux::GetGraphicsDisplay()->GetX11Display();
2080+ Window root = DefaultRootWindow(dpy);
2081+
2082+ unsigned char master_dev_bits[XIMaskLen(XI_LASTEVENT)] = { 0 };
2083+ XIEventMask master_dev = { XIAllMasterDevices, sizeof(master_dev_bits), master_dev_bits };
2084+
2085+ if (!barrier_callbacks_.empty())
2086+ {
2087+ XISetMask(master_dev.mask, XI_BarrierHit);
2088+ XISetMask(master_dev.mask, XI_BarrierLeave);
2089+ }
2090+
2091+ unsigned char all_devs_bits[XIMaskLen(XI_LASTEVENT)] = { 0 };
2092+ XIEventMask all_devs = { XIAllDevices, sizeof(all_devs_bits), all_devs_bits };
2093+
2094+ if (!pointer_callbacks_.empty())
2095+ {
2096+ XISetMask(all_devs.mask, XI_Motion);
2097+ XISetMask(all_devs.mask, XI_ButtonPress);
2098+ XISetMask(all_devs.mask, XI_ButtonRelease);
2099+ }
2100+
2101+ if (!key_callbacks_.empty())
2102+ {
2103+ XISetMask(all_devs.mask, XI_KeyPress);
2104+ XISetMask(all_devs.mask, XI_KeyRelease);
2105+ }
2106+
2107+ XIEventMask selected[] = {master_dev, all_devs};
2108+ XISelectEvents(dpy, root, selected, G_N_ELEMENTS(selected));
2109+ XSync(dpy, False);
2110+
2111+ if (!pointer_callbacks_.empty() || !key_callbacks_.empty() || !barrier_callbacks_.empty())
2112+ {
2113+ if (!event_filter_set_)
2114+ {
2115+ nux::GetGraphicsDisplay()->AddEventFilter({[] (XEvent event, void* data) {
2116+ return static_cast<Impl*>(data)->HandleEvent(event);
2117+ }, this});
2118+
2119+ event_filter_set_ = true;
2120+ }
2121+ }
2122+ else if (event_filter_set_)
2123+ {
2124+ nux::GetGraphicsDisplay()->RemoveEventFilter(this);
2125+ event_filter_set_ = false;
2126+ }
2127+ }
2128+
2129+ bool HandleEvent(XEvent& event)
2130+ {
2131+ bool handled = false;
2132+
2133+ if (event.type != GenericEvent || event.xcookie.extension != xi_opcode_)
2134+ return handled;
2135+
2136+ switch (event.xcookie.evtype)
2137+ {
2138+ case XI_ButtonPress:
2139+ case XI_ButtonRelease:
2140+ handled = InvokeCallbacks<XButtonEvent>(pointer_callbacks_, event);
2141+ break;
2142+ case XI_Motion:
2143+ handled = InvokeCallbacks<XMotionEvent>(pointer_callbacks_, event);
2144+ break;
2145+ case XI_KeyPress:
2146+ case XI_KeyRelease:
2147+ handled = InvokeCallbacks<XKeyEvent>(key_callbacks_, event);
2148+ break;
2149+ case XI_BarrierHit:
2150+ case XI_BarrierLeave:
2151+ handled = InvokeCallbacks<XGenericEventCookie, XIBarrierEvent>(barrier_callbacks_, event);
2152+ break;
2153+ }
2154+
2155+ return handled;
2156+ }
2157+
2158+ template <typename EVENT_TYPE, typename NATIVE_TYPE = XIDeviceEvent>
2159+ bool InvokeCallbacks(EventCallbackSet& callbacks, XEvent& xiev)
2160+ {
2161+ XGenericEventCookie *cookie = &xiev.xcookie;
2162+
2163+ if (!XGetEventData(xiev.xany.display, cookie))
2164+ return false;
2165+
2166+ XEvent event;
2167+ initialize_event<EVENT_TYPE>(&event, reinterpret_cast<NATIVE_TYPE*>(cookie->data));
2168+ invoking_callbacks_ = true;
2169+
2170+ for (auto it = callbacks.begin(); it != callbacks.end();)
2171+ {
2172+ if (it->empty())
2173+ {
2174+ it = callbacks.erase(it);
2175+ continue;
2176+ }
2177+
2178+ (*it)(event);
2179+ ++it;
2180+ }
2181+
2182+ XFreeEventData(xiev.xany.display, cookie);
2183+ invoking_callbacks_ = false;
2184+
2185+ // A callback might unregister itself on the event callback, causing the
2186+ // above callbacks loop to crash, so in this case we save the event in the
2187+ // removal queue and eventually we unregistered these callbacks.
2188+ bool update_event_monitor = false;
2189+ for (auto it = removal_queue_.begin(); it != removal_queue_.end(); it = removal_queue_.erase(it))
2190+ {
2191+ auto const& cb = *it;
2192+ pointer_callbacks_.erase(cb);
2193+ key_callbacks_.erase(cb);
2194+ barrier_callbacks_.erase(cb);
2195+ update_event_monitor = true;
2196+ }
2197+
2198+ if (callbacks.empty() || update_event_monitor)
2199+ {
2200+ idle_removal_.reset(new glib::Idle([this] {
2201+ UpdateEventMonitor();
2202+ return false;
2203+ }));
2204+
2205+ return false;
2206+ }
2207+
2208+ return true;
2209+ }
2210+
2211+ int xi_opcode_;
2212+ bool event_filter_set_;
2213+ bool invoking_callbacks_;
2214+ glib::Source::UniquePtr idle_removal_;
2215+ EventCallbackSet pointer_callbacks_;
2216+ EventCallbackSet key_callbacks_;
2217+ EventCallbackSet barrier_callbacks_;
2218+ EventCallbackSet removal_queue_;
2219+};
2220+
2221+Monitor::Monitor()
2222+{
2223+ if (instance_)
2224+ {
2225+ LOG_WARN(logger) << "More than one input::Monitor created.";
2226+ return;
2227+ }
2228+
2229+ instance_ = this;
2230+ impl_.reset(new Impl());
2231+}
2232+
2233+Monitor::~Monitor()
2234+{
2235+ if (this == instance_)
2236+ instance_ = nullptr;
2237+}
2238+
2239+Monitor& Monitor::Get()
2240+{
2241+ if (!instance_)
2242+ {
2243+ LOG_ERROR(logger) << "No input::Monitor created yet.";
2244+ }
2245+
2246+ return *instance_;
2247+}
2248+
2249+bool Monitor::RegisterClient(Events events, EventCallback const& cb)
2250+{
2251+ return impl_->RegisterClient(events, cb);
2252+}
2253+
2254+bool Monitor::UnregisterClient(EventCallback const& cb)
2255+{
2256+ return impl_->UnregisterClient(cb);
2257+}
2258+
2259+Events Monitor::RegisteredEvents(EventCallback const& cb) const
2260+{
2261+ return impl_->RegisteredEvents(cb);
2262+}
2263+
2264+} // input namespace
2265+} // unity namespace
2266
2267=== added file 'unity-shared/InputMonitor.h'
2268--- unity-shared/InputMonitor.h 1970-01-01 00:00:00 +0000
2269+++ unity-shared/InputMonitor.h 2016-08-30 14:38:39 +0000
2270@@ -0,0 +1,67 @@
2271+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
2272+/*
2273+ * Copyright (C) 2014 Canonical Ltd
2274+ *
2275+ * This program is free software: you can redistribute it and/or modify
2276+ * it under the terms of the GNU General Public License version 3 as
2277+ * published by the Free Software Foundation.
2278+ *
2279+ * This program is distributed in the hope that it will be useful,
2280+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2281+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2282+ * GNU General Public License for more details.
2283+ *
2284+ * You should have received a copy of the GNU General Public License
2285+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2286+ *
2287+ * Authored by: Marco Trevisan <marco.trevisan@canonical.com>
2288+ */
2289+
2290+#ifndef __UNITY_INPUT_MONITOR__
2291+#define __UNITY_INPUT_MONITOR__
2292+
2293+#include <X11/Xlib.h>
2294+#include <sigc++/slot.h>
2295+#include <memory>
2296+
2297+namespace unity
2298+{
2299+namespace input
2300+{
2301+enum class Events : unsigned
2302+{
2303+ NONE = 0,
2304+ POINTER = (1 << 0),
2305+ KEYS = (1 << 1),
2306+ BARRIER = (1 << 2),
2307+ INPUT = POINTER | KEYS,
2308+ ALL = POINTER | KEYS | BARRIER
2309+};
2310+
2311+class Monitor : public sigc::trackable
2312+{
2313+public:
2314+ typedef sigc::slot<void, XEvent const&> EventCallback;
2315+
2316+ static Monitor& Get();
2317+
2318+ Monitor();
2319+ virtual ~Monitor();
2320+
2321+ bool RegisterClient(Events, EventCallback const&);
2322+ bool UnregisterClient(EventCallback const&);
2323+
2324+ Events RegisteredEvents(EventCallback const&) const;
2325+
2326+private:
2327+ Monitor(Monitor const&) = delete;
2328+ Monitor& operator=(Monitor const&) = delete;
2329+
2330+ struct Impl;
2331+ std::unique_ptr<Impl> impl_;
2332+};
2333+
2334+} // input namespace
2335+} // unity namespace
2336+
2337+#endif // __UNITY_INPUT_MONITOR__
2338
2339=== modified file 'unity-shared/MenuManager.cpp'
2340--- unity-shared/MenuManager.cpp 2015-10-02 14:02:05 +0000
2341+++ unity-shared/MenuManager.cpp 2016-08-30 14:38:39 +0000
2342@@ -21,11 +21,17 @@
2343 #include <gtk/gtk.h>
2344 #include <NuxCore/Logger.h>
2345 #include <UnityCore/GLibSignal.h>
2346+#include <UnityCore/GLibSource.h>
2347 #include <UnityCore/GLibWrapper.h>
2348 #include <UnityCore/DBusIndicators.h>
2349 #include <unordered_map>
2350
2351 #include "MenuManager.h"
2352+#include "InputMonitor.h"
2353+#include "RawPixel.h"
2354+#include "SigcSlotHash.h"
2355+#include "UnitySettings.h"
2356+#include "UScreen.h"
2357 #include "WindowManager.h"
2358
2359 namespace unity
2360@@ -40,6 +46,10 @@
2361 const std::string LIM_KEY = "integrated-menus";
2362 const std::string SHOW_MENUS_NOW_DELAY = "show-menus-now-delay";
2363 const std::string ALWAYS_SHOW_MENUS_KEY = "always-show-menus";
2364+
2365+const RawPixel TRIANGLE_THRESHOLD = 5_em;
2366+const double SCRUB_VELOCITY_THRESHOLD = 0.05;
2367+const unsigned MENU_OPEN_MOUSE_WAIT = 150;
2368 }
2369
2370 using namespace indicator;
2371@@ -51,6 +61,7 @@
2372 , indicators_(indicators)
2373 , key_grabber_(grabber)
2374 , show_now_window_(0)
2375+ , last_pointer_time_(0)
2376 , settings_(g_settings_new(SETTINGS_NAME.c_str()))
2377 {
2378 for (auto const& indicator : indicators_->GetIndicators())
2379@@ -182,9 +193,15 @@
2380 parent_->key_activate_entry.emit(entry_id);
2381 }
2382
2383- void EntryActivated(std::string const&, std::string const&, nux::Rect const& geo)
2384+ void EntryActivated(std::string const& menubar, std::string const&, nux::Rect const& geo)
2385 {
2386 parent_->menu_open = !geo.IsNull();
2387+
2388+ if (active_menubar_ != menubar)
2389+ {
2390+ active_menubar_ = menubar;
2391+ UpdateActiveTracker();
2392+ }
2393 }
2394
2395 void SetShowNowForWindow(Window xid, bool show)
2396@@ -231,15 +248,148 @@
2397 gtk_icon_theme_set_search_path(gtk_icon_theme_get_default(), gicon_paths.data(), gicon_paths.size());
2398 }
2399
2400+ bool PointInTriangle(nux::Point const& p, nux::Point const& t0, nux::Point const& t1, nux::Point const& t2)
2401+ {
2402+ int s = t0.y * t2.x - t0.x * t2.y + (t2.y - t0.y) * p.x + (t0.x - t2.x) * p.y;
2403+ int t = t0.x * t1.y - t0.y * t1.x + (t0.y - t1.y) * p.x + (t1.x - t0.x) * p.y;
2404+
2405+ if ((s < 0) != (t < 0))
2406+ return false;
2407+
2408+ int A = -t1.y * t2.x + t0.y * (t2.x - t1.x) + t0.x * (t1.y - t2.y) + t1.x * t2.y;
2409+ if (A < 0)
2410+ {
2411+ s = -s;
2412+ t = -t;
2413+ A = -A;
2414+ }
2415+
2416+ return s > 0 && t > 0 && (s + t) < A;
2417+ }
2418+
2419+ double GetMouseVelocity(nux::Point const& p0, nux::Point const& p1, Time time_delta)
2420+ {
2421+ int dx, dy;
2422+ double speed;
2423+
2424+ if (time_delta == 0)
2425+ return 1;
2426+
2427+ dx = p0.x - p1.x;
2428+ dy = p0.y - p1.y;
2429+
2430+ speed = sqrt(dx * dx + dy * dy) / time_delta;
2431+
2432+ return speed;
2433+ }
2434+
2435+ void OnActiveEntryEvent(XEvent const& e)
2436+ {
2437+ if (e.type != MotionNotify)
2438+ return;
2439+
2440+ auto const& active_entry = indicators_->GetActiveEntry();
2441+
2442+ if (!active_entry)
2443+ return;
2444+
2445+ nux::Point mouse(e.xmotion.x_root, e.xmotion.y_root);
2446+ auto monitor = UScreen::GetDefault()->GetMonitorAtPosition(mouse.x, mouse.y);
2447+ double scale = Settings::Instance().em(monitor)->DPIScale();
2448+ double speed = GetMouseVelocity(mouse, tracked_pointer_pos_, e.xmotion.time - last_pointer_time_);
2449+ auto menu_geo = active_entry->geometry();
2450+
2451+ tracked_pointer_pos_ = mouse;
2452+ last_pointer_time_ = e.xmotion.time;
2453+
2454+ if (speed > SCRUB_VELOCITY_THRESHOLD &&
2455+ PointInTriangle(mouse, {mouse.x, std::max(mouse.y - TRIANGLE_THRESHOLD.CP(scale), 0)},
2456+ menu_geo.GetPosition(), {menu_geo.x + menu_geo.width, menu_geo.y}))
2457+ {
2458+ pointer_movement_timeout_ = std::make_shared<glib::Timeout>(MENU_OPEN_MOUSE_WAIT, [this, mouse, speed] {
2459+ if (active_tracker_)
2460+ active_tracker_(mouse.x, mouse.y, speed);
2461+
2462+ return false;
2463+ });
2464+
2465+ return;
2466+ }
2467+
2468+ if (active_tracker_)
2469+ {
2470+ pointer_movement_timeout_.reset();
2471+ active_tracker_(mouse.x, mouse.y, speed);
2472+ }
2473+ }
2474+
2475+ bool RegisterTracker(std::string const& menubar, PositionTracker const& cb)
2476+ {
2477+ auto it = position_trackers_.find(menubar);
2478+
2479+ if (it != end(position_trackers_))
2480+ return false;
2481+
2482+ position_trackers_.insert({menubar, cb});
2483+
2484+ if (active_menubar_ == menubar)
2485+ UpdateActiveTracker();
2486+
2487+ return true;
2488+ }
2489+
2490+ bool UnregisterTracker(std::string const& menubar, PositionTracker const& cb)
2491+ {
2492+ auto it = position_trackers_.find(menubar);
2493+
2494+ if (it == end(position_trackers_))
2495+ return false;
2496+
2497+ if (!cb || (cb && it->second == cb))
2498+ {
2499+ position_trackers_.erase(it);
2500+ UpdateActiveTracker();
2501+ return true;
2502+ }
2503+
2504+ return false;
2505+ }
2506+
2507+ void UpdateActiveTracker()
2508+ {
2509+ auto it = position_trackers_.find(active_menubar_);
2510+ active_tracker_ = (it != end(position_trackers_)) ? it->second : PositionTracker();
2511+ pointer_movement_timeout_.reset();
2512+
2513+ if (active_tracker_)
2514+ {
2515+ if (input::Monitor::Get().RegisterClient(input::Events::POINTER, sigc::mem_fun(this, &Impl::OnActiveEntryEvent)))
2516+ last_pointer_time_ = 0;
2517+ }
2518+ else
2519+ {
2520+ input::Monitor::Get().UnregisterClient(sigc::mem_fun(this, &Impl::OnActiveEntryEvent));
2521+
2522+ if (it != end(position_trackers_))
2523+ position_trackers_.erase(it);
2524+ }
2525+ }
2526+
2527 Manager* parent_;
2528 Indicators::Ptr indicators_;
2529 AppmenuIndicator::Ptr appmenu_;
2530 key::Grabber::Ptr key_grabber_;
2531 Window show_now_window_;
2532+ std::string active_menubar_;
2533+ PositionTracker active_tracker_;
2534+ nux::Point tracked_pointer_pos_;
2535+ Time last_pointer_time_;
2536+ glib::Source::Ptr pointer_movement_timeout_;
2537 connection::Manager appmenu_connections_;
2538 connection::Wrapper active_win_conn_;
2539 glib::Object<GSettings> settings_;
2540 glib::SignalManager signals_;
2541+ std::unordered_map<std::string, PositionTracker> position_trackers_;
2542 std::unordered_map<indicator::Entry::Ptr, uint32_t> entry_actions_;
2543 };
2544
2545@@ -278,5 +428,16 @@
2546 return impl_->key_grabber_;
2547 }
2548
2549+bool Manager::RegisterTracker(std::string const& menubar, PositionTracker const& cb)
2550+{
2551+ return impl_->RegisterTracker(menubar, cb);
2552+}
2553+
2554+bool Manager::UnregisterTracker(std::string const& menubar, PositionTracker const& cb)
2555+{
2556+ return impl_->UnregisterTracker(menubar, cb);
2557+}
2558+
2559+
2560 } // menu namespace
2561 } // unity namespace
2562
2563=== modified file 'unity-shared/MenuManager.h'
2564--- unity-shared/MenuManager.h 2015-06-05 14:28:27 +0000
2565+++ unity-shared/MenuManager.h 2016-08-30 14:38:39 +0000
2566@@ -67,6 +67,10 @@
2567
2568 key::Grabber::Ptr const& KeyGrabber() const;
2569
2570+ typedef sigc::slot<void, int /*x*/, int /*y*/, double /*speed*/> PositionTracker;
2571+ bool RegisterTracker(std::string const& menubar, PositionTracker const&);
2572+ bool UnregisterTracker(std::string const& menubar, PositionTracker const& = PositionTracker());
2573+
2574 sigc::signal<void> appmenu_added;
2575 sigc::signal<void> appmenu_removed;
2576 sigc::signal<bool>::accumulated<any_true> open_first;
2577
2578=== added file 'unity-shared/SigcSlotHash.h'
2579--- unity-shared/SigcSlotHash.h 1970-01-01 00:00:00 +0000
2580+++ unity-shared/SigcSlotHash.h 2016-08-30 14:38:39 +0000
2581@@ -0,0 +1,70 @@
2582+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
2583+/*
2584+ * Copyright (C) 2016 Canonical Ltd
2585+ *
2586+ * This program is free software: you can redistribute it and/or modify
2587+ * it under the terms of the GNU General Public License version 3 as
2588+ * published by the Free Software Foundation.
2589+ *
2590+ * This program is distributed in the hope that it will be useful,
2591+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2592+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2593+ * GNU General Public License for more details.
2594+ *
2595+ * You should have received a copy of the GNU General Public License
2596+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2597+ *
2598+ * Authored by: Marco Trevisan <marco.trevisan@canonical.com>
2599+ */
2600+
2601+#ifndef __UNITY_SIGC_SLOT_HASHER__
2602+#define __UNITY_SIGC_SLOT_HASHER__
2603+
2604+#include <sigc++/slot.h>
2605+
2606+namespace sigc
2607+{
2608+inline bool operator==(slot_base const& lhs, slot_base const& rhs)
2609+{
2610+ if (!lhs.rep_ || !rhs.rep_)
2611+ return (lhs.rep_ == rhs.rep_);
2612+
2613+ return (lhs.rep_->call_ == rhs.rep_->call_);
2614+}
2615+
2616+inline bool operator!=(slot_base const& lhs, slot_base const& rhs)
2617+{
2618+ return !(lhs == rhs);
2619+}
2620+} // sigc namespace
2621+
2622+namespace std
2623+{
2624+
2625+template<>
2626+struct hash<sigc::slot_base>
2627+{
2628+ size_t operator()(sigc::slot_base const& cb) const
2629+ {
2630+ if (cb.rep_)
2631+ return hash<size_t>()(reinterpret_cast<size_t>(cb.rep_->call_));
2632+
2633+ return hash<size_t>()(reinterpret_cast<size_t>(cb.rep_));
2634+ }
2635+};
2636+
2637+#if __GNUC__ < 6
2638+template<class T>
2639+struct hash
2640+{
2641+ size_t operator()(T const& cb) const
2642+ {
2643+ static_assert(std::is_base_of<sigc::slot_base, T>::value, "Type is not derived from sigc::slot_base");
2644+ return hash<sigc::slot_base>()(cb);
2645+ }
2646+};
2647+#endif
2648+
2649+} // std namespace
2650+
2651+#endif // __UNITY_SIGC_SLOT_HASHER__
2652
2653=== modified file 'unity-shared/StandaloneWindowManager.cpp'
2654--- unity-shared/StandaloneWindowManager.cpp 2015-11-20 11:33:38 +0000
2655+++ unity-shared/StandaloneWindowManager.cpp 2016-08-30 14:38:39 +0000
2656@@ -624,6 +624,9 @@
2657 return std::string();
2658 }
2659
2660+void StandaloneWindowManager::SetCardinalProperty(Window, Atom, std::vector<long> const&)
2661+{}
2662+
2663 std::vector<long> StandaloneWindowManager::GetCardinalProperty(Window, Atom) const
2664 {
2665 return std::vector<long>();
2666
2667=== modified file 'unity-shared/StandaloneWindowManager.h'
2668--- unity-shared/StandaloneWindowManager.h 2016-03-18 18:58:26 +0000
2669+++ unity-shared/StandaloneWindowManager.h 2016-08-30 14:38:39 +0000
2670@@ -165,6 +165,7 @@
2671 virtual std::string GetWindowName(Window window_id) const;
2672 virtual bool IsOnscreenKeyboard(Window window_id) const;
2673 virtual std::string GetStringProperty(Window window_id, Atom) const;
2674+ virtual void SetCardinalProperty(Window window_id, Atom, std::vector<long> const&);
2675 virtual std::vector<long> GetCardinalProperty(Window window_id, Atom) const;
2676
2677 // Mock functions
2678
2679=== added file 'unity-shared/SystemdWrapper.cpp'
2680--- unity-shared/SystemdWrapper.cpp 1970-01-01 00:00:00 +0000
2681+++ unity-shared/SystemdWrapper.cpp 2016-08-30 14:38:39 +0000
2682@@ -0,0 +1,103 @@
2683+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 3 -*-
2684+/*
2685+* Copyright © 2016 Canonical Ltd
2686+*
2687+* This program is free software: you can redistribute it and/or modify
2688+* it under the terms of the GNU General Public License version 3 as
2689+* published by the Free Software Foundation.
2690+*
2691+* This program is distributed in the hope that it will be useful,
2692+* but WITHOUT ANY WARRANTY; without even the implied warranty of
2693+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2694+* GNU General Public License for more details.
2695+*
2696+* You should have received a copy of the GNU General Public License
2697+* along with this program. If not, see <http://www.gnu.org/licenses/>.
2698+*
2699+* Authored by: Ted Gould <ted@canonical.com>
2700+*/
2701+
2702+#include "SystemdWrapper.h"
2703+
2704+#include <UnityCore/GLibDBusProxy.h>
2705+
2706+namespace unity
2707+{
2708+
2709+//
2710+// Start private implementation
2711+//
2712+
2713+class SystemdWrapper::Impl
2714+{
2715+public:
2716+ Impl(bool test);
2717+
2718+ void Start(std::string const& name);
2719+ void Stop(std::string const& name);
2720+ bool IsConnected();
2721+
2722+private:
2723+ glib::DBusProxy::Ptr systemd_proxy_;
2724+};
2725+
2726+SystemdWrapper::Impl::Impl(bool test)
2727+{
2728+ std::string busname = "org.freedesktop.systemd1";
2729+ if (test) {
2730+ busname = "com.canonical.Unity.Test.Systemd";
2731+ }
2732+
2733+ systemd_proxy_ = std::make_shared<unity::glib::DBusProxy>(busname, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager");
2734+}
2735+
2736+void SystemdWrapper::Impl::Start(std::string const& name)
2737+{
2738+ if (IsConnected()) {
2739+ systemd_proxy_->Call("StartUnit", g_variant_new("(ss)", name.c_str(), "replace"));
2740+ }
2741+}
2742+
2743+void SystemdWrapper::Impl::Stop(std::string const& name)
2744+{
2745+ if (IsConnected()) {
2746+ systemd_proxy_->Call("StopUnit", g_variant_new("(ss)", name.c_str(), "replace"));
2747+ }
2748+}
2749+
2750+bool SystemdWrapper::Impl::IsConnected()
2751+{
2752+ return systemd_proxy_->IsConnected();
2753+}
2754+
2755+//
2756+// End private implementation
2757+//
2758+
2759+SystemdWrapper::SystemdWrapper()
2760+ : pimpl_(new Impl(false))
2761+{}
2762+
2763+SystemdWrapper::SystemdWrapper(SystemdWrapper::TestMode const& tm)
2764+ : pimpl_(new Impl(true))
2765+{}
2766+
2767+SystemdWrapper::~SystemdWrapper()
2768+{}
2769+
2770+void SystemdWrapper::Start(std::string const& name)
2771+{
2772+ pimpl_->Start(name);
2773+}
2774+
2775+void SystemdWrapper::Stop(std::string const& name)
2776+{
2777+ pimpl_->Stop(name);
2778+}
2779+
2780+bool SystemdWrapper::IsConnected()
2781+{
2782+ return pimpl_->IsConnected();
2783+}
2784+
2785+}
2786
2787=== added file 'unity-shared/SystemdWrapper.h'
2788--- unity-shared/SystemdWrapper.h 1970-01-01 00:00:00 +0000
2789+++ unity-shared/SystemdWrapper.h 2016-08-30 14:38:39 +0000
2790@@ -0,0 +1,55 @@
2791+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
2792+/*
2793+* Copyright © 2016 Canonical Ltd
2794+*
2795+* This program is free software: you can redistribute it and/or modify
2796+* it under the terms of the GNU General Public License version 3 as
2797+* published by the Free Software Foundation.
2798+*
2799+* This program is distributed in the hope that it will be useful,
2800+* but WITHOUT ANY WARRANTY; without even the implied warranty of
2801+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2802+* GNU General Public License for more details.
2803+*
2804+* You should have received a copy of the GNU General Public License
2805+* along with this program. If not, see <http://www.gnu.org/licenses/>.
2806+*
2807+* Authored by: Ted Gould <ted@canonical.com>
2808+*/
2809+
2810+#ifndef UNITY_SYSTEMD_WRAPPER
2811+#define UNITY_SYSTEMD_WRAPPER
2812+
2813+#include <memory>
2814+
2815+namespace unity
2816+{
2817+
2818+class SystemdWrapper
2819+{
2820+public:
2821+ typedef std::shared_ptr<SystemdWrapper> Ptr;
2822+
2823+ SystemdWrapper();
2824+ ~SystemdWrapper();
2825+
2826+ void Start(std::string const& name);
2827+ void Stop(std::string const& name);
2828+ bool IsConnected();
2829+
2830+protected:
2831+ struct TestMode {};
2832+ SystemdWrapper(TestMode const&);
2833+
2834+private:
2835+ // Noncopyable
2836+ SystemdWrapper(SystemdWrapper const&) = delete;
2837+ SystemdWrapper& operator=(SystemdWrapper const&) = delete;
2838+
2839+ class Impl;
2840+ std::unique_ptr<Impl> pimpl_;
2841+};
2842+
2843+}
2844+
2845+#endif
2846
2847=== modified file 'unity-shared/WindowManager.h'
2848--- unity-shared/WindowManager.h 2016-03-18 18:58:26 +0000
2849+++ unity-shared/WindowManager.h 2016-08-30 14:38:39 +0000
2850@@ -170,6 +170,7 @@
2851 virtual bool IsOnscreenKeyboard(Window window_id) const = 0;
2852
2853 virtual std::string GetStringProperty(Window, Atom) const = 0;
2854+ virtual void SetCardinalProperty(Window, Atom, std::vector<long> const&) = 0;
2855 virtual std::vector<long> GetCardinalProperty(Window, Atom) const = 0;
2856
2857 virtual Cursor GetCachedCursor(unsigned int cursor_name) const = 0;
2858
2859=== modified file 'unity-shared/XWindowManager.cpp'
2860--- unity-shared/XWindowManager.cpp 2015-01-21 15:28:59 +0000
2861+++ unity-shared/XWindowManager.cpp 2016-08-30 14:38:39 +0000
2862@@ -123,6 +123,12 @@
2863 return std::string(val, n_items);
2864 }
2865
2866+void XWindowManager::SetCardinalProperty(Window window_id, Atom atom, std::vector<long> const& values)
2867+{
2868+ XChangeProperty(screen->dpy(), window_id, atom, XA_CARDINAL, 32, PropModeReplace,
2869+ (unsigned char *) values.data(), values.size());
2870+}
2871+
2872 std::vector<long> XWindowManager::GetCardinalProperty(Window window_id, Atom atom) const
2873 {
2874 Atom type;
2875
2876=== modified file 'unity-shared/XWindowManager.h'
2877--- unity-shared/XWindowManager.h 2015-01-21 15:28:59 +0000
2878+++ unity-shared/XWindowManager.h 2016-08-30 14:38:39 +0000
2879@@ -36,6 +36,7 @@
2880 std::string GetWindowName(Window window_id) const;
2881 bool IsOnscreenKeyboard(Window window_id) const;
2882 std::string GetStringProperty(Window window_id, Atom atom) const;
2883+ void SetCardinalProperty(Window, Atom, std::vector<long> const&);
2884 std::vector<long> GetCardinalProperty(Window, Atom) const;
2885 };
2886
2887
2888=== modified file 'unity7.conf.in'
2889--- unity7.conf.in 2016-07-21 13:01:59 +0000
2890+++ unity7.conf.in 2016-08-30 14:38:39 +0000
2891@@ -4,27 +4,7 @@
2892 start on xsession SESSION=ubuntu and started unity-settings-daemon
2893 stop on desktop-end
2894
2895-pre-start script
2896- # If gnome-session is going to start compiz,
2897- # we don't want to be the ones doing it.
2898-
2899- if grep -q compiz /usr/share/gnome-session/sessions/ubuntu.session ; then
2900- echo "GNOME Session is starting Compiz"
2901- stop ; exit 0
2902- fi
2903-
2904- compiz_profile="ubuntu"
2905-
2906- if ! /usr/lib/nux/unity_support_test -p; then
2907- compiz_profile="ubuntu-lowgfx"
2908- fi
2909-
2910- echo "Using compiz profile '$compiz_profile'"
2911- initctl set-env -g COMPIZ_CONFIG_PROFILE="$compiz_profile"
2912- export COMPIZ_CONFIG_PROFILE="$compiz_profile"
2913-
2914- ${CMAKE_INSTALL_FULL_LIBDIR}/unity/unity-active-plugins-safety-check
2915-end script
2916+pre-start exec @CMAKE_INSTALL_LIBDIR@/unity/unity-compiz-profile-select
2917
2918 respawn
2919 exec compiz
2920
2921=== added file 'unity7.override'
2922--- unity7.override 1970-01-01 00:00:00 +0000
2923+++ unity7.override 2016-08-30 14:38:39 +0000
2924@@ -0,0 +1,1 @@
2925+manual
2926
2927=== added file 'unity7.service.in'
2928--- unity7.service.in 1970-01-01 00:00:00 +0000
2929+++ unity7.service.in 2016-08-30 14:38:39 +0000
2930@@ -0,0 +1,11 @@
2931+[Unit]
2932+Description=Unity Shell v7
2933+Requires=unity-settings-daemon.service unity-panel-service.service bamfdaemon.service
2934+Wants=unity-gtk-module.service
2935+After=unity-settings-daemon.service
2936+PartOf=graphical-session.target
2937+
2938+[Service]
2939+ExecStart=/usr/bin/compiz
2940+ExecStart.Pre=@CMAKE_INSTALL_LIBDIR@/unity/unity-compiz-profile-select
2941+Restart=on-failure