Merge lp:~azzar1/unity/lp-552920 into lp:unity

Proposed by Andrea Azzarone
Status: Merged
Approved by: Marco Trevisan (Treviño)
Approved revision: no longer in the source branch.
Merged at revision: 4014
Proposed branch: lp:~azzar1/unity/lp-552920
Merge into: lp:unity
Prerequisite: lp:~azzar1/unity/cmake-3
Diff against target: 152 lines (+69/-9)
2 files modified
panel/PanelView.cpp (+64/-8)
panel/PanelView.h (+5/-1)
To merge this branch: bzr merge lp:~azzar1/unity/lp-552920
Reviewer Review Type Date Requested Status
Marco Trevisan (Treviño) Approve
PS Jenkins bot (community) continuous-integration Needs Fixing
Review via email: mp+267685@code.launchpad.net

Commit message

Avoid to open adjacent menu when moving from an indicator icon to its dropdown menu.

Description of the change

Basically we use the "triangle technique" [1] to avoid using delays. We cannot make it perfect because we are not monitoring mouse motion events directly but we are using XQueryPointer to get the mouse coordinates because gtk owns the mouse grab. Btw it significantly improves the current behavior.

[1] https://usercontent.irccloud-cdn.com/file/qXGkfaSw/triangle.png

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Marco Trevisan (Treviño) (3v1n0) wrote :

Very nice technique, and it will improve also when adding proper input monitoring with xinput2.

There Check the comments, mostly style stuff, btw.

Revision history for this message
Andrea Azzarone (azzar1) wrote :

Done. Please take a look at the inline comments.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Marco Trevisan (Treviño) (3v1n0) wrote :

Yeah, looks fine now.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'panel/PanelView.cpp'
2--- panel/PanelView.cpp 2015-04-21 15:12:02 +0000
3+++ panel/PanelView.cpp 2015-09-21 09:31:23 +0000
4@@ -24,6 +24,7 @@
5 #include <UnityCore/GLibWrapper.h>
6
7 #include "unity-shared/PanelStyle.h"
8+#include "unity-shared/RawPixel.h"
9 #include "unity-shared/TextureCache.h"
10 #include "unity-shared/WindowManager.h"
11 #include "unity-shared/UBusMessages.h"
12@@ -33,15 +34,16 @@
13
14 #include "PanelView.h"
15
16+namespace unity
17+{
18+namespace panel
19+{
20 namespace
21 {
22+const RawPixel TRIANGLE_THRESHOLD = 5_em;
23 const int refine_gradient_midpoint = 959;
24 }
25
26-namespace unity
27-{
28-namespace panel
29-{
30
31 NUX_IMPLEMENT_OBJECT_TYPE(PanelView);
32
33@@ -635,23 +637,75 @@
34 }
35 }
36
37+static bool PointInTriangle(nux::Point const& p, nux::Point const& t0, nux::Point const& t1, nux::Point const& t2)
38+{
39+ int s = t0.y * t2.x - t0.x * t2.y + (t2.y - t0.y) * p.x + (t0.x - t2.x) * p.y;
40+ int t = t0.x * t1.y - t0.y * t1.x + (t0.y - t1.y) * p.x + (t1.x - t0.x) * p.y;
41+
42+ if ((s < 0) != (t < 0))
43+ return false;
44+
45+ int A = -t1.y * t2.x + t0.y * (t2.x - t1.x) + t0.x * (t1.y - t2.y) + t1.x * t2.y;
46+ if (A < 0)
47+ {
48+ s = -s;
49+ t = -t;
50+ A = -A;
51+ }
52+
53+ return s > 0 && t > 0 && (s + t) < A;
54+}
55+
56+static double GetMouseVelocity(nux::Point const& p0, nux::Point const& p1, util::Timer &timer)
57+{
58+ int dx, dy;
59+ double speed;
60+ auto millis = timer.ElapsedMicroSeconds();
61+
62+ if (millis == 0)
63+ return 1;
64+
65+ dx = p0.x - p1.x;
66+ dy = p0.y - p1.y;
67+
68+ speed = sqrt(dx * dx + dy * dy) / millis * 1000;
69+
70+ return speed;
71+}
72+
73 bool PanelView::TrackMenuPointer()
74 {
75 nux::Point const& mouse = nux::GetGraphicsDisplay()->GetMouseScreenCoord();
76- if (tracked_pointer_pos_ != mouse)
77- {
78+ double speed = GetMouseVelocity(mouse, tracked_pointer_pos_, mouse_tracker_timer_);
79+
80+ mouse_tracker_timer_.Reset();
81+ tracked_pointer_pos_ = mouse;
82+
83+ double scale = Settings::Instance().em(monitor_)->DPIScale();
84+ if (speed > 0 && PointInTriangle(mouse,
85+ nux::Point(triangle_top_corner_.x, std::max(triangle_top_corner_.y - TRIANGLE_THRESHOLD.CP(scale), 0)),
86+ nux::Point(menu_geo_.x, menu_geo_.y),
87+ nux::Point(menu_geo_.x + menu_geo_.width, menu_geo_.y)))
88+ {
89+ return true;
90+ }
91+
92+ if (mouse != triangle_top_corner_)
93+ {
94+ triangle_top_corner_ = mouse;
95 OnMenuPointerMoved(mouse.x, mouse.y);
96- tracked_pointer_pos_ = mouse;
97 }
98
99 return true;
100 }
101
102-void PanelView::OnEntryActivated(std::string const& panel, std::string const& entry_id, nux::Rect const&)
103+void PanelView::OnEntryActivated(std::string const& panel, std::string const& entry_id, nux::Rect const& menu_geo)
104 {
105 if (!panel.empty() && panel != GetPanelName())
106 return;
107
108+ menu_geo_ = menu_geo;
109+
110 bool active = !entry_id.empty();
111 if (active && !track_menu_pointer_timeout_)
112 {
113@@ -665,6 +719,8 @@
114 // process. All the motion events will go to unity-panel-service while
115 // scrubbing because the active panel menu has (needs) the pointer grab.
116 //
117+ mouse_tracker_timer_.Reset();
118+ triangle_top_corner_ = nux::GetGraphicsDisplay()->GetMouseScreenCoord();
119 track_menu_pointer_timeout_.reset(new glib::Timeout(16));
120 track_menu_pointer_timeout_->Run(sigc::mem_fun(this, &PanelView::TrackMenuPointer));
121 }
122
123=== modified file 'panel/PanelView.h'
124--- panel/PanelView.h 2015-04-21 15:12:02 +0000
125+++ panel/PanelView.h 2015-09-21 09:31:23 +0000
126@@ -35,6 +35,7 @@
127 #include "unity-shared/Introspectable.h"
128 #include "unity-shared/MenuManager.h"
129 #include "unity-shared/MockableBaseWindow.h"
130+#include "unity-shared/Timer.h"
131 #include "PanelMenuView.h"
132 #include "PanelTray.h"
133 #include "PanelIndicatorsView.h"
134@@ -132,7 +133,8 @@
135 std::unique_ptr<nux::AbstractPaintLayer> bg_refine_single_column_layer_;
136
137 std::string active_overlay_;
138- nux::Point tracked_pointer_pos_;
139+ nux::Point tracked_pointer_pos_, triangle_top_corner_;
140+ util::Timer mouse_tracker_timer_;
141
142 bool is_dirty_;
143 bool opacity_maximized_toggle_;
144@@ -142,6 +144,8 @@
145 int monitor_;
146 int stored_dash_width_;
147
148+ nux::Geometry menu_geo_;
149+
150 connection::Manager on_indicator_updated_connections_;
151 connection::Manager maximized_opacity_toggle_connections_;
152 BackgroundEffectHelper bg_effect_helper_;