Merge lp:~3v1n0/unity/input-monitor-menus-scrubbing-triangolation into lp:unity
- input-monitor-menus-scrubbing-triangolation
- Merge into trunk
Proposed by
Marco Trevisan (Treviño)
Status: | Merged |
---|---|
Approved by: | Andrea Azzarone |
Approved revision: | no longer in the source branch. |
Merged at revision: | 4187 |
Proposed branch: | lp:~3v1n0/unity/input-monitor-menus-scrubbing-triangolation |
Merge into: | lp:unity |
Prerequisite: | lp:~3v1n0/unity/input-monitor-lockscreen-panel |
Diff against target: |
1307 lines (+360/-246) 26 files modified
decorations/DecoratedWindow.cpp (+2/-9) decorations/DecorationsMenuLayout.cpp (+14/-10) decorations/DecorationsMenuLayout.h (+2/-1) decorations/DecorationsPriv.h (+0/-1) lockscreen/KylinLockScreenShield.cpp (+1/-1) lockscreen/LockScreenBaseShield.cpp (+0/-2) lockscreen/LockScreenBaseShield.h (+3/-4) lockscreen/LockScreenController.cpp (+3/-3) lockscreen/LockScreenController.h (+1/-2) lockscreen/LockScreenPanel.cpp (+19/-36) lockscreen/LockScreenPanel.h (+4/-5) 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 (+2/-105) panel/PanelView.h (+2/-9) tests/test_lockscreen_controller.cpp (+2/-2) unity-shared/InputMonitor.cpp (+39/-5) unity-shared/InputMonitor.h (+3/-27) unity-shared/MenuManager.cpp (+162/-1) unity-shared/MenuManager.h (+4/-0) unity-shared/SigcSlotHash.h (+70/-0) |
To merge this branch: | bzr merge lp:~3v1n0/unity/input-monitor-menus-scrubbing-triangolation |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Andrea Azzarone (community) | Approve | ||
Review via email: mp+304353@code.launchpad.net |
This proposal supersedes a proposal from 2016-08-30.
Commit message
MenuManager: add support for mouse trackers with triangle algorithm support
It allows to register pointer trackers with menu entries selection by using the triangle
technique which prevents menus items from being opened on quick menu scrubbing
Then use use menu::Manager pointer tracker for entries activation in PanelView, LockScreenPanel and DecorationsMenu
Description of the change
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 'decorations/DecoratedWindow.cpp' |
2 | --- decorations/DecoratedWindow.cpp 2016-08-06 16:24:45 +0000 |
3 | +++ decorations/DecoratedWindow.cpp 2016-09-01 22:11:45 +0000 |
4 | @@ -37,7 +37,6 @@ |
5 | { |
6 | namespace |
7 | { |
8 | -const std::string MENUS_PANEL_NAME = "WindowLIM"; |
9 | const int SHADOW_BLUR_MARGIN_FACTOR = 2; |
10 | } |
11 | |
12 | @@ -55,7 +54,6 @@ |
13 | , deco_elements_(cu::DecorationElement::NONE) |
14 | , last_mwm_decor_(win_->mwmDecor()) |
15 | , last_actions_(win_->actions()) |
16 | - , panel_id_(MENUS_PANEL_NAME + std::to_string(win_->id())) |
17 | , cv_(Settings::Instance().em()) |
18 | { |
19 | active.changed.connect([this] (bool active) { |
20 | @@ -932,18 +930,13 @@ |
21 | sliding_layout->mouse_owner = grab_edge_->mouse_owner(); |
22 | } |
23 | |
24 | -inline std::string const& Window::Impl::GetMenusPanelID() const |
25 | -{ |
26 | - return panel_id_; |
27 | -} |
28 | - |
29 | void Window::Impl::UnsetAppMenu() |
30 | { |
31 | if (!menus_) |
32 | return; |
33 | |
34 | auto const& indicators = manager_->impl_->menu_manager_->Indicators(); |
35 | - indicators->SyncGeometries(GetMenusPanelID(), indicator::EntryLocationMap()); |
36 | + indicators->SyncGeometries(menus_->MenubarId(), indicator::EntryLocationMap()); |
37 | sliding_layout_->SetInputItem(nullptr); |
38 | grab_mouse_changed_->disconnect(); |
39 | } |
40 | @@ -956,7 +949,7 @@ |
41 | auto const& indicators = manager_->impl_->menu_manager_->Indicators(); |
42 | indicator::EntryLocationMap map; |
43 | menus_->ChildrenGeometries(map); |
44 | - indicators->SyncGeometries(GetMenusPanelID(), map); |
45 | + indicators->SyncGeometries(menus_->MenubarId(), map); |
46 | } |
47 | |
48 | bool Window::Impl::ActivateMenu(std::string const& entry_id) |
49 | |
50 | === modified file 'decorations/DecorationsMenuLayout.cpp' |
51 | --- decorations/DecorationsMenuLayout.cpp 2016-09-01 22:11:44 +0000 |
52 | +++ decorations/DecorationsMenuLayout.cpp 2016-09-01 22:11:45 +0000 |
53 | @@ -20,12 +20,15 @@ |
54 | #include "DecorationsMenuLayout.h" |
55 | #include "DecorationsMenuEntry.h" |
56 | #include "DecorationsMenuDropdown.h" |
57 | -#include "InputMonitor.h" |
58 | |
59 | namespace unity |
60 | { |
61 | namespace decoration |
62 | { |
63 | +namespace |
64 | +{ |
65 | +const std::string MENUS_PANEL_NAME = "WindowLIM"; |
66 | +} |
67 | |
68 | using namespace indicator; |
69 | |
70 | @@ -35,6 +38,7 @@ |
71 | , menu_manager_(menu) |
72 | , win_(win) |
73 | , dropdown_(std::make_shared<MenuDropdown>(menu_manager_->Indicators(), win)) |
74 | + , menubar_id_(MENUS_PANEL_NAME + std::to_string(win_->id())) |
75 | { |
76 | visible = false; |
77 | } |
78 | @@ -91,6 +95,11 @@ |
79 | Relayout(); |
80 | } |
81 | |
82 | +std::string const& MenuLayout::MenubarId() const |
83 | +{ |
84 | + return menubar_id_; |
85 | +} |
86 | + |
87 | bool MenuLayout::ActivateMenu(std::string const& entry_id) |
88 | { |
89 | MenuEntry::Ptr target; |
90 | @@ -169,21 +178,16 @@ |
91 | |
92 | if (active && items_.size() > 1) |
93 | { |
94 | - auto const& event_cb = sigc::mem_fun(this, &MenuLayout::OnEntryInputEvent); |
95 | - input::Monitor::Get().RegisterClient(input::Events::POINTER, event_cb); |
96 | + menu_manager_->RegisterTracker(menubar_id_, (sigc::track_obj([this] (int x, int y, double speed) { |
97 | + ActivateMenu(CompPoint(x, y)); |
98 | + }, *this))); |
99 | } |
100 | else if (!active) |
101 | { |
102 | - input::Monitor::Get().UnregisterClient(sigc::mem_fun(this, &MenuLayout::OnEntryInputEvent)); |
103 | + menu_manager_->UnregisterTracker(menubar_id_); |
104 | } |
105 | } |
106 | |
107 | -void MenuLayout::OnEntryInputEvent(XEvent const& e) |
108 | -{ |
109 | - if (e.type == MotionNotify) |
110 | - ActivateMenu(CompPoint(e.xmotion.x_root, e.xmotion.y_root)); |
111 | -} |
112 | - |
113 | void MenuLayout::ChildrenGeometries(EntryLocationMap& map) const |
114 | { |
115 | for (auto const& item : items_) |
116 | |
117 | === modified file 'decorations/DecorationsMenuLayout.h' |
118 | --- decorations/DecorationsMenuLayout.h 2016-09-01 22:11:44 +0000 |
119 | +++ decorations/DecorationsMenuLayout.h 2016-09-01 22:11:45 +0000 |
120 | @@ -44,6 +44,7 @@ |
121 | bool ActivateMenu(std::string const& entry_id); |
122 | bool ActivateMenu(CompPoint const&); |
123 | void ChildrenGeometries(indicator::EntryLocationMap&) const; |
124 | + std::string const& MenubarId() const; |
125 | |
126 | protected: |
127 | void DoRelayout() override; |
128 | @@ -53,12 +54,12 @@ |
129 | void OnEntryMouseOwnershipChanged(bool); |
130 | void OnEntryActiveChanged(bool); |
131 | void OnEntryShowNowChanged(bool); |
132 | - void OnEntryInputEvent(XEvent const&); |
133 | |
134 | menu::Manager::Ptr menu_manager_; |
135 | CompWindow* win_; |
136 | glib::Source::UniquePtr show_now_timeout_; |
137 | std::shared_ptr<MenuDropdown> dropdown_; |
138 | + std::string menubar_id_; |
139 | }; |
140 | |
141 | } // decoration namespace |
142 | |
143 | === modified file 'decorations/DecorationsPriv.h' |
144 | --- decorations/DecorationsPriv.h 2016-08-06 16:24:45 +0000 |
145 | +++ decorations/DecorationsPriv.h 2016-09-01 22:11:45 +0000 |
146 | @@ -162,7 +162,6 @@ |
147 | connection::Wrapper dpi_changed_; |
148 | connection::Wrapper grab_mouse_changed_; |
149 | std::string last_title_; |
150 | - std::string panel_id_; |
151 | std::vector<cu::SimpleTextureQuad> bg_textures_; |
152 | cu::PixmapTexture::Ptr shaped_shadow_pixmap_; |
153 | std::shared_ptr<ForceQuitDialog> force_quit_; |
154 | |
155 | === modified file 'lockscreen/KylinLockScreenShield.cpp' |
156 | --- lockscreen/KylinLockScreenShield.cpp 2015-12-07 03:09:28 +0000 |
157 | +++ lockscreen/KylinLockScreenShield.cpp 2016-09-01 22:11:45 +0000 |
158 | @@ -37,7 +37,7 @@ |
159 | Accelerators::Ptr const& accelerators, |
160 | nux::ObjectPtr<AbstractUserPromptView> const& prompt_view, |
161 | int monitor_num, bool is_primary) |
162 | - : BaseShield(session_manager, nullptr, accelerators, prompt_view, monitor_num, is_primary) |
163 | + : BaseShield(session_manager, accelerators, prompt_view, monitor_num, is_primary) |
164 | { |
165 | is_primary ? ShowPrimaryView() : ShowSecondaryView(); |
166 | EnableInputWindow(true); |
167 | |
168 | === modified file 'lockscreen/LockScreenBaseShield.cpp' |
169 | --- lockscreen/LockScreenBaseShield.cpp 2015-12-03 14:13:10 +0000 |
170 | +++ lockscreen/LockScreenBaseShield.cpp 2016-09-01 22:11:45 +0000 |
171 | @@ -38,7 +38,6 @@ |
172 | } |
173 | |
174 | BaseShield::BaseShield(session::Manager::Ptr const& session, |
175 | - indicator::Indicators::Ptr const& indicators, |
176 | Accelerators::Ptr const& accelerators, |
177 | nux::ObjectPtr<AbstractUserPromptView> const& prompt_view, |
178 | int monitor_num, bool is_primary) |
179 | @@ -47,7 +46,6 @@ |
180 | , monitor(monitor_num) |
181 | , scale(1.0) |
182 | , session_manager_(session) |
183 | - , indicators_(indicators) |
184 | , accelerators_(accelerators) |
185 | , prompt_view_(prompt_view) |
186 | , bg_settings_(std::make_shared<BackgroundSettings>()) |
187 | |
188 | === modified file 'lockscreen/LockScreenBaseShield.h' |
189 | --- lockscreen/LockScreenBaseShield.h 2016-03-31 09:51:33 +0000 |
190 | +++ lockscreen/LockScreenBaseShield.h 2016-09-01 22:11:45 +0000 |
191 | @@ -21,8 +21,8 @@ |
192 | #define UNITY_LOCKSCREEN_BASE_SHIELD_H |
193 | |
194 | #include <NuxCore/Property.h> |
195 | +#include "UnityCore/ConnectionManager.h" |
196 | #include "UnityCore/SessionManager.h" |
197 | -#include "UnityCore/Indicators.h" |
198 | #include "UnityCore/GLibSource.h" |
199 | #include "unity-shared/MockableBaseWindow.h" |
200 | |
201 | @@ -39,8 +39,8 @@ |
202 | class BaseShield : public MockableBaseWindow |
203 | { |
204 | public: |
205 | - BaseShield(session::Manager::Ptr const&, indicator::Indicators::Ptr const&, |
206 | - Accelerators::Ptr const&, nux::ObjectPtr<AbstractUserPromptView> const&, |
207 | + BaseShield(session::Manager::Ptr const&, Accelerators::Ptr const&, |
208 | + nux::ObjectPtr<AbstractUserPromptView> const&, |
209 | int monitor_num, bool is_primary); |
210 | |
211 | nux::Property<bool> primary; |
212 | @@ -69,7 +69,6 @@ |
213 | void UpdateScale(); |
214 | |
215 | session::Manager::Ptr session_manager_; |
216 | - indicator::Indicators::Ptr indicators_; |
217 | Accelerators::Ptr accelerators_; |
218 | nux::ObjectPtr<AbstractUserPromptView> prompt_view_; |
219 | std::shared_ptr<BackgroundSettings> bg_settings_; |
220 | |
221 | === modified file 'lockscreen/LockScreenController.cpp' |
222 | --- lockscreen/LockScreenController.cpp 2016-07-04 12:45:06 +0000 |
223 | +++ lockscreen/LockScreenController.cpp 2016-09-01 22:11:45 +0000 |
224 | @@ -130,7 +130,7 @@ |
225 | |
226 | upstart_wrapper_->Emit("desktop-unlock"); |
227 | accelerator_controller_.reset(); |
228 | - indicators_.reset(); |
229 | + menu_manager_.reset(); |
230 | } |
231 | else if (!prompt_activation_) |
232 | { |
233 | @@ -252,7 +252,7 @@ |
234 | |
235 | if (i >= shields_size) |
236 | { |
237 | - shield = shield_factory_->CreateShield(session_manager_, indicators_, accelerator_controller_->GetAccelerators(), prompt_view, i, i == primary); |
238 | + shield = shield_factory_->CreateShield(session_manager_, menu_manager_, accelerator_controller_->GetAccelerators(), prompt_view, i, i == primary); |
239 | is_new = true; |
240 | } |
241 | |
242 | @@ -462,7 +462,7 @@ |
243 | |
244 | void Controller::LockScreen() |
245 | { |
246 | - indicators_ = std::make_shared<indicator::LockScreenDBusIndicators>(); |
247 | + menu_manager_ = std::make_shared<menu::Manager>(std::make_shared<indicator::LockScreenDBusIndicators>(), key_grabber_); |
248 | upstart_wrapper_->Emit("desktop-lock"); |
249 | |
250 | accelerator_controller_ = std::make_shared<AcceleratorController>(key_grabber_); |
251 | |
252 | === modified file 'lockscreen/LockScreenController.h' |
253 | --- lockscreen/LockScreenController.h 2016-06-21 01:28:26 +0000 |
254 | +++ lockscreen/LockScreenController.h 2016-09-01 22:11:45 +0000 |
255 | @@ -30,7 +30,6 @@ |
256 | #include "SuspendInhibitorManager.h" |
257 | #include "ScreenSaverDBusManager.h" |
258 | #include "unity-shared/BackgroundEffectHelper.h" |
259 | -#include "unity-shared/KeyGrabber.h" |
260 | #include "unity-shared/UpstartWrapper.h" |
261 | |
262 | namespace unity |
263 | @@ -85,8 +84,8 @@ |
264 | |
265 | DBusManager::Ptr dbus_manager_; |
266 | session::Manager::Ptr session_manager_; |
267 | + menu::Manager::Ptr menu_manager_; |
268 | key::Grabber::Ptr key_grabber_; |
269 | - indicator::Indicators::Ptr indicators_; |
270 | AcceleratorController::Ptr accelerator_controller_; |
271 | UpstartWrapper::Ptr upstart_wrapper_; |
272 | ShieldFactoryInterface::Ptr shield_factory_; |
273 | |
274 | === modified file 'lockscreen/LockScreenPanel.cpp' |
275 | --- lockscreen/LockScreenPanel.cpp 2016-09-01 22:11:44 +0000 |
276 | +++ lockscreen/LockScreenPanel.cpp 2016-09-01 22:11:45 +0000 |
277 | @@ -44,11 +44,11 @@ |
278 | using namespace indicator; |
279 | using namespace panel; |
280 | |
281 | -Panel::Panel(int monitor_, Indicators::Ptr const& indicators, session::Manager::Ptr const& session_manager) |
282 | +Panel::Panel(int monitor_, menu::Manager::Ptr const& menu_manager, session::Manager::Ptr const& session_manager) |
283 | : nux::View(NUX_TRACKER_LOCATION) |
284 | , active(false) |
285 | , monitor(monitor_) |
286 | - , indicators_(indicators) |
287 | + , menu_manager_(menu_manager) |
288 | , needs_geo_sync_(true) |
289 | { |
290 | double scale = unity::Settings::Instance().em(monitor)->DPIScale(); |
291 | @@ -72,14 +72,19 @@ |
292 | indicators_view_->on_indicator_updated.connect(sigc::mem_fun(this, &Panel::OnIndicatorViewUpdated)); |
293 | layout->AddView(indicators_view_, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL); |
294 | |
295 | - for (auto const& indicator : indicators_->GetIndicators()) |
296 | + auto indicators = menu_manager_->Indicators(); |
297 | + menu_manager_->RegisterTracker(GetPanelName(), (sigc::track_obj([this] (int x, int y, double speed) { |
298 | + indicators_view_->ActivateEntryAt(x, y); |
299 | + }, *this))); |
300 | + |
301 | + for (auto const& indicator : indicators->GetIndicators()) |
302 | AddIndicator(indicator); |
303 | |
304 | - indicators_->on_object_added.connect(sigc::mem_fun(this, &Panel::AddIndicator)); |
305 | - indicators_->on_object_removed.connect(sigc::mem_fun(this, &Panel::RemoveIndicator)); |
306 | - indicators_->on_entry_show_menu.connect(sigc::mem_fun(this, &Panel::OnEntryShowMenu)); |
307 | - indicators_->on_entry_activated.connect(sigc::mem_fun(this, &Panel::OnEntryActivated)); |
308 | - indicators_->on_entry_activate_request.connect(sigc::mem_fun(this, &Panel::OnEntryActivateRequest)); |
309 | + indicators->on_object_added.connect(sigc::mem_fun(this, &Panel::AddIndicator)); |
310 | + indicators->on_object_removed.connect(sigc::mem_fun(this, &Panel::RemoveIndicator)); |
311 | + indicators->on_entry_show_menu.connect(sigc::mem_fun(this, &Panel::OnEntryShowMenu)); |
312 | + indicators->on_entry_activated.connect(sigc::mem_fun(this, &Panel::OnEntryActivated)); |
313 | + indicators->on_entry_activate_request.connect(sigc::mem_fun(this, &Panel::OnEntryActivateRequest)); |
314 | |
315 | monitor.changed.connect([this, hostname] (int monitor) { |
316 | double scale = unity::Settings::Instance().em(monitor)->DPIScale(); |
317 | @@ -159,12 +164,7 @@ |
318 | if (!GetInputEventSensitivity()) |
319 | return; |
320 | |
321 | - if (!active) |
322 | - { |
323 | - // This is ugly... But Nux fault! |
324 | - WindowManager::Default().UnGrabMousePointer(CurrentTime, button, x, y); |
325 | - active = true; |
326 | - } |
327 | + active = true; |
328 | } |
329 | |
330 | void Panel::OnEntryActivateRequest(std::string const& entry_id) |
331 | @@ -178,33 +178,16 @@ |
332 | if (!GetInputEventSensitivity() || (!panel.empty() && panel != GetPanelName())) |
333 | return; |
334 | |
335 | - bool active = !entry_id.empty(); |
336 | + bool valid_entry = !entry_id.empty(); |
337 | |
338 | - if (active && !WindowManager::Default().IsScreenGrabbed()) |
339 | + if (valid_entry && !WindowManager::Default().IsScreenGrabbed()) |
340 | { |
341 | // The menu didn't grab the keyboard, let's take it back. |
342 | nux::GetWindowCompositor().GrabKeyboardAdd(static_cast<nux::BaseWindow*>(GetTopLevelViewWindow())); |
343 | } |
344 | |
345 | - auto& im = input::Monitor::Get(); |
346 | - auto const& event_cb = sigc::mem_fun(this, &Panel::OnEntryEvent); |
347 | - |
348 | - if (active) |
349 | - { |
350 | - if (im.RegisterClient(input::Events::POINTER, event_cb)) |
351 | - indicators_view_->ActivateEntry(entry_id); |
352 | - } |
353 | - else |
354 | - { |
355 | - im.UnregisterClient(event_cb); |
356 | - this->active = active; |
357 | - } |
358 | -} |
359 | - |
360 | -void Panel::OnEntryEvent(XEvent const& e) |
361 | -{ |
362 | - if (e.type == MotionNotify && GetAbsoluteGeometry().IsPointInside(e.xmotion.x, e.xmotion.y)) |
363 | - indicators_view_->ActivateEntryAt(e.xmotion.x, e.xmotion.y); |
364 | + if (!valid_entry) |
365 | + active = valid_entry; |
366 | } |
367 | |
368 | void Panel::Draw(nux::GraphicsEngine& graphics_engine, bool force_draw) |
369 | @@ -228,7 +211,7 @@ |
370 | { |
371 | EntryLocationMap locations; |
372 | indicators_view_->GetGeometryForSync(locations); |
373 | - indicators_->SyncGeometries(GetPanelName(), locations); |
374 | + menu_manager_->Indicators()->SyncGeometries(GetPanelName(), locations); |
375 | needs_geo_sync_ = false; |
376 | } |
377 | } |
378 | |
379 | === modified file 'lockscreen/LockScreenPanel.h' |
380 | --- lockscreen/LockScreenPanel.h 2016-09-01 22:11:44 +0000 |
381 | +++ lockscreen/LockScreenPanel.h 2016-09-01 22:11:45 +0000 |
382 | @@ -22,9 +22,9 @@ |
383 | |
384 | #include <Nux/Nux.h> |
385 | #include <Nux/View.h> |
386 | -#include "UnityCore/Indicators.h" |
387 | #include "UnityCore/GLibSource.h" |
388 | #include "UnityCore/SessionManager.h" |
389 | +#include "unity-shared/MenuManager.h" |
390 | |
391 | namespace unity |
392 | { |
393 | @@ -39,7 +39,7 @@ |
394 | class Panel : public nux::View |
395 | { |
396 | public: |
397 | - Panel(int monitor, indicator::Indicators::Ptr const&, session::Manager::Ptr const&); |
398 | + Panel(int monitor, menu::Manager::Ptr const&, session::Manager::Ptr const&); |
399 | |
400 | nux::Property<bool> active; |
401 | nux::Property<int> monitor; |
402 | @@ -55,15 +55,14 @@ |
403 | void AddIndicator(indicator::Indicator::Ptr const&); |
404 | void RemoveIndicator(indicator::Indicator::Ptr const&); |
405 | void OnIndicatorViewUpdated(); |
406 | - void OnEntryActivated(std::string const& panel, std::string const& entry_id, nux::Rect const& geo); |
407 | + void OnEntryActivated(std::string const& panel, std::string const& entry_id, nux::Rect const&); |
408 | void OnEntryShowMenu(std::string const& entry_id, unsigned xid, int x, int y, unsigned button); |
409 | void OnEntryActivateRequest(std::string const& entry_id); |
410 | - void OnEntryEvent(XEvent const&); |
411 | |
412 | void UpdateSize(); |
413 | std::string GetPanelName() const; |
414 | |
415 | - indicator::Indicators::Ptr indicators_; |
416 | + menu::Manager::Ptr menu_manager_; |
417 | panel::PanelIndicatorsView* indicators_view_; |
418 | bool needs_geo_sync_; |
419 | }; |
420 | |
421 | === modified file 'lockscreen/LockScreenShield.cpp' |
422 | --- lockscreen/LockScreenShield.cpp 2015-12-03 14:13:10 +0000 |
423 | +++ lockscreen/LockScreenShield.cpp 2016-09-01 22:11:45 +0000 |
424 | @@ -32,11 +32,12 @@ |
425 | { |
426 | |
427 | Shield::Shield(session::Manager::Ptr const& session_manager, |
428 | - indicator::Indicators::Ptr const& indicators, |
429 | + menu::Manager::Ptr const& menu_manager, |
430 | Accelerators::Ptr const& accelerators, |
431 | nux::ObjectPtr<AbstractUserPromptView> const& prompt_view, |
432 | int monitor_num, bool is_primary) |
433 | - : BaseShield(session_manager, indicators, accelerators, prompt_view, monitor_num, is_primary) |
434 | + : BaseShield(session_manager, accelerators, prompt_view, monitor_num, is_primary) |
435 | + , menu_manager_(menu_manager) |
436 | , panel_view_(nullptr) |
437 | { |
438 | is_primary ? ShowPrimaryView() : ShowSecondaryView(); |
439 | @@ -91,11 +92,11 @@ |
440 | |
441 | Panel* Shield::CreatePanel() |
442 | { |
443 | - if (!indicators_ || !session_manager_) |
444 | + if (!menu_manager_ || !session_manager_) |
445 | return nullptr; |
446 | |
447 | - panel_view_ = new Panel(monitor, indicators_, session_manager_); |
448 | - panel_active_conn_ = panel_view_->active.changed.connect([this] (bool active) { |
449 | + panel_view_ = new Panel(monitor, menu_manager_, session_manager_); |
450 | + panel_view_->active.changed.connect(sigc::track_obj([this] (bool active) { |
451 | if (primary()) |
452 | { |
453 | if (active) |
454 | @@ -109,7 +110,7 @@ |
455 | GrabScreen(false); |
456 | } |
457 | } |
458 | - }); |
459 | + }, *this)); |
460 | |
461 | return panel_view_; |
462 | } |
463 | |
464 | === modified file 'lockscreen/LockScreenShield.h' |
465 | --- lockscreen/LockScreenShield.h 2015-12-03 14:13:10 +0000 |
466 | +++ lockscreen/LockScreenShield.h 2016-09-01 22:11:45 +0000 |
467 | @@ -20,8 +20,9 @@ |
468 | #ifndef UNITY_LOCKSCREEN_SHIELD_H |
469 | #define UNITY_LOCKSCREEN_SHIELD_H |
470 | |
471 | -#include <UnityCore/ConnectionManager.h> |
472 | #include "LockScreenBaseShield.h" |
473 | +#include "unity-shared/MenuManager.h" |
474 | + |
475 | |
476 | namespace unity |
477 | { |
478 | @@ -35,7 +36,7 @@ |
479 | { |
480 | public: |
481 | Shield(session::Manager::Ptr const&, |
482 | - indicator::Indicators::Ptr const&, |
483 | + menu::Manager::Ptr const&, |
484 | Accelerators::Ptr const&, |
485 | nux::ObjectPtr<AbstractUserPromptView> const&, |
486 | int monitor, bool is_primary); |
487 | @@ -50,7 +51,7 @@ |
488 | void ShowPrimaryView() override; |
489 | Panel* CreatePanel(); |
490 | |
491 | - connection::Wrapper panel_active_conn_; |
492 | + menu::Manager::Ptr menu_manager_; |
493 | Panel* panel_view_; |
494 | }; |
495 | |
496 | |
497 | === modified file 'lockscreen/LockScreenShieldFactory.cpp' |
498 | --- lockscreen/LockScreenShieldFactory.cpp 2015-12-04 08:17:46 +0000 |
499 | +++ lockscreen/LockScreenShieldFactory.cpp 2016-09-01 22:11:45 +0000 |
500 | @@ -28,7 +28,7 @@ |
501 | { |
502 | |
503 | nux::ObjectPtr<BaseShield> ShieldFactory::CreateShield(session::Manager::Ptr const& session_manager, |
504 | - indicator::Indicators::Ptr const& indicators, |
505 | + menu::Manager::Ptr const& menu_manager, |
506 | Accelerators::Ptr const& accelerators, |
507 | nux::ObjectPtr<AbstractUserPromptView> const& prompt_view, |
508 | int monitor, bool is_primary) |
509 | @@ -38,7 +38,7 @@ |
510 | if (Settings::Instance().desktop_type() == DesktopType::UBUNTUKYLIN) |
511 | shield = new KylinShield(session_manager, accelerators, prompt_view, monitor, is_primary); |
512 | else |
513 | - shield = new Shield(session_manager, indicators, accelerators, prompt_view, monitor, is_primary); |
514 | + shield = new Shield(session_manager, menu_manager, accelerators, prompt_view, monitor, is_primary); |
515 | |
516 | return shield; |
517 | } |
518 | |
519 | === modified file 'lockscreen/LockScreenShieldFactory.h' |
520 | --- lockscreen/LockScreenShieldFactory.h 2016-03-31 09:51:33 +0000 |
521 | +++ lockscreen/LockScreenShieldFactory.h 2016-09-01 22:11:45 +0000 |
522 | @@ -22,7 +22,7 @@ |
523 | |
524 | #include <NuxCore/NuxCore.h> |
525 | #include "UnityCore/SessionManager.h" |
526 | -#include "UnityCore/Indicators.h" |
527 | +#include "unity-shared/MenuManager.h" |
528 | #include "LockScreenAccelerators.h" |
529 | |
530 | namespace unity |
531 | @@ -41,7 +41,7 @@ |
532 | virtual ~ShieldFactoryInterface() = default; |
533 | |
534 | virtual nux::ObjectPtr<BaseShield> CreateShield(session::Manager::Ptr const&, |
535 | - indicator::Indicators::Ptr const&, |
536 | + menu::Manager::Ptr const&, |
537 | Accelerators::Ptr const&, |
538 | nux::ObjectPtr<AbstractUserPromptView> const&, |
539 | int monitor, bool is_primary) = 0; |
540 | @@ -50,7 +50,7 @@ |
541 | struct ShieldFactory : ShieldFactoryInterface |
542 | { |
543 | nux::ObjectPtr<BaseShield> CreateShield(session::Manager::Ptr const&, |
544 | - indicator::Indicators::Ptr const&, |
545 | + menu::Manager::Ptr const&, |
546 | Accelerators::Ptr const&, |
547 | nux::ObjectPtr<AbstractUserPromptView> const&, |
548 | int monitor, bool is_primary) override; |
549 | |
550 | === modified file 'panel/PanelIndicatorEntryView.cpp' |
551 | --- panel/PanelIndicatorEntryView.cpp 2016-02-17 13:14:37 +0000 |
552 | +++ panel/PanelIndicatorEntryView.cpp 2016-09-01 22:11:45 +0000 |
553 | @@ -33,6 +33,8 @@ |
554 | #include "unity-shared/RawPixel.h" |
555 | #include "unity-shared/WindowManager.h" |
556 | #include "unity-shared/ThemeSettings.h" |
557 | +#include "unity-shared/UBusWrapper.h" |
558 | +#include "unity-shared/UBusMessages.h" |
559 | #include "unity-shared/UnitySettings.h" |
560 | |
561 | namespace unity |
562 | @@ -117,6 +119,9 @@ |
563 | } |
564 | else |
565 | { |
566 | + if (overlay_showing_) |
567 | + UBusManager::SendMessage(UBUS_OVERLAY_CLOSE_REQUEST); |
568 | + |
569 | WindowManager& wm = WindowManager::Default(); |
570 | |
571 | if (wm.IsExpoActive()) |
572 | @@ -140,6 +145,11 @@ |
573 | wm.TerminateScale(); |
574 | } |
575 | |
576 | + // This is ugly... But Nux fault! |
577 | + auto const& abs_geo = GetAbsoluteGeometry(); |
578 | + guint64 timestamp = nux::GetGraphicsDisplay()->GetCurrentEvent().x11_timestamp; |
579 | + WindowManager::Default().UnGrabMousePointer(timestamp, button, abs_geo.x, abs_geo.y); |
580 | + |
581 | Activate(button); |
582 | } |
583 | } |
584 | |
585 | === modified file 'panel/PanelMenuView.cpp' |
586 | --- panel/PanelMenuView.cpp 2015-12-16 15:12:05 +0000 |
587 | +++ panel/PanelMenuView.cpp 2016-09-01 22:11:45 +0000 |
588 | @@ -102,7 +102,6 @@ |
589 | , ignore_menu_visibility_(false) |
590 | , integrated_menus_(menu_manager_->integrated_menus()) |
591 | , always_show_menus_(menu_manager_->always_show_menus()) |
592 | - , ignore_leave_events_(false) |
593 | , desktop_name_(get_current_desktop()) |
594 | { |
595 | if (ApplicationWindowPtr const& win = ApplicationManager::Default().GetActiveWindow()) |
596 | @@ -1814,14 +1813,9 @@ |
597 | } |
598 | } |
599 | |
600 | -void PanelMenuView::IgnoreLeaveEvents(bool ignore) |
601 | -{ |
602 | - ignore_leave_events_ = ignore; |
603 | -} |
604 | - |
605 | void PanelMenuView::OnPanelViewMouseLeave(int x, int y, unsigned long mouse_button_state, unsigned long special_keys_state) |
606 | { |
607 | - if (always_show_menus_ || ignore_leave_events_) |
608 | + if (always_show_menus_) |
609 | return; |
610 | |
611 | if (is_inside_) |
612 | |
613 | === modified file 'panel/PanelMenuView.h' |
614 | --- panel/PanelMenuView.h 2015-11-05 14:54:13 +0000 |
615 | +++ panel/PanelMenuView.h 2016-09-01 22:11:45 +0000 |
616 | @@ -56,7 +56,6 @@ |
617 | bool HasKeyActivableMenus() const; |
618 | |
619 | void NotifyAllMenusClosed(); |
620 | - void IgnoreLeaveEvents(bool); |
621 | |
622 | virtual void AddIndicator(indicator::Indicator::Ptr const& indicator); |
623 | |
624 | @@ -192,7 +191,6 @@ |
625 | bool ignore_menu_visibility_; |
626 | bool integrated_menus_; |
627 | bool always_show_menus_; |
628 | - bool ignore_leave_events_; |
629 | |
630 | nux::Geometry monitor_geo_; |
631 | const std::string desktop_name_; |
632 | |
633 | === modified file 'panel/PanelView.cpp' |
634 | --- panel/PanelView.cpp 2016-09-01 22:11:44 +0000 |
635 | +++ panel/PanelView.cpp 2016-09-01 22:11:45 +0000 |
636 | @@ -23,7 +23,6 @@ |
637 | |
638 | #include <UnityCore/GLibWrapper.h> |
639 | |
640 | -#include "unity-shared/InputMonitor.h" |
641 | #include "unity-shared/PanelStyle.h" |
642 | #include "unity-shared/RawPixel.h" |
643 | #include "unity-shared/TextureCache.h" |
644 | @@ -54,7 +53,6 @@ |
645 | : View(NUX_FILE_LINE_PARAM) |
646 | , parent_(parent) |
647 | , remote_(menus->Indicators()) |
648 | - , last_pointer_time_(0) |
649 | , is_dirty_(true) |
650 | , opacity_maximized_toggle_(false) |
651 | , needs_geo_sync_(false) |
652 | @@ -116,10 +114,9 @@ |
653 | |
654 | remote_->on_object_added.connect(sigc::mem_fun(this, &PanelView::OnObjectAdded)); |
655 | remote_->on_object_removed.connect(sigc::mem_fun(this, &PanelView::OnObjectRemoved)); |
656 | - remote_->on_entry_activated.connect(sigc::mem_fun(this, &PanelView::OnEntryActivated)); |
657 | - remote_->on_entry_show_menu.connect(sigc::mem_fun(this, &PanelView::OnEntryShowMenu)); |
658 | menus->key_activate_entry.connect(sigc::mem_fun(this, &PanelView::ActivateEntry)); |
659 | menus->open_first.connect(sigc::mem_fun(this, &PanelView::ActivateFirstSensitive)); |
660 | + menus->RegisterTracker(GetPanelName(), sigc::mem_fun(this, &PanelView::OnMenuPointerMoved)); |
661 | |
662 | ubus_manager_.RegisterInterest(UBUS_OVERLAY_HIDDEN, sigc::mem_fun(this, &PanelView::OnOverlayHidden)); |
663 | ubus_manager_.RegisterInterest(UBUS_OVERLAY_SHOWN, sigc::mem_fun(this, &PanelView::OnOverlayShown)); |
664 | @@ -630,7 +627,7 @@ |
665 | QueueDraw(); |
666 | } |
667 | |
668 | -void PanelView::OnMenuPointerMoved(int x, int y) |
669 | +void PanelView::OnMenuPointerMoved(int x, int y, double speed) |
670 | { |
671 | nux::Geometry const& geo = GetAbsoluteGeometry(); |
672 | |
673 | @@ -651,106 +648,6 @@ |
674 | } |
675 | } |
676 | |
677 | -namespace |
678 | -{ |
679 | -bool PointInTriangle(nux::Point const& p, nux::Point const& t0, nux::Point const& t1, nux::Point const& t2) |
680 | -{ |
681 | - int s = t0.y * t2.x - t0.x * t2.y + (t2.y - t0.y) * p.x + (t0.x - t2.x) * p.y; |
682 | - int t = t0.x * t1.y - t0.y * t1.x + (t0.y - t1.y) * p.x + (t1.x - t0.x) * p.y; |
683 | - |
684 | - if ((s < 0) != (t < 0)) |
685 | - return false; |
686 | - |
687 | - int A = -t1.y * t2.x + t0.y * (t2.x - t1.x) + t0.x * (t1.y - t2.y) + t1.x * t2.y; |
688 | - if (A < 0) |
689 | - { |
690 | - s = -s; |
691 | - t = -t; |
692 | - A = -A; |
693 | - } |
694 | - |
695 | - return s > 0 && t > 0 && (s + t) < A; |
696 | -} |
697 | - |
698 | -double GetMouseVelocity(nux::Point const& p0, nux::Point const& p1, Time time_delta) |
699 | -{ |
700 | - int dx, dy; |
701 | - double speed; |
702 | - |
703 | - if (time_delta == 0) |
704 | - return 1; |
705 | - |
706 | - dx = p0.x - p1.x; |
707 | - dy = p0.y - p1.y; |
708 | - |
709 | - speed = sqrt(dx * dx + dy * dy) / time_delta; |
710 | - |
711 | - return speed; |
712 | -} |
713 | -} // anonymous namespace |
714 | - |
715 | -void PanelView::OnActiveEntryEvent(XEvent const& e) |
716 | -{ |
717 | - if (e.type != MotionNotify) |
718 | - return; |
719 | - |
720 | - double scale = Settings::Instance().em(monitor_)->DPIScale(); |
721 | - nux::Point mouse(e.xmotion.x_root, e.xmotion.y_root); |
722 | - double speed = GetMouseVelocity(mouse, tracked_pointer_pos_, e.xmotion.time - last_pointer_time_); |
723 | - |
724 | - tracked_pointer_pos_ = mouse; |
725 | - last_pointer_time_ = e.xmotion.time; |
726 | - |
727 | - if (speed > SCRUB_VELOCITY_THRESHOLD && |
728 | - PointInTriangle(mouse, {mouse.x, std::max(mouse.y - TRIANGLE_THRESHOLD.CP(scale), 0)}, |
729 | - menu_geo_.GetPosition(), {menu_geo_.x + menu_geo_.width, menu_geo_.y})) |
730 | - { |
731 | - return; |
732 | - } |
733 | - |
734 | - OnMenuPointerMoved(mouse.x, mouse.y); |
735 | -} |
736 | - |
737 | -void PanelView::OnEntryActivated(std::string const& panel, std::string const& entry_id, nux::Rect const& menu_geo) |
738 | -{ |
739 | - if (!panel.empty() && panel != GetPanelName()) |
740 | - return; |
741 | - |
742 | - bool active = !entry_id.empty(); |
743 | - auto const& activation_cb = sigc::mem_fun(this, &PanelView::OnActiveEntryEvent); |
744 | - menu_geo_ = menu_geo; |
745 | - |
746 | - if (active) |
747 | - { |
748 | - auto& im = input::Monitor::Get(); |
749 | - if (im.RegisterClient(input::Events::POINTER, activation_cb)) |
750 | - { |
751 | - last_pointer_time_ = 0; |
752 | - ActivateEntry(entry_id); |
753 | - } |
754 | - |
755 | - if (overlay_is_open_) |
756 | - ubus_manager_.SendMessage(UBUS_OVERLAY_CLOSE_REQUEST); |
757 | - } |
758 | - else |
759 | - { |
760 | - input::Monitor::Get().UnregisterClient(activation_cb); |
761 | - menu_view_->NotifyAllMenusClosed(); |
762 | - } |
763 | -} |
764 | - |
765 | -void PanelView::OnEntryShowMenu(std::string const& entry_id, unsigned xid, |
766 | - int x, int y, unsigned button) |
767 | -{ |
768 | - if (menu_geo_.IsNull()) |
769 | - { |
770 | - // This is ugly... But Nux fault! |
771 | - menu_view_->IgnoreLeaveEvents(true); |
772 | - WindowManager::Default().UnGrabMousePointer(CurrentTime, button, x, y); |
773 | - menu_view_->IgnoreLeaveEvents(false); |
774 | - } |
775 | -} |
776 | - |
777 | bool PanelView::ActivateFirstSensitive() |
778 | { |
779 | if (!IsActive()) |
780 | |
781 | === modified file 'panel/PanelView.h' |
782 | --- panel/PanelView.h 2016-09-01 22:11:44 +0000 |
783 | +++ panel/PanelView.h 2016-09-01 22:11:45 +0000 |
784 | @@ -87,8 +87,6 @@ |
785 | void OnObjectAdded(indicator::Indicator::Ptr const& proxy); |
786 | void OnObjectRemoved(indicator::Indicator::Ptr const& proxy); |
787 | void OnIndicatorViewUpdated(); |
788 | - void OnEntryActivated(std::string const& panel, std::string const& entry_id, nux::Rect const& geo); |
789 | - void OnEntryShowMenu(std::string const& entry_id, unsigned xid, int x, int y, unsigned button); |
790 | |
791 | private: |
792 | std::string GetPanelName() const; |
793 | @@ -98,7 +96,7 @@ |
794 | void OnSpreadInitiate(); |
795 | void OnSpreadTerminate(); |
796 | void OnLowGfxChanged(); |
797 | - void OnMenuPointerMoved(int x, int y); |
798 | + void OnMenuPointerMoved(int x, int y, double speed); |
799 | void OnActiveEntryEvent(XEvent const&); |
800 | void EnableOverlayMode(bool); |
801 | void LoadTextures(); |
802 | @@ -132,10 +130,6 @@ |
803 | BaseTexturePtr bg_refine_single_column_tex_; |
804 | std::unique_ptr<nux::AbstractPaintLayer> bg_refine_single_column_layer_; |
805 | |
806 | - std::string active_overlay_; |
807 | - nux::Point tracked_pointer_pos_; |
808 | - Time last_pointer_time_; |
809 | - |
810 | bool is_dirty_; |
811 | bool opacity_maximized_toggle_; |
812 | bool needs_geo_sync_; |
813 | @@ -143,8 +137,7 @@ |
814 | float opacity_; |
815 | int monitor_; |
816 | int stored_dash_width_; |
817 | - |
818 | - nux::Geometry menu_geo_; |
819 | + std::string active_overlay_; |
820 | |
821 | connection::Manager on_indicator_updated_connections_; |
822 | connection::Manager maximized_opacity_toggle_connections_; |
823 | |
824 | === modified file 'tests/test_lockscreen_controller.cpp' |
825 | --- tests/test_lockscreen_controller.cpp 2016-06-21 14:40:26 +0000 |
826 | +++ tests/test_lockscreen_controller.cpp 2016-09-01 22:11:45 +0000 |
827 | @@ -55,7 +55,7 @@ |
828 | struct MockShield : BaseShield |
829 | { |
830 | MockShield() |
831 | - : BaseShield(nullptr, nullptr, nullptr, nux::ObjectPtr<AbstractUserPromptView>(), 0, false) |
832 | + : BaseShield(nullptr, nullptr, nux::ObjectPtr<AbstractUserPromptView>(), 0, false) |
833 | {} |
834 | |
835 | MOCK_CONST_METHOD0(IsIndicatorOpen, bool()); |
836 | @@ -67,7 +67,7 @@ |
837 | struct ShieldFactoryMock : ShieldFactoryInterface |
838 | { |
839 | nux::ObjectPtr<BaseShield> CreateShield(session::Manager::Ptr const&, |
840 | - indicator::Indicators::Ptr const&, |
841 | + menu::Manager::Ptr const&, |
842 | Accelerators::Ptr const&, |
843 | nux::ObjectPtr<AbstractUserPromptView> const&, |
844 | int, bool) override |
845 | |
846 | === modified file 'unity-shared/InputMonitor.cpp' |
847 | --- unity-shared/InputMonitor.cpp 2016-09-01 22:11:44 +0000 |
848 | +++ unity-shared/InputMonitor.cpp 2016-09-01 22:11:45 +0000 |
849 | @@ -18,6 +18,7 @@ |
850 | */ |
851 | |
852 | #include "InputMonitor.h" |
853 | +#include "SigcSlotHash.h" |
854 | |
855 | #include <Nux/Nux.h> |
856 | #include <NuxCore/Logger.h> |
857 | @@ -46,6 +47,12 @@ |
858 | return static_cast<ut>(static_cast<ut>(l) & static_cast<ut>(r)); |
859 | } |
860 | |
861 | +Events& operator|=(Events& l, Events r) |
862 | +{ |
863 | + typedef std::underlying_type<Events>::type ut; |
864 | + return l = static_cast<Events>(static_cast<ut>(l) | static_cast<ut>(r)); |
865 | +} |
866 | + |
867 | template <typename EVENT> |
868 | void initialize_event_common(EVENT* ev, XIDeviceEvent* xiev) |
869 | { |
870 | @@ -118,6 +125,12 @@ |
871 | |
872 | struct Monitor::Impl |
873 | { |
874 | +#if __GNUC__ < 6 |
875 | + using EventCallbackSet = std::unordered_set<EventCallback>; |
876 | +#else |
877 | + using EventCallbackSet = std::unordered_set<EventCallback, std::hash<sigc::slot_base>>; |
878 | +#endif |
879 | + |
880 | Impl() |
881 | : xi_opcode_(0) |
882 | , event_filter_set_(false) |
883 | @@ -194,6 +207,22 @@ |
884 | return removed; |
885 | } |
886 | |
887 | + Events RegisteredEvents(EventCallback const& cb) const |
888 | + { |
889 | + Events events = Events::NONE; |
890 | + |
891 | + if (pointer_callbacks_.find(cb) != end(pointer_callbacks_)) |
892 | + events |= Events::POINTER; |
893 | + |
894 | + if (key_callbacks_.find(cb) != end(key_callbacks_)) |
895 | + events |= Events::KEYS; |
896 | + |
897 | + if (barrier_callbacks_.find(cb) != end(barrier_callbacks_)) |
898 | + events |= Events::BARRIER; |
899 | + |
900 | + return events; |
901 | + } |
902 | + |
903 | void UpdateEventMonitor() |
904 | { |
905 | auto* dpy = nux::GetGraphicsDisplay()->GetX11Display(); |
906 | @@ -276,7 +305,7 @@ |
907 | } |
908 | |
909 | template <typename EVENT_TYPE, typename NATIVE_TYPE = XIDeviceEvent> |
910 | - bool InvokeCallbacks(std::unordered_set<EventCallback>& callbacks, XEvent& xiev) |
911 | + bool InvokeCallbacks(EventCallbackSet& callbacks, XEvent& xiev) |
912 | { |
913 | XGenericEventCookie *cookie = &xiev.xcookie; |
914 | |
915 | @@ -332,10 +361,10 @@ |
916 | bool event_filter_set_; |
917 | bool invoking_callbacks_; |
918 | glib::Source::UniquePtr idle_removal_; |
919 | - std::unordered_set<EventCallback> pointer_callbacks_; |
920 | - std::unordered_set<EventCallback> key_callbacks_; |
921 | - std::unordered_set<EventCallback> barrier_callbacks_; |
922 | - std::unordered_set<EventCallback> removal_queue_; |
923 | + EventCallbackSet pointer_callbacks_; |
924 | + EventCallbackSet key_callbacks_; |
925 | + EventCallbackSet barrier_callbacks_; |
926 | + EventCallbackSet removal_queue_; |
927 | }; |
928 | |
929 | Monitor::Monitor() |
930 | @@ -376,5 +405,10 @@ |
931 | return impl_->UnregisterClient(cb); |
932 | } |
933 | |
934 | +Events Monitor::RegisteredEvents(EventCallback const& cb) const |
935 | +{ |
936 | + return impl_->RegisteredEvents(cb); |
937 | +} |
938 | + |
939 | } // input namespace |
940 | } // unity namespace |
941 | |
942 | === modified file 'unity-shared/InputMonitor.h' |
943 | --- unity-shared/InputMonitor.h 2016-09-01 22:11:44 +0000 |
944 | +++ unity-shared/InputMonitor.h 2016-09-01 22:11:45 +0000 |
945 | @@ -30,6 +30,7 @@ |
946 | { |
947 | enum class Events : unsigned |
948 | { |
949 | + NONE = 0, |
950 | POINTER = (1 << 0), |
951 | KEYS = (1 << 1), |
952 | BARRIER = (1 << 2), |
953 | @@ -50,6 +51,8 @@ |
954 | bool RegisterClient(Events, EventCallback const&); |
955 | bool UnregisterClient(EventCallback const&); |
956 | |
957 | + Events RegisteredEvents(EventCallback const&) const; |
958 | + |
959 | private: |
960 | Monitor(Monitor const&) = delete; |
961 | Monitor& operator=(Monitor const&) = delete; |
962 | @@ -61,31 +64,4 @@ |
963 | } // input namespace |
964 | } // unity namespace |
965 | |
966 | -namespace std |
967 | -{ |
968 | -template<> |
969 | -struct hash<unity::input::Monitor::EventCallback> |
970 | -{ |
971 | - size_t operator()(unity::input::Monitor::EventCallback const& cb) const |
972 | - { |
973 | - if (cb.rep_) |
974 | - return std::hash<size_t>()(reinterpret_cast<size_t>(cb.rep_->call_)); |
975 | - |
976 | - return std::hash<size_t>()(reinterpret_cast<size_t>(cb.rep_)); |
977 | - } |
978 | -}; |
979 | - |
980 | -template<> |
981 | -struct equal_to<unity::input::Monitor::EventCallback> |
982 | -{ |
983 | - bool operator()(unity::input::Monitor::EventCallback const& lhs, unity::input::Monitor::EventCallback const& rhs) const |
984 | - { |
985 | - if (!lhs.rep_ || !rhs.rep_) |
986 | - return (lhs.rep_ == rhs.rep_); |
987 | - |
988 | - return (lhs.rep_->call_ == rhs.rep_->call_); |
989 | - } |
990 | -}; |
991 | -} // std namespace |
992 | - |
993 | #endif // __UNITY_INPUT_MONITOR__ |
994 | |
995 | === modified file 'unity-shared/MenuManager.cpp' |
996 | --- unity-shared/MenuManager.cpp 2015-10-02 14:02:05 +0000 |
997 | +++ unity-shared/MenuManager.cpp 2016-09-01 22:11:45 +0000 |
998 | @@ -21,11 +21,17 @@ |
999 | #include <gtk/gtk.h> |
1000 | #include <NuxCore/Logger.h> |
1001 | #include <UnityCore/GLibSignal.h> |
1002 | +#include <UnityCore/GLibSource.h> |
1003 | #include <UnityCore/GLibWrapper.h> |
1004 | #include <UnityCore/DBusIndicators.h> |
1005 | #include <unordered_map> |
1006 | |
1007 | #include "MenuManager.h" |
1008 | +#include "InputMonitor.h" |
1009 | +#include "RawPixel.h" |
1010 | +#include "SigcSlotHash.h" |
1011 | +#include "UnitySettings.h" |
1012 | +#include "UScreen.h" |
1013 | #include "WindowManager.h" |
1014 | |
1015 | namespace unity |
1016 | @@ -40,6 +46,10 @@ |
1017 | const std::string LIM_KEY = "integrated-menus"; |
1018 | const std::string SHOW_MENUS_NOW_DELAY = "show-menus-now-delay"; |
1019 | const std::string ALWAYS_SHOW_MENUS_KEY = "always-show-menus"; |
1020 | + |
1021 | +const RawPixel TRIANGLE_THRESHOLD = 5_em; |
1022 | +const double SCRUB_VELOCITY_THRESHOLD = 0.05; |
1023 | +const unsigned MENU_OPEN_MOUSE_WAIT = 150; |
1024 | } |
1025 | |
1026 | using namespace indicator; |
1027 | @@ -51,6 +61,7 @@ |
1028 | , indicators_(indicators) |
1029 | , key_grabber_(grabber) |
1030 | , show_now_window_(0) |
1031 | + , last_pointer_time_(0) |
1032 | , settings_(g_settings_new(SETTINGS_NAME.c_str())) |
1033 | { |
1034 | for (auto const& indicator : indicators_->GetIndicators()) |
1035 | @@ -182,9 +193,15 @@ |
1036 | parent_->key_activate_entry.emit(entry_id); |
1037 | } |
1038 | |
1039 | - void EntryActivated(std::string const&, std::string const&, nux::Rect const& geo) |
1040 | + void EntryActivated(std::string const& menubar, std::string const&, nux::Rect const& geo) |
1041 | { |
1042 | parent_->menu_open = !geo.IsNull(); |
1043 | + |
1044 | + if (active_menubar_ != menubar) |
1045 | + { |
1046 | + active_menubar_ = menubar; |
1047 | + UpdateActiveTracker(); |
1048 | + } |
1049 | } |
1050 | |
1051 | void SetShowNowForWindow(Window xid, bool show) |
1052 | @@ -231,15 +248,148 @@ |
1053 | gtk_icon_theme_set_search_path(gtk_icon_theme_get_default(), gicon_paths.data(), gicon_paths.size()); |
1054 | } |
1055 | |
1056 | + bool PointInTriangle(nux::Point const& p, nux::Point const& t0, nux::Point const& t1, nux::Point const& t2) |
1057 | + { |
1058 | + int s = t0.y * t2.x - t0.x * t2.y + (t2.y - t0.y) * p.x + (t0.x - t2.x) * p.y; |
1059 | + int t = t0.x * t1.y - t0.y * t1.x + (t0.y - t1.y) * p.x + (t1.x - t0.x) * p.y; |
1060 | + |
1061 | + if ((s < 0) != (t < 0)) |
1062 | + return false; |
1063 | + |
1064 | + int A = -t1.y * t2.x + t0.y * (t2.x - t1.x) + t0.x * (t1.y - t2.y) + t1.x * t2.y; |
1065 | + if (A < 0) |
1066 | + { |
1067 | + s = -s; |
1068 | + t = -t; |
1069 | + A = -A; |
1070 | + } |
1071 | + |
1072 | + return s > 0 && t > 0 && (s + t) < A; |
1073 | + } |
1074 | + |
1075 | + double GetMouseVelocity(nux::Point const& p0, nux::Point const& p1, Time time_delta) |
1076 | + { |
1077 | + int dx, dy; |
1078 | + double speed; |
1079 | + |
1080 | + if (time_delta == 0) |
1081 | + return 1; |
1082 | + |
1083 | + dx = p0.x - p1.x; |
1084 | + dy = p0.y - p1.y; |
1085 | + |
1086 | + speed = sqrt(dx * dx + dy * dy) / time_delta; |
1087 | + |
1088 | + return speed; |
1089 | + } |
1090 | + |
1091 | + void OnActiveEntryEvent(XEvent const& e) |
1092 | + { |
1093 | + if (e.type != MotionNotify) |
1094 | + return; |
1095 | + |
1096 | + auto const& active_entry = indicators_->GetActiveEntry(); |
1097 | + |
1098 | + if (!active_entry) |
1099 | + return; |
1100 | + |
1101 | + nux::Point mouse(e.xmotion.x_root, e.xmotion.y_root); |
1102 | + auto monitor = UScreen::GetDefault()->GetMonitorAtPosition(mouse.x, mouse.y); |
1103 | + double scale = Settings::Instance().em(monitor)->DPIScale(); |
1104 | + double speed = GetMouseVelocity(mouse, tracked_pointer_pos_, e.xmotion.time - last_pointer_time_); |
1105 | + auto menu_geo = active_entry->geometry(); |
1106 | + |
1107 | + tracked_pointer_pos_ = mouse; |
1108 | + last_pointer_time_ = e.xmotion.time; |
1109 | + |
1110 | + if (speed > SCRUB_VELOCITY_THRESHOLD && |
1111 | + PointInTriangle(mouse, {mouse.x, std::max(mouse.y - TRIANGLE_THRESHOLD.CP(scale), 0)}, |
1112 | + menu_geo.GetPosition(), {menu_geo.x + menu_geo.width, menu_geo.y})) |
1113 | + { |
1114 | + pointer_movement_timeout_ = std::make_shared<glib::Timeout>(MENU_OPEN_MOUSE_WAIT, [this, mouse, speed] { |
1115 | + if (active_tracker_) |
1116 | + active_tracker_(mouse.x, mouse.y, speed); |
1117 | + |
1118 | + return false; |
1119 | + }); |
1120 | + |
1121 | + return; |
1122 | + } |
1123 | + |
1124 | + if (active_tracker_) |
1125 | + { |
1126 | + pointer_movement_timeout_.reset(); |
1127 | + active_tracker_(mouse.x, mouse.y, speed); |
1128 | + } |
1129 | + } |
1130 | + |
1131 | + bool RegisterTracker(std::string const& menubar, PositionTracker const& cb) |
1132 | + { |
1133 | + auto it = position_trackers_.find(menubar); |
1134 | + |
1135 | + if (it != end(position_trackers_)) |
1136 | + return false; |
1137 | + |
1138 | + position_trackers_.insert({menubar, cb}); |
1139 | + |
1140 | + if (active_menubar_ == menubar) |
1141 | + UpdateActiveTracker(); |
1142 | + |
1143 | + return true; |
1144 | + } |
1145 | + |
1146 | + bool UnregisterTracker(std::string const& menubar, PositionTracker const& cb) |
1147 | + { |
1148 | + auto it = position_trackers_.find(menubar); |
1149 | + |
1150 | + if (it == end(position_trackers_)) |
1151 | + return false; |
1152 | + |
1153 | + if (!cb || (cb && it->second == cb)) |
1154 | + { |
1155 | + position_trackers_.erase(it); |
1156 | + UpdateActiveTracker(); |
1157 | + return true; |
1158 | + } |
1159 | + |
1160 | + return false; |
1161 | + } |
1162 | + |
1163 | + void UpdateActiveTracker() |
1164 | + { |
1165 | + auto it = position_trackers_.find(active_menubar_); |
1166 | + active_tracker_ = (it != end(position_trackers_)) ? it->second : PositionTracker(); |
1167 | + pointer_movement_timeout_.reset(); |
1168 | + |
1169 | + if (active_tracker_) |
1170 | + { |
1171 | + if (input::Monitor::Get().RegisterClient(input::Events::POINTER, sigc::mem_fun(this, &Impl::OnActiveEntryEvent))) |
1172 | + last_pointer_time_ = 0; |
1173 | + } |
1174 | + else |
1175 | + { |
1176 | + input::Monitor::Get().UnregisterClient(sigc::mem_fun(this, &Impl::OnActiveEntryEvent)); |
1177 | + |
1178 | + if (it != end(position_trackers_)) |
1179 | + position_trackers_.erase(it); |
1180 | + } |
1181 | + } |
1182 | + |
1183 | Manager* parent_; |
1184 | Indicators::Ptr indicators_; |
1185 | AppmenuIndicator::Ptr appmenu_; |
1186 | key::Grabber::Ptr key_grabber_; |
1187 | Window show_now_window_; |
1188 | + std::string active_menubar_; |
1189 | + PositionTracker active_tracker_; |
1190 | + nux::Point tracked_pointer_pos_; |
1191 | + Time last_pointer_time_; |
1192 | + glib::Source::Ptr pointer_movement_timeout_; |
1193 | connection::Manager appmenu_connections_; |
1194 | connection::Wrapper active_win_conn_; |
1195 | glib::Object<GSettings> settings_; |
1196 | glib::SignalManager signals_; |
1197 | + std::unordered_map<std::string, PositionTracker> position_trackers_; |
1198 | std::unordered_map<indicator::Entry::Ptr, uint32_t> entry_actions_; |
1199 | }; |
1200 | |
1201 | @@ -278,5 +428,16 @@ |
1202 | return impl_->key_grabber_; |
1203 | } |
1204 | |
1205 | +bool Manager::RegisterTracker(std::string const& menubar, PositionTracker const& cb) |
1206 | +{ |
1207 | + return impl_->RegisterTracker(menubar, cb); |
1208 | +} |
1209 | + |
1210 | +bool Manager::UnregisterTracker(std::string const& menubar, PositionTracker const& cb) |
1211 | +{ |
1212 | + return impl_->UnregisterTracker(menubar, cb); |
1213 | +} |
1214 | + |
1215 | + |
1216 | } // menu namespace |
1217 | } // unity namespace |
1218 | |
1219 | === modified file 'unity-shared/MenuManager.h' |
1220 | --- unity-shared/MenuManager.h 2015-06-05 14:28:27 +0000 |
1221 | +++ unity-shared/MenuManager.h 2016-09-01 22:11:45 +0000 |
1222 | @@ -67,6 +67,10 @@ |
1223 | |
1224 | key::Grabber::Ptr const& KeyGrabber() const; |
1225 | |
1226 | + typedef sigc::slot<void, int /*x*/, int /*y*/, double /*speed*/> PositionTracker; |
1227 | + bool RegisterTracker(std::string const& menubar, PositionTracker const&); |
1228 | + bool UnregisterTracker(std::string const& menubar, PositionTracker const& = PositionTracker()); |
1229 | + |
1230 | sigc::signal<void> appmenu_added; |
1231 | sigc::signal<void> appmenu_removed; |
1232 | sigc::signal<bool>::accumulated<any_true> open_first; |
1233 | |
1234 | === added file 'unity-shared/SigcSlotHash.h' |
1235 | --- unity-shared/SigcSlotHash.h 1970-01-01 00:00:00 +0000 |
1236 | +++ unity-shared/SigcSlotHash.h 2016-09-01 22:11:45 +0000 |
1237 | @@ -0,0 +1,70 @@ |
1238 | +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- |
1239 | +/* |
1240 | + * Copyright (C) 2016 Canonical Ltd |
1241 | + * |
1242 | + * This program is free software: you can redistribute it and/or modify |
1243 | + * it under the terms of the GNU General Public License version 3 as |
1244 | + * published by the Free Software Foundation. |
1245 | + * |
1246 | + * This program is distributed in the hope that it will be useful, |
1247 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1248 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1249 | + * GNU General Public License for more details. |
1250 | + * |
1251 | + * You should have received a copy of the GNU General Public License |
1252 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1253 | + * |
1254 | + * Authored by: Marco Trevisan <marco.trevisan@canonical.com> |
1255 | + */ |
1256 | + |
1257 | +#ifndef __UNITY_SIGC_SLOT_HASHER__ |
1258 | +#define __UNITY_SIGC_SLOT_HASHER__ |
1259 | + |
1260 | +#include <sigc++/slot.h> |
1261 | + |
1262 | +namespace sigc |
1263 | +{ |
1264 | +inline bool operator==(slot_base const& lhs, slot_base const& rhs) |
1265 | +{ |
1266 | + if (!lhs.rep_ || !rhs.rep_) |
1267 | + return (lhs.rep_ == rhs.rep_); |
1268 | + |
1269 | + return (lhs.rep_->call_ == rhs.rep_->call_); |
1270 | +} |
1271 | + |
1272 | +inline bool operator!=(slot_base const& lhs, slot_base const& rhs) |
1273 | +{ |
1274 | + return !(lhs == rhs); |
1275 | +} |
1276 | +} // sigc namespace |
1277 | + |
1278 | +namespace std |
1279 | +{ |
1280 | + |
1281 | +template<> |
1282 | +struct hash<sigc::slot_base> |
1283 | +{ |
1284 | + size_t operator()(sigc::slot_base const& cb) const |
1285 | + { |
1286 | + if (cb.rep_) |
1287 | + return hash<size_t>()(reinterpret_cast<size_t>(cb.rep_->call_)); |
1288 | + |
1289 | + return hash<size_t>()(reinterpret_cast<size_t>(cb.rep_)); |
1290 | + } |
1291 | +}; |
1292 | + |
1293 | +#if __GNUC__ < 6 |
1294 | +template<class T> |
1295 | +struct hash |
1296 | +{ |
1297 | + size_t operator()(T const& cb) const |
1298 | + { |
1299 | + static_assert(std::is_base_of<sigc::slot_base, T>::value, "Type is not derived from sigc::slot_base"); |
1300 | + return hash<sigc::slot_base>()(cb); |
1301 | + } |
1302 | +}; |
1303 | +#endif |
1304 | + |
1305 | +} // std namespace |
1306 | + |
1307 | +#endif // __UNITY_SIGC_SLOT_HASHER__ |
+1