Merge lp:~3v1n0/unity/launcher-nux-animation into lp:unity

Proposed by Marco Trevisan (Treviño)
Status: Merged
Approved by: Christopher Townsend
Approved revision: no longer in the source branch.
Merged at revision: 3510
Proposed branch: lp:~3v1n0/unity/launcher-nux-animation
Merge into: lp:unity
Diff against target: 1277 lines (+261/-295)
5 files modified
launcher/Launcher.cpp (+241/-244)
launcher/Launcher.h (+12/-43)
plugins/unityshell/src/unityshell.cpp (+2/-2)
tests/test_launcher.cpp (+6/-0)
unity-shared/UBusMessages.h (+0/-6)
To merge this branch: bzr merge lp:~3v1n0/unity/launcher-nux-animation
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Christopher Townsend Approve
Review via email: mp+185416@code.launchpad.net

Commit message

Launcher: use nux::Animation for all the launcher animations

This allows to do these when compiz requests to prepare painting, instead of
using only an idle to perform this.

Description of the change

Use nux::AnimationValue for Launcher animations.

For now only the main animations (not the icons) have been ported. This allows to make sure we don't redraw when not needed, but the animators only obey to compiz and the queuedraw will happen only when really needed.

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
Christopher Townsend (townsend) wrote :

Somehow, there is a regression with the progressive Launcher scrolling when using the cursor to scroll.

657 + speed = (SCROLL_AREA_HEIGHT - _mouse_position.y) / SCROLL_AREA_HEIGHT * SCROLL_FPS;
669 + speed = ((_mouse_position.y + 1) - (GetGeometry().height - SCROLL_AREA_HEIGHT)) / SCROLL_AREA_HEIGHT * SCROLL_FPS;

Adjusting the formatting of the line (pulling it in 2 spaces) cannot possibly be the reason for this, so it's a mystery why there is a regression. However, I fixed it by doing this:

speed = (float(SCROLL_AREA_HEIGHT - _mouse_position.y) / SCROLL_AREA_HEIGHT) * SCROLL_FPS;
speed = (float((_mouse_position.y + 1) - (GetGeometry().height - SCROLL_AREA_HEIGHT)) / SCROLL_AREA_HEIGHT) * SCROLL_FPS;

There is probably a better way to cast that for C++, but I'll leave that up to you. Other than this, I haven't seen any other regressions and the code looks good.

review: Needs Fixing
Revision history for this message
Christopher Townsend (townsend) wrote :

Maybe the regression is due to changing _mouse_position from type nux::Point2 to nux::Point, but that is just a guess.

Revision history for this message
Marco Trevisan (Treviño) (3v1n0) wrote :

> Maybe the regression is due to changing _mouse_position from type nux::Point2
> to nux::Point, but that is just a guess.

Yes, very likely... Since Point2 contained floats... I consider if this may affect other computations.

Thank you for looking at it, much appreciated! :)

Revision history for this message
Marco Trevisan (Treviño) (3v1n0) wrote :

Ok, branch updated... It should work again as expected.

Revision history for this message
Christopher Townsend (townsend) wrote :

Cool, the regression is fixed and I can't see any other regressions. +1

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'launcher/Launcher.cpp'
2--- launcher/Launcher.cpp 2013-09-12 16:14:45 +0000
3+++ launcher/Launcher.cpp 2013-09-16 17:01:30 +0000
4@@ -53,7 +53,6 @@
5 #include "unity-shared/UnitySettings.h"
6 #include "unity-shared/GraphicsUtils.h"
7
8-
9 #include <UnityCore/GLibWrapper.h>
10 #include <UnityCore/Variant.h>
11
12@@ -63,7 +62,7 @@
13 namespace unity
14 {
15 using ui::RenderArg;
16-using ui::Decaymulator;
17+namespace na = nux::animation;
18
19 namespace launcher
20 {
21@@ -90,8 +89,15 @@
22 const int ANIM_DURATION_LONG = 350;
23 const int START_DRAGICON_DURATION = 250;
24
25+const int DEFAULT_ICON_SIZE = 48;
26+const int DEFAULT_ICON_SIZE_DELTA = 6;
27+const int SPACE_BETWEEN_ICONS = 5;
28+
29 const int MOUSE_DEADZONE = 15;
30+
31 const float DRAG_OUT_PIXELS = 300.0f;
32+const float FOLDED_Z_DISTANCE = 10.f;
33+const float NEG_FOLDED_ANGLE = -1.0f;
34
35 const int SCROLL_AREA_HEIGHT = 24;
36 const int SCROLL_FPS = 30;
37@@ -106,7 +112,6 @@
38 const std::string URGENT_TIMEOUT = "urgent-timeout";
39 }
40
41-
42 NUX_IMPLEMENT_OBJECT_TYPE(Launcher);
43
44 const int Launcher::Launcher::ANIM_DURATION_SHORT = 125;
45@@ -114,11 +119,6 @@
46 Launcher::Launcher(MockableBaseWindow* parent,
47 NUX_FILE_LINE_DECL)
48 : View(NUX_FILE_LINE_PARAM)
49-#ifdef USE_X11
50- , display(nux::GetGraphicsDisplay()->GetX11Display())
51-#else
52- , display(0)
53-#endif
54 , monitor(0)
55 , _parent(parent)
56 , _active_quicklist(nullptr)
57@@ -131,16 +131,9 @@
58 , _initial_drag_animation(false)
59 , _dash_is_open(false)
60 , _hud_is_open(false)
61- , _folded_angle(1.0f)
62- , _neg_folded_angle(-1.0f)
63- , _folded_z_distance(10.0f)
64- , _edge_overcome_pressure(0.0f)
65+ , _folded(true)
66 , _launcher_action_state(ACTION_NONE)
67- , _space_between_icons(5)
68- , _icon_image_size(48)
69- , _icon_image_size_delta(6)
70- , _icon_glow_size(62)
71- , _icon_size(_icon_image_size + _icon_image_size_delta)
72+ , _icon_size(DEFAULT_ICON_SIZE + DEFAULT_ICON_SIZE_DELTA)
73 , _dnd_delta_y(0)
74 , _dnd_delta_x(0)
75 , _postreveal_mousemove_delta_x(0)
76@@ -159,23 +152,28 @@
77 , _last_reveal_progress(0.0f)
78 , _drag_action(nux::DNDACTION_NONE)
79 , _selection_atom(0)
80+ , auto_hide_animation_(ANIM_DURATION_SHORT)
81+ , hover_animation_(ANIM_DURATION)
82+ , drag_over_animation_(ANIM_DURATION_LONG)
83+ , drag_out_animation_(ANIM_DURATION_SHORT)
84+ , drag_icon_animation_(ANIM_DURATION_SHORT)
85+ , dnd_hide_animation_(ANIM_DURATION * 3)
86 , dash_showing_animation_(90)
87 , icon_renderer(std::make_shared<ui::IconRenderer>())
88 {
89- m_Layout = new nux::HLayout(NUX_TRACKER_LOCATION);
90 icon_renderer->monitor = monitor();
91
92 bg_effect_helper_.owner = this;
93 bg_effect_helper_.enabled = false;
94
95- SetCompositionLayout(m_Layout);
96 CaptureMouseDownAnyWhereElse(true);
97 SetAcceptKeyNavFocusOnMouseDown(false);
98 SetAcceptMouseWheelEvent(true);
99 SetDndEnabled(false, true);
100
101+ auto const& redraw_cb = sigc::hide(sigc::mem_fun(this, &Launcher::QueueDraw));
102 _hide_machine.should_hide_changed.connect(sigc::mem_fun(this, &Launcher::SetHidden));
103- _hide_machine.reveal_progress.changed.connect([&](float value) { EnsureAnimation(); });
104+ _hide_machine.reveal_progress.changed.connect(redraw_cb);
105 _hover_machine.should_hover_changed.connect(sigc::mem_fun(this, &Launcher::SetHover));
106
107 mouse_down.connect(sigc::mem_fun(this, &Launcher::RecvMouseDown));
108@@ -185,7 +183,6 @@
109 mouse_leave.connect(sigc::mem_fun(this, &Launcher::RecvMouseLeave));
110 mouse_move.connect(sigc::mem_fun(this, &Launcher::RecvMouseMove));
111 mouse_wheel.connect(sigc::mem_fun(this, &Launcher::RecvMouseWheel));
112- //OnEndFocus.connect (sigc::mem_fun (this, &Launcher::exitKeyNavMode));
113
114 QuicklistManager& ql_manager = *(QuicklistManager::Default());
115 ql_manager.quicklist_opened.connect(sigc::mem_fun(this, &Launcher::RecvQuicklistOpened));
116@@ -196,14 +193,7 @@
117 wm.initiate_expo.connect(sigc::mem_fun(this, &Launcher::OnPluginStateChanged));
118 wm.terminate_spread.connect(sigc::mem_fun(this, &Launcher::OnPluginStateChanged));
119 wm.terminate_expo.connect(sigc::mem_fun(this, &Launcher::OnPluginStateChanged));
120- wm.screen_viewport_switch_ended.connect(sigc::mem_fun(this, &Launcher::EnsureAnimation));
121-
122- // 0 out timers to avoid wonky startups
123- for (int i = 0; i < TIME_LAST; ++i)
124- {
125- _times[i].tv_sec = 0;
126- _times[i].tv_nsec = 0;
127- }
128+ wm.screen_viewport_switch_ended.connect(sigc::mem_fun(this, &Launcher::QueueDraw));
129
130 _urgent_finished_time.tv_sec = 0;
131 _urgent_finished_time.tv_nsec = 0;
132@@ -212,7 +202,7 @@
133 ubus_.RegisterInterest(UBUS_OVERLAY_HIDDEN, sigc::mem_fun(this, &Launcher::OnOverlayHidden));
134 ubus_.RegisterInterest(UBUS_LAUNCHER_LOCK_HIDE, sigc::mem_fun(this, &Launcher::OnLockHideChanged));
135
136- icon_renderer->SetTargetSize(_icon_size, _icon_image_size, _space_between_icons);
137+ icon_renderer->SetTargetSize(_icon_size, DEFAULT_ICON_SIZE, SPACE_BETWEEN_ICONS);
138
139 TextureCache& cache = TextureCache::GetDefault();
140 launcher_sheen_ = cache.FindTexture("dash_sheen.png");
141@@ -220,6 +210,18 @@
142
143 options.changed.connect(sigc::mem_fun(this, &Launcher::OnOptionsChanged));
144 monitor.changed.connect(sigc::mem_fun(this, &Launcher::OnMonitorChanged));
145+
146+ auto_hide_animation_.updated.connect(redraw_cb);
147+ hover_animation_.updated.connect(redraw_cb);
148+ drag_over_animation_.updated.connect(redraw_cb);
149+ drag_out_animation_.updated.connect(redraw_cb);
150+ drag_icon_animation_.updated.connect(redraw_cb);
151+ dnd_hide_animation_.updated.connect(redraw_cb);
152+ dash_showing_animation_.updated.connect(redraw_cb);
153+
154+ /* FIXME: the easing curve for this animation should be only
155+ * std::pow(progress, 2); */
156+ drag_over_animation_.SetEasingCurve(na::EasingCurve(na::EasingCurve::Type::ExpoEaseIn));
157 }
158
159 /* Introspection */
160@@ -247,31 +249,26 @@
161 {
162 _drag_out_delta_x =
163 CLAMP(_drag_out_delta_x + event.GetDelta().x, 0.0f, DRAG_OUT_PIXELS);
164- EnsureAnimation();
165+ QueueDraw();
166 }
167
168 void Launcher::OnDragFinish(const nux::GestureEvent &event)
169 {
170 if (_drag_out_delta_x >= DRAG_OUT_PIXELS - 90.0f)
171 _hide_machine.SetQuirk(LauncherHideMachine::MT_DRAG_OUT, true);
172- TimeUtil::SetTimeStruct(&_times[TIME_DRAG_OUT],
173- &_times[TIME_DRAG_OUT],
174- ANIM_DURATION_SHORT);
175- EnsureAnimation();
176+
177+ drag_out_animation_.SetStartValue(1.0f).SetFinishValue(0.0f).Start();
178 _drag_gesture_ongoing = false;
179 }
180 #endif
181
182 void Launcher::AddProperties(GVariantBuilder* builder)
183 {
184- timespec current;
185- clock_gettime(CLOCK_MONOTONIC, &current);
186-
187 unity::variant::BuilderWrapper(builder)
188 .add(GetAbsoluteGeometry())
189- .add("hover-progress", GetHoverProgress(current))
190- .add("dnd-exit-progress", DnDExitProgress(current))
191- .add("autohide-progress", AutohideProgress(current))
192+ .add("hover-progress", hover_animation_.GetCurrentValue())
193+ .add("dnd-exit-progress", drag_over_animation_.GetCurrentValue())
194+ .add("autohide-progress", auto_hide_animation_.GetCurrentValue())
195 .add("dnd-delta", _dnd_delta_y)
196 .add("hovered", _hovered)
197 .add("hidemode", options()->hide_mode)
198@@ -288,11 +285,37 @@
199
200 void Launcher::SetMousePosition(int x, int y)
201 {
202- bool beyond_drag_threshold = MouseBeyondDragThreshold();
203- _mouse_position = nux::Point2(x, y);
204+ bool was_beyond_drag_threshold = MouseBeyondDragThreshold();
205+ _mouse_position = nux::Point(x, y);
206+ bool is_beyond_drag_threshold = MouseBeyondDragThreshold();
207
208- if (beyond_drag_threshold != MouseBeyondDragThreshold())
209- TimeUtil::SetTimeStruct(&_times[TIME_DRAG_THRESHOLD], &_times[TIME_DRAG_THRESHOLD], ANIM_DURATION_SHORT);
210+ if (was_beyond_drag_threshold != is_beyond_drag_threshold)
211+ {
212+ if (!is_beyond_drag_threshold)
213+ {
214+ if (drag_icon_animation_.CurrentState() == na::Animation::State::Running)
215+ {
216+ if (drag_icon_animation_.GetFinishValue() != 1.0f)
217+ drag_icon_animation_.Reverse();
218+ }
219+ else
220+ {
221+ drag_icon_animation_.SetStartValue(0.0f).SetFinishValue(1.0f).Start();
222+ }
223+ }
224+ else
225+ {
226+ if (drag_icon_animation_.CurrentState() == na::Animation::State::Running)
227+ {
228+ if (drag_icon_animation_.GetFinishValue() != 0.0f)
229+ drag_icon_animation_.Reverse();
230+ }
231+ else
232+ {
233+ drag_icon_animation_.SetStartValue(1.0f).SetFinishValue(0.0f).Start();
234+ }
235+ }
236+ }
237
238 EnsureScrollTimer();
239 }
240@@ -326,61 +349,14 @@
241 }
242
243 /* Render Layout Logic */
244-float Launcher::GetHoverProgress(struct timespec const& current) const
245-{
246- if (_hovered)
247- return CLAMP((float)(unity::TimeUtil::TimeDelta(&current, &_times[TIME_ENTER])) / (float) ANIM_DURATION, 0.0f, 1.0f);
248- else
249- return 1.0f - CLAMP((float)(unity::TimeUtil::TimeDelta(&current, &_times[TIME_LEAVE])) / (float) ANIM_DURATION, 0.0f, 1.0f);
250-}
251-
252-float Launcher::DnDExitProgress(struct timespec const& current) const
253-{
254- return pow(1.0f - CLAMP((float)(unity::TimeUtil::TimeDelta(&current, &_times[TIME_DRAG_END])) / (float) ANIM_DURATION_LONG, 0.0f, 1.0f), 2);
255-}
256-
257-float Launcher::DragOutProgress(struct timespec const& current) const
258-{
259- float timeout = CLAMP((float)(unity::TimeUtil::TimeDelta(&current, &_times[TIME_DRAG_OUT])) / (float) ANIM_DURATION_SHORT, 0.0f, 1.0f);
260- float progress = CLAMP(_drag_out_delta_x / DRAG_OUT_PIXELS, 0.0f, 1.0f);
261-
262- if (_drag_gesture_ongoing
263- || _hide_machine.GetQuirk(LauncherHideMachine::MT_DRAG_OUT))
264+float Launcher::DragOutProgress() const
265+{
266+ float progress = _drag_out_delta_x / DRAG_OUT_PIXELS;
267+
268+ if (_drag_gesture_ongoing || _hide_machine.GetQuirk(LauncherHideMachine::MT_DRAG_OUT))
269 return progress;
270 else
271- return progress * (1.0f - timeout);
272-}
273-
274-float Launcher::AutohideProgress(struct timespec const& current) const
275-{
276- // time-based progress (full scale or finish the TRIGGER_AUTOHIDE_MIN -> 0.00f on bfb)
277- float animation_progress;
278- animation_progress = CLAMP((float)(unity::TimeUtil::TimeDelta(&current, &_times[TIME_AUTOHIDE])) / (float) ANIM_DURATION_SHORT, 0.0f, 1.0f);
279- if (_hidden)
280- return animation_progress;
281- else
282- return 1.0f - animation_progress;
283-}
284-
285-float Launcher::DragHideProgress(struct timespec const& current) const
286-{
287- if (_drag_edge_touching)
288- return CLAMP((float)(unity::TimeUtil::TimeDelta(&current, &_times[TIME_DRAG_EDGE_TOUCH])) / (float)(ANIM_DURATION * 3), 0.0f, 1.0f);
289- else
290- return 1.0f - CLAMP((float)(unity::TimeUtil::TimeDelta(&current, &_times[TIME_DRAG_EDGE_TOUCH])) / (float)(ANIM_DURATION * 3), 0.0f, 1.0f);
291-}
292-
293-float Launcher::DragThresholdProgress(struct timespec const& current) const
294-{
295- if (MouseBeyondDragThreshold())
296- return 1.0f - CLAMP((float)(unity::TimeUtil::TimeDelta(&current, &_times[TIME_DRAG_THRESHOLD])) / (float) ANIM_DURATION_SHORT, 0.0f, 1.0f);
297- else
298- return CLAMP((float)(unity::TimeUtil::TimeDelta(&current, &_times[TIME_DRAG_THRESHOLD])) / (float) ANIM_DURATION_SHORT, 0.0f, 1.0f);
299-}
300-
301-void Launcher::EnsureAnimation()
302-{
303- QueueDraw();
304+ return progress * drag_out_animation_.GetCurrentValue();
305 }
306
307 bool Launcher::IconNeedsAnimation(AbstractLauncherIcon::Ptr const& icon, struct timespec const& current) const
308@@ -445,43 +421,12 @@
309 // performance here can be improved by caching the longer remaining animation found and short circuiting to that each time
310 // this way extra checks may be avoided
311
312- if (_last_reveal_progress != _hide_machine.reveal_progress)
313- return true;
314-
315 // short circuit to avoid unneeded calculations
316 struct timespec current;
317 clock_gettime(CLOCK_MONOTONIC, &current);
318
319- // hover in animation
320- if (unity::TimeUtil::TimeDelta(&current, &_times[TIME_ENTER]) < ANIM_DURATION)
321- return true;
322-
323- // hover out animation
324- if (unity::TimeUtil::TimeDelta(&current, &_times[TIME_LEAVE]) < ANIM_DURATION)
325- return true;
326-
327- // drag end animation
328- if (unity::TimeUtil::TimeDelta(&current, &_times[TIME_DRAG_END]) < ANIM_DURATION_LONG)
329- return true;
330-
331- // hide animation (time only), position is trigger manually on the bfb
332- if (unity::TimeUtil::TimeDelta(&current, &_times[TIME_AUTOHIDE]) < ANIM_DURATION_SHORT)
333- return true;
334-
335- // collapse animation on DND out of launcher space
336- if (unity::TimeUtil::TimeDelta(&current, &_times[TIME_DRAG_THRESHOLD]) < ANIM_DURATION_SHORT)
337- return true;
338-
339- // hide animation for dnd
340- if (unity::TimeUtil::TimeDelta(&current, &_times[TIME_DRAG_EDGE_TOUCH]) < ANIM_DURATION * 6)
341- return true;
342-
343- // restore from drag_out animation
344- if (unity::TimeUtil::TimeDelta(&current, &_times[TIME_DRAG_OUT]) < ANIM_DURATION_SHORT)
345- return true;
346-
347 // animations happening on specific icons
348- for (auto const &icon : *_model)
349+ for (auto const& icon : *_model)
350 if (IconNeedsAnimation(icon, current))
351 return true;
352
353@@ -496,6 +441,7 @@
354 else
355 return 0.25f;
356 }
357+
358 /* Max is the initial state over the bfb */
359 float Launcher::GetAutohidePositionMax() const
360 {
361@@ -505,7 +451,6 @@
362 return 0.75f;
363 }
364
365-
366 float Launcher::IconVisibleProgress(AbstractLauncherIcon::Ptr const& icon, struct timespec const& current) const
367 {
368 if (!icon->IsVisibleOnMonitor(monitor))
369@@ -549,7 +494,7 @@
370
371 break;
372 }
373- position += (_icon_size + _space_between_icons) * IconVisibleProgress(model_icon, current);
374+ position += (_icon_size + SPACE_BETWEEN_ICONS) * IconVisibleProgress(model_icon, current);
375 }
376 }
377 }
378@@ -925,7 +870,9 @@
379
380 if (icon == _drag_icon)
381 {
382- if (MouseBeyondDragThreshold())
383+ bool mouse_beyond_drag_threshold = MouseBeyondDragThreshold();
384+
385+ if (mouse_beyond_drag_threshold)
386 arg.stick_thingy = true;
387
388 if (GetActionState() == ACTION_DRAG_ICON ||
389@@ -935,7 +882,10 @@
390 arg.skip = true;
391 }
392
393- size_modifier *= DragThresholdProgress(current);
394+ if (drag_icon_animation_.CurrentState() == na::Animation::State::Running)
395+ size_modifier *= drag_icon_animation_.GetCurrentValue();
396+ else if (mouse_beyond_drag_threshold)
397+ size_modifier = 0.0f;
398 }
399
400 if (size_modifier <= 0.0f)
401@@ -957,8 +907,8 @@
402 center.z += folded_z_distance * folding_progress;
403 arg.rotation.x = animation_neg_rads * folding_progress;
404
405- float spacing_overlap = CLAMP((float)(center.y + (2.0f * half_size * size_modifier) + (_space_between_icons * size_modifier) - folding_threshold) / (float) _icon_size, 0.0f, 1.0f);
406- float spacing = (_space_between_icons * (1.0f - spacing_overlap) + folded_spacing * spacing_overlap) * size_modifier;
407+ float spacing_overlap = CLAMP((float)(center.y + (2.0f * half_size * size_modifier) + (SPACE_BETWEEN_ICONS * size_modifier) - folding_threshold) / (float) _icon_size, 0.0f, 1.0f);
408+ float spacing = (SPACE_BETWEEN_ICONS * (1.0f - spacing_overlap) + folded_spacing * spacing_overlap) * size_modifier;
409
410 nux::Point3 centerOffset;
411 float center_transit_progress = IconCenterTransitionProgress(icon, current);
412@@ -1015,28 +965,29 @@
413
414 nux::Color const& colorify = FullySaturateColor(options()->background_color);
415
416- float hover_progress = GetHoverProgress(current);
417- float folded_z_distance = _folded_z_distance * (1.0f - hover_progress);
418- float animation_neg_rads = _neg_folded_angle * (1.0f - hover_progress);
419+ float hover_progress = _folded ? hover_animation_.GetCurrentValue() : 1.0f;
420+ float folded_z_distance = FOLDED_Z_DISTANCE * (1.0f - hover_progress);
421+ float animation_neg_rads = NEG_FOLDED_ANGLE * (1.0f - hover_progress);
422
423 float folding_constant = 0.25f;
424 float folding_not_constant = folding_constant + ((1.0f - folding_constant) * hover_progress);
425
426 float folded_size = _icon_size * folding_not_constant;
427- float folded_spacing = _space_between_icons * folding_not_constant;
428+ float folded_spacing = SPACE_BETWEEN_ICONS * folding_not_constant;
429
430 center.x = geo.width / 2;
431- center.y = _space_between_icons;
432+ center.y = SPACE_BETWEEN_ICONS;
433 center.z = 0;
434
435 int launcher_height = geo.height;
436+ _folded = true;
437
438 // compute required height of launcher AND folding threshold
439 float sum = 0.0f + center.y;
440 float folding_threshold = launcher_height - _icon_size / 2.5f;
441 for (it = _model->begin(); it != _model->end(); ++it)
442 {
443- float height = (_icon_size + _space_between_icons) * IconVisibleProgress(*it, current);
444+ float height = (_icon_size + SPACE_BETWEEN_ICONS) * IconVisibleProgress(*it, current);
445 sum += height;
446
447 // magic constant must some day be explained, for now suffice to say this constant prevents the bottom from "marching";
448@@ -1046,14 +997,17 @@
449 folding_threshold -= CLAMP(sum - launcher_height, 0.0f, height * magic_constant) * (folding_constant + (1.0f - folding_constant) * unfold_progress);
450 }
451
452- if (sum - _space_between_icons <= launcher_height)
453+ if (sum - SPACE_BETWEEN_ICONS <= launcher_height)
454+ {
455 folding_threshold = launcher_height;
456+ _folded = false;
457+ }
458
459 float autohide_offset = 0.0f;
460 *launcher_alpha = 1.0f;
461 if (options()->hide_mode != LAUNCHER_HIDE_NEVER || _hide_machine.GetQuirk(LauncherHideMachine::LOCK_HIDE))
462 {
463- float autohide_progress = AutohideProgress(current) * (1.0f - DragOutProgress(current));
464+ float autohide_progress = auto_hide_animation_.GetCurrentValue() * (1.0f - DragOutProgress());
465 if (_dash_is_open)
466 {
467 *launcher_alpha = dash_showing_animation_.GetCurrentValue();
468@@ -1073,7 +1027,7 @@
469 }
470 }
471
472- float drag_hide_progress = DragHideProgress(current);
473+ float drag_hide_progress = dnd_hide_animation_.GetCurrentValue();
474 if (options()->hide_mode != LAUNCHER_HIDE_NEVER && drag_hide_progress > 0.0f)
475 {
476 autohide_offset -= geo.width * 0.25f * drag_hide_progress;
477@@ -1104,7 +1058,6 @@
478 last_geo = box_geo;
479 _enter_y = 0;
480
481-
482 // logically dnd exit only restores to the clamped ranges
483 // hover_progress restores to 0
484 _launcher_drag_delta_max = 0.0f;
485@@ -1121,7 +1074,7 @@
486
487 if (GetActionState() != ACTION_DRAG_LAUNCHER)
488 {
489- float dnd_progress = DnDExitProgress(current);
490+ float dnd_progress = drag_over_animation_.GetCurrentValue();
491
492 if (_launcher_drag_delta > _launcher_drag_delta_max)
493 delta_y = _launcher_drag_delta_max + (delta_y - _launcher_drag_delta_max) * dnd_progress;
494@@ -1165,15 +1118,15 @@
495 float shelf_sum = 0.0f;
496 for (it = _model->shelf_begin(); it != _model->shelf_end(); ++it)
497 {
498- float height = (_icon_size + _space_between_icons) * IconVisibleProgress(*it, current);
499+ float height = (_icon_size + SPACE_BETWEEN_ICONS) * IconVisibleProgress(*it, current);
500 shelf_sum += height;
501 }
502
503 // add bottom padding
504 if (shelf_sum > 0.0f)
505- shelf_sum += _space_between_icons;
506+ shelf_sum += SPACE_BETWEEN_ICONS;
507
508- float shelf_delta = MAX(((launcher_height - shelf_sum) + _space_between_icons) - center.y, 0.0f);
509+ float shelf_delta = MAX(((launcher_height - shelf_sum) + SPACE_BETWEEN_ICONS) - center.y, 0.0f);
510 folding_threshold += shelf_delta;
511 center.y += shelf_delta;
512
513@@ -1200,7 +1153,7 @@
514 {
515 _shortcuts_shown = show;
516 _hide_machine.SetQuirk(LauncherHideMachine::SHORTCUT_KEYS_VISIBLE, show);
517- EnsureAnimation();
518+ QueueDraw();
519 }
520
521 void Launcher::OnLockHideChanged(GVariant *data)
522@@ -1282,7 +1235,7 @@
523 if (_icon_under_mouse)
524 _icon_under_mouse->HideTooltip();
525 }
526- EnsureAnimation();
527+ QueueDraw();
528 }
529
530 void Launcher::OnOverlayHidden(GVariant* data)
531@@ -1324,12 +1277,13 @@
532 SaturateIcons();
533 }
534 }
535- EnsureAnimation();
536
537 // as the leave event is no more received when the place is opened
538 // FIXME: remove when we change the mouse grab strategy in nux
539 nux::Point pt = nux::GetWindowCompositor().GetMousePosition();
540 SetStateMouseOverLauncher(GetAbsoluteGeometry().IsInside(pt));
541+
542+ QueueDraw();
543 }
544
545 bool Launcher::IsOverlayOpen() const
546@@ -1351,21 +1305,39 @@
547 _hide_machine.SetQuirk(LauncherHideMachine::MOUSE_MOVE_POST_REVEAL, false);
548 _hide_machine.SetQuirk(LauncherHideMachine::MT_DRAG_OUT, false);
549 SetStateMouseOverLauncher(false);
550+
551+ if (auto_hide_animation_.CurrentState() == na::Animation::State::Running)
552+ {
553+ if (auto_hide_animation_.GetFinishValue() != 1.0f)
554+ auto_hide_animation_.Reverse();
555+ }
556+ else
557+ {
558+ auto_hide_animation_.SetStartValue(0.0f).SetFinishValue(1.0f).Start();
559+ }
560+ }
561+ else
562+ {
563+ if (auto_hide_animation_.CurrentState() == na::Animation::State::Running)
564+ {
565+ if (auto_hide_animation_.GetFinishValue() != 0.0f)
566+ auto_hide_animation_.Reverse();
567+ }
568+ else
569+ {
570+ auto_hide_animation_.SetStartValue(1.0f).SetFinishValue(0.0f).Start();
571+ }
572 }
573
574 _postreveal_mousemove_delta_x = 0;
575 _postreveal_mousemove_delta_y = 0;
576
577- TimeUtil::SetTimeStruct(&_times[TIME_AUTOHIDE], &_times[TIME_AUTOHIDE], ANIM_DURATION_SHORT);
578-
579 if (nux::GetWindowThread()->IsEmbeddedWindow())
580 _parent->EnableInputWindow(!hide_launcher, launcher::window_title, false, false);
581
582 if (!hide_launcher && GetActionState() == ACTION_DRAG_EXTERNAL)
583 DndReset();
584
585- EnsureAnimation();
586-
587 hidden_changed.emit();
588 }
589
590@@ -1434,7 +1406,7 @@
591 SetHideMode(options->hide_mode);
592
593 ConfigureBarrier();
594- EnsureAnimation();
595+ QueueDraw();
596 }
597
598 void Launcher::ConfigureBarrier()
599@@ -1451,7 +1423,6 @@
600 bool fixed_launcher = (hidemode == LAUNCHER_HIDE_NEVER);
601 _parent->InputWindowEnableStruts(fixed_launcher);
602 _hide_machine.SetMode(static_cast<LauncherHideMachine::HideMode>(hidemode));
603- EnsureAnimation();
604 }
605
606 BacklightMode Launcher::GetBacklightMode() const
607@@ -1506,12 +1477,32 @@
608
609 if (!IsInKeyNavMode() && _hovered)
610 {
611- _enter_y = (int) _mouse_position.y;
612- TimeUtil::SetTimeStruct(&_times[TIME_ENTER], &_times[TIME_LEAVE], ANIM_DURATION);
613+ _enter_y = _mouse_position.y;
614+
615+ if (_folded)
616+ {
617+ if (hover_animation_.CurrentState() == na::Animation::State::Running)
618+ {
619+ if (hover_animation_.GetFinishValue() != 1.0f)
620+ hover_animation_.Reverse();
621+ }
622+ else
623+ {
624+ hover_animation_.SetStartValue(0.0f).SetFinishValue(1.0f).Start();
625+ }
626+ }
627 }
628- else
629+ else if (_folded)
630 {
631- TimeUtil::SetTimeStruct(&_times[TIME_LEAVE], &_times[TIME_ENTER], ANIM_DURATION);
632+ if (hover_animation_.CurrentState() == na::Animation::State::Running)
633+ {
634+ if (hover_animation_.GetFinishValue() != 0.0f)
635+ hover_animation_.Reverse();
636+ }
637+ else
638+ {
639+ hover_animation_.SetStartValue(1.0f).SetFinishValue(0.0f).Start();
640+ }
641 }
642
643 if (IsOverlayOpen() && !_hide_machine.GetQuirk(LauncherHideMachine::EXTERNAL_DND_ACTIVE))
644@@ -1521,8 +1512,6 @@
645 else
646 DesaturateIcons();
647 }
648-
649- EnsureAnimation();
650 }
651
652 bool Launcher::MouseOverTopScrollArea()
653@@ -1538,7 +1527,6 @@
654 bool Launcher::OnScrollTimeout()
655 {
656 bool continue_animation = true;
657- int speed = 0;
658
659 if (IsInKeyNavMode() || !_hovered ||
660 GetActionState() == ACTION_DRAG_LAUNCHER)
661@@ -1548,22 +1536,28 @@
662 else if (MouseOverTopScrollArea())
663 {
664 if (_launcher_drag_delta >= _launcher_drag_delta_max)
665+ {
666 continue_animation = false;
667+ }
668 else
669 {
670- speed = (SCROLL_AREA_HEIGHT - _mouse_position.y) / SCROLL_AREA_HEIGHT * SCROLL_FPS;
671- _launcher_drag_delta += speed;
672+ int mouse_distance = (SCROLL_AREA_HEIGHT - _mouse_position.y);
673+ int speed = static_cast<float>(mouse_distance) / SCROLL_AREA_HEIGHT * SCROLL_FPS;
674+ _launcher_drag_delta += speed;
675 }
676 }
677 else if (MouseOverBottomScrollArea())
678 {
679 if (_launcher_drag_delta <= _launcher_drag_delta_min)
680+ {
681 continue_animation = false;
682+ }
683 else
684 {
685- speed = ((_mouse_position.y + 1) - (GetGeometry().height - SCROLL_AREA_HEIGHT)) / SCROLL_AREA_HEIGHT * SCROLL_FPS;
686- _launcher_drag_delta -= speed;
687- }
688+ int mouse_distance = (_mouse_position.y + 1) - (GetGeometry().height - SCROLL_AREA_HEIGHT);
689+ int speed = static_cast<float>(mouse_distance) / SCROLL_AREA_HEIGHT * SCROLL_FPS;
690+ _launcher_drag_delta -= speed;
691+ }
692 }
693 else
694 {
695@@ -1572,7 +1566,7 @@
696
697 if (continue_animation)
698 {
699- EnsureAnimation();
700+ QueueDraw();
701 }
702
703 return continue_animation;
704@@ -1610,7 +1604,7 @@
705 struct timespec urgent_time = icon->GetQuirkTime(AbstractLauncherIcon::Quirk::URGENT);
706 DeltaTime urgent_delta = unity::TimeUtil::TimeDelta(&urgent_time, &_urgent_finished_time);
707
708- // If the Launcher is hidden, then add a timer to wiggle the urgent icons at
709+ // If the Launcher is hidden, then add a timer to wiggle the urgent icons at
710 // certain intervals (1m, 2m, 4m, 8m, 16m, & 32m).
711 if (_hidden && !_urgent_timer_running && urgent_delta > 0)
712 {
713@@ -1626,7 +1620,7 @@
714 _urgent_wiggle_time = 0;
715 SetUrgentTimer(BASE_URGENT_WIGGLE_PERIOD);
716 }
717- // If the Launcher is no longer hidden, then after the Launcher is fully revealed, wiggle the
718+ // If the Launcher is no longer hidden, then after the Launcher is fully revealed, wiggle the
719 // urgent icon and then stop the timer (if it's running).
720 else if (!_hidden && _urgent_ack_needed)
721 {
722@@ -1703,11 +1697,7 @@
723 ui::IconRenderer::DestroyShortcutTextures();
724
725 _icon_size = tile_size;
726- _icon_image_size = icon_size;
727- _icon_image_size_delta = tile_size - icon_size;
728- _icon_glow_size = icon_size + 14;
729-
730- icon_renderer->SetTargetSize(_icon_size, _icon_image_size, _space_between_icons);
731+ icon_renderer->SetTargetSize(_icon_size, icon_size, SPACE_BETWEEN_ICONS);
732
733 nux::Geometry const& parent_geo = _parent->GetGeometry();
734 Resize(nux::Point(parent_geo.x, parent_geo.y), parent_geo.height);
735@@ -1730,9 +1720,9 @@
736
737 void Launcher::OnIconAdded(AbstractLauncherIcon::Ptr const& icon)
738 {
739- EnsureAnimation();
740+ QueueDraw();
741
742- icon->needs_redraw.connect(sigc::mem_fun(this, &Launcher::OnIconNeedsRedraw));
743+ icon->needs_redraw.connect(sigc::hide(sigc::mem_fun(this, &Launcher::QueueDraw)));
744 icon->tooltip_visible.connect(sigc::mem_fun(this, &Launcher::OnTooltipVisible));
745 }
746
747@@ -1744,24 +1734,20 @@
748 if (icon == _drag_icon)
749 _drag_icon = nullptr;
750
751- EnsureAnimation();
752-}
753-
754-void Launcher::OnOrderChanged()
755-{
756- EnsureAnimation();
757+ QueueDraw();
758 }
759
760 void Launcher::SetModel(LauncherModel::Ptr model)
761 {
762 _model = model;
763+ auto const& queue_draw_cb = sigc::hide(sigc::mem_fun(this, &Launcher::QueueDraw));
764
765- for (auto icon : *_model)
766- icon->needs_redraw.connect(sigc::mem_fun(this, &Launcher::OnIconNeedsRedraw));
767+ for (auto const& icon : *_model)
768+ icon->needs_redraw.connect(queue_draw_cb);
769
770 _model->icon_added.connect(sigc::mem_fun(this, &Launcher::OnIconAdded));
771 _model->icon_removed.connect(sigc::mem_fun(this, &Launcher::OnIconRemoved));
772- _model->order_changed.connect(sigc::mem_fun(this, &Launcher::OnOrderChanged));
773+ _model->order_changed.connect(sigc::mem_fun(this, &Launcher::QueueDraw));
774 _model->selection_changed.connect(sigc::mem_fun(this, &Launcher::OnSelectionChanged));
775 }
776
777@@ -1783,10 +1769,10 @@
778 if (icon == selection)
779 break;
780
781- natural_y += _icon_size + _space_between_icons;
782+ natural_y += _icon_size + SPACE_BETWEEN_ICONS;
783 }
784
785- int max_drag_delta = geo.height - (natural_y + _icon_size + (2 * _space_between_icons));
786+ int max_drag_delta = geo.height - (natural_y + _icon_size + (2 * SPACE_BETWEEN_ICONS));
787 int min_drag_delta = -natural_y;
788
789 _launcher_drag_delta = std::max<int>(min_drag_delta, std::min<int>(max_drag_delta, _launcher_drag_delta));
790@@ -1797,15 +1783,10 @@
791 if (IsInKeyNavMode())
792 {
793 EnsureIconOnScreen(selection);
794- EnsureAnimation();
795+ QueueDraw();
796 }
797 }
798
799-void Launcher::OnIconNeedsRedraw(AbstractLauncherIcon::Ptr const& icon)
800-{
801- EnsureAnimation();
802-}
803-
804 void Launcher::OnTooltipVisible(nux::ObjectPtr<nux::View> view)
805 {
806 _active_tooltip = view;
807@@ -1829,10 +1810,7 @@
808 {
809 auto idle = std::make_shared<glib::Idle>(glib::Source::Priority::DEFAULT);
810 sources_.Add(idle, ANIMATION_IDLE);
811- idle->Run([&]() {
812- EnsureAnimation();
813- return false;
814- });
815+ idle->Run([this]() { QueueDraw(); return false; });
816 }
817
818 nux::ROPConfig ROP;
819@@ -1843,9 +1821,9 @@
820 nux::Geometry const& geo_absolute = GetAbsoluteGeometry();
821 RenderArgs(args, bkg_box, &launcher_alpha, geo_absolute);
822 bkg_box.width -= RIGHT_LINE_WIDTH;
823-
824+
825 nux::Color clear_colour = nux::Color(0x00000000);
826-
827+
828 if (Settings::Instance().GetLowGfxMode())
829 {
830 clear_colour = options()->background_color;
831@@ -2047,7 +2025,7 @@
832 void Launcher::OnDragWindowAnimCompleted()
833 {
834 HideDragWindow();
835- EnsureAnimation();
836+ QueueDraw();
837 }
838
839 bool Launcher::StartIconDragTimeout(int x, int y)
840@@ -2086,7 +2064,7 @@
841 _drag_window->StartQuickAnimation();
842 }
843
844- EnsureAnimation();
845+ QueueDraw();
846 }
847 else
848 {
849@@ -2111,8 +2089,6 @@
850 auto cb = std::bind(&Launcher::RenderIconToTexture, this, _1, _2, _drag_icon);
851 _drag_window = new LauncherDragWindow(GetWidth(), cb);
852 ShowDragWindow();
853-
854- ubus_.SendMessage(UBUS_LAUNCHER_ICON_START_DND);
855 }
856
857 void Launcher::EndIconDrag()
858@@ -2131,7 +2107,7 @@
859 remove_request.emit(_drag_icon);
860
861 HideDragWindow();
862- EnsureAnimation();
863+ QueueDraw();
864 }
865 else
866 {
867@@ -2148,10 +2124,19 @@
868 }
869
870 if (MouseBeyondDragThreshold())
871- TimeUtil::SetTimeStruct(&_times[TIME_DRAG_THRESHOLD], &_times[TIME_DRAG_THRESHOLD], ANIM_DURATION_SHORT);
872+ {
873+ if (drag_icon_animation_.CurrentState() == na::Animation::State::Running)
874+ {
875+ if (drag_icon_animation_.GetFinishValue() != 1.0f)
876+ drag_icon_animation_.Reverse();
877+ }
878+ else
879+ {
880+ drag_icon_animation_.SetStartValue(0.0f).SetFinishValue(1.0f).Start();
881+ }
882+ }
883
884 _hide_machine.SetQuirk(LauncherHideMachine::INTERNAL_DND_ACTIVE, false);
885- ubus_.SendMessage(UBUS_LAUNCHER_ICON_END_DND);
886 }
887
888 void Launcher::ShowDragWindow()
889@@ -2172,6 +2157,7 @@
890 _model->ReorderBefore(_drag_icon, closer, true);
891
892 ResetMouseDragState();
893+ SetActionState(ACTION_DRAG_ICON_CANCELLED);
894 });
895 }
896
897@@ -2204,22 +2190,20 @@
898
899 auto const& launcher_geo = GetGeometry();
900 auto const& hovered_icon = MouseIconIntersection((launcher_geo.x + launcher_geo.width) / 2.0, y - GetAbsoluteY());
901- struct timespec current;
902- clock_gettime(CLOCK_MONOTONIC, &current);
903- float progress = DragThresholdProgress(current);
904+ bool mouse_beyond_drag_threshold = MouseBeyondDragThreshold();
905
906 if (hovered_icon && _drag_icon != hovered_icon)
907 {
908- if (progress >= 1.0f)
909+ if (!mouse_beyond_drag_threshold)
910 {
911 _model->ReorderSmart(_drag_icon, hovered_icon, true);
912 }
913- else if (progress == 0.0f)
914+ else
915 {
916 _model->ReorderBefore(_drag_icon, hovered_icon, false);
917 }
918 }
919- else if (!hovered_icon && progress == 0.0f)
920+ else if (!hovered_icon && mouse_beyond_drag_threshold)
921 {
922 // If no icon is hovered, then we can add our icon to the bottom
923 for (auto it = _model->main_rbegin(); it != _model->main_rend(); ++it)
924@@ -2250,7 +2234,6 @@
925 _dnd_delta_x = 0;
926 _dnd_delta_y = 0;
927 _last_button_press = 0;
928- EnsureAnimation();
929 }
930
931 void Launcher::RecvMouseDown(int x, int y, unsigned long button_flags, unsigned long key_flags)
932@@ -2259,7 +2242,6 @@
933 SetMousePosition(x, y);
934
935 MouseDownLogic(x, y, button_flags, key_flags);
936- EnsureAnimation();
937 }
938
939 void Launcher::RecvMouseUp(int x, int y, unsigned long button_flags, unsigned long key_flags)
940@@ -2314,7 +2296,6 @@
941 else if (GetActionState() == ACTION_DRAG_LAUNCHER)
942 {
943 _launcher_drag_delta += dy;
944- ubus_.SendMessage(UBUS_LAUNCHER_END_DND);
945 }
946 else if (GetActionState() == ACTION_DRAG_ICON)
947 {
948@@ -2322,23 +2303,20 @@
949 UpdateDragWindowPosition(geo.x + x, geo.y + y);
950 }
951
952- EnsureAnimation();
953+ QueueDraw();
954 }
955
956 void Launcher::RecvMouseEnter(int x, int y, unsigned long button_flags, unsigned long key_flags)
957 {
958 SetMousePosition(x, y);
959 SetStateMouseOverLauncher(true);
960-
961 EventLogic();
962- EnsureAnimation();
963 }
964
965 void Launcher::RecvMouseLeave(int x, int y, unsigned long button_flags, unsigned long key_flags)
966 {
967 SetStateMouseOverLauncher(false);
968 EventLogic();
969- EnsureAnimation();
970 }
971
972 void Launcher::RecvMouseMove(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags)
973@@ -2380,7 +2358,7 @@
974 // scroll up
975 _launcher_drag_delta += 25;
976
977- EnsureAnimation();
978+ QueueDraw();
979 }
980
981 #ifdef USE_X11
982@@ -2464,7 +2442,6 @@
983 _hide_machine.SetQuirk(LauncherHideMachine::QUICKLIST_OPEN, true);
984 _hover_machine.SetQuirk(LauncherHoverMachine::QUICKLIST_OPEN, true);
985 EventLogic();
986- EnsureAnimation();
987 }
988 }
989
990@@ -2484,7 +2461,6 @@
991 _hover_machine.SetQuirk(LauncherHoverMachine::QUICKLIST_OPEN, false);
992
993 EventLogic();
994- EnsureAnimation();
995 }
996
997 void Launcher::EventLogic()
998@@ -2542,7 +2518,7 @@
999
1000 if (GetActionState() == ACTION_DRAG_LAUNCHER)
1001 {
1002- TimeUtil::SetTimeStruct(&_times[TIME_DRAG_END]);
1003+ drag_over_animation_.SetStartValue(1.0f).SetFinishValue(0.0f).Start();
1004 }
1005
1006 _icon_mouse_down = nullptr;
1007@@ -2646,8 +2622,9 @@
1008 _drag_action = nux::DNDACTION_NONE;
1009 _steal_drag = false;
1010 _data_checked = false;
1011+ _dnd_hovered_icon = nullptr;
1012 _drag_edge_touching = false;
1013- _dnd_hovered_icon = nullptr;
1014+ dnd_hide_animation_.Stop();
1015 #endif
1016 }
1017
1018@@ -2682,7 +2659,6 @@
1019 void Launcher::DndHoveredIconReset()
1020 {
1021 #ifdef USE_X11
1022- _drag_edge_touching = false;
1023 SetActionState(ACTION_NONE);
1024
1025 if (_steal_drag && _dnd_hovered_icon)
1026@@ -2695,6 +2671,7 @@
1027 _dnd_hovered_icon->SendDndLeave();
1028
1029 _steal_drag = false;
1030+ _drag_edge_touching = false;
1031 _dnd_hovered_icon = nullptr;
1032 #endif
1033 }
1034@@ -2754,20 +2731,40 @@
1035
1036 SetMousePosition(x - _parent->GetGeometry().x, y - _parent->GetGeometry().y);
1037
1038- if (monitor() == 0 && !IsOverlayOpen() && _mouse_position.x == 0 && _mouse_position.y <= (_parent->GetGeometry().height - _icon_size - 2 * _space_between_icons) && !_drag_edge_touching)
1039- {
1040- if (_dnd_hovered_icon)
1041- _dnd_hovered_icon->SendDndLeave();
1042-
1043- _drag_edge_touching = true;
1044- TimeUtil::SetTimeStruct(&_times[TIME_DRAG_EDGE_TOUCH], &_times[TIME_DRAG_EDGE_TOUCH], ANIM_DURATION * 3);
1045- EnsureAnimation();
1046- }
1047- else if (_mouse_position.x != 0 && _drag_edge_touching)
1048- {
1049- _drag_edge_touching = false;
1050- TimeUtil::SetTimeStruct(&_times[TIME_DRAG_EDGE_TOUCH], &_times[TIME_DRAG_EDGE_TOUCH], ANIM_DURATION * 3);
1051- EnsureAnimation();
1052+ if (options()->hide_mode != LAUNCHER_HIDE_NEVER)
1053+ {
1054+ if (monitor() == 0 && !IsOverlayOpen() && _mouse_position.x == 0 && !_drag_edge_touching &&
1055+ _mouse_position.y <= (_parent->GetGeometry().height - _icon_size - 2 * SPACE_BETWEEN_ICONS))
1056+ {
1057+ if (_dnd_hovered_icon)
1058+ _dnd_hovered_icon->SendDndLeave();
1059+
1060+ if (dnd_hide_animation_.CurrentState() == na::Animation::State::Running)
1061+ {
1062+ if (dnd_hide_animation_.GetFinishValue() != 1.0f)
1063+ dnd_hide_animation_.Reverse();
1064+ }
1065+ else
1066+ {
1067+ dnd_hide_animation_.SetStartValue(0.0f).SetFinishValue(1.0f).Start();
1068+ }
1069+
1070+ _drag_edge_touching = true;
1071+ }
1072+ else if (_mouse_position.x != 0 && _drag_edge_touching)
1073+ {
1074+ if (dnd_hide_animation_.CurrentState() == na::Animation::State::Running)
1075+ {
1076+ if (dnd_hide_animation_.GetFinishValue() != 0.0f)
1077+ dnd_hide_animation_.Reverse();
1078+ }
1079+ else
1080+ {
1081+ dnd_hide_animation_.SetStartValue(1.0f).SetFinishValue(0.0f).Start();
1082+ }
1083+
1084+ _drag_edge_touching = false;
1085+ }
1086 }
1087
1088 EventLogic();
1089
1090=== modified file 'launcher/Launcher.h'
1091--- launcher/Launcher.h 2013-09-12 13:50:07 +0000
1092+++ launcher/Launcher.h 2013-09-16 17:01:30 +0000
1093@@ -70,7 +70,6 @@
1094
1095 Launcher(MockableBaseWindow* parent, NUX_FILE_LINE_PROTO);
1096
1097- nux::Property<Display*> display;
1098 nux::Property<int> monitor;
1099 nux::Property<Options::Ptr> options;
1100
1101@@ -180,24 +179,10 @@
1102 ACTION_NONE,
1103 ACTION_DRAG_LAUNCHER,
1104 ACTION_DRAG_ICON,
1105+ ACTION_DRAG_ICON_CANCELLED,
1106 ACTION_DRAG_EXTERNAL,
1107 } LauncherActionState;
1108
1109- typedef enum
1110- {
1111- TIME_ENTER,
1112- TIME_LEAVE,
1113- TIME_DRAG_END,
1114- TIME_DRAG_THRESHOLD,
1115- TIME_AUTOHIDE,
1116- TIME_DRAG_EDGE_TOUCH,
1117- TIME_DRAG_OUT,
1118- TIME_TAP_SUPER,
1119- TIME_SUPER_PRESSED,
1120-
1121- TIME_LAST
1122- } LauncherActionTimes;
1123-
1124 void ConfigureBarrier();
1125
1126 void OnMonitorChanged(int monitor);
1127@@ -244,20 +229,11 @@
1128 void SetActionState(LauncherActionState actionstate);
1129 LauncherActionState GetActionState() const;
1130
1131- void EnsureAnimation();
1132 void EnsureScrollTimer();
1133-
1134 bool MouseOverTopScrollArea();
1135-
1136 bool MouseOverBottomScrollArea();
1137
1138- float DnDStartProgress(struct timespec const& current) const;
1139- float DnDExitProgress(struct timespec const& current) const;
1140- float GetHoverProgress(struct timespec const& current) const;
1141- float AutohideProgress(struct timespec const& current) const;
1142- float DragThresholdProgress(struct timespec const& current) const;
1143- float DragHideProgress(struct timespec const& current) const;
1144- float DragOutProgress(struct timespec const& current) const;
1145+ float DragOutProgress() const;
1146 float IconDesatValue(AbstractLauncherIcon::Ptr const& icon, struct timespec const& current) const;
1147 float IconPresentProgress(AbstractLauncherIcon::Ptr const& icon, struct timespec const& current) const;
1148 float IconUnfoldProgress(AbstractLauncherIcon::Ptr const& icon, struct timespec const& current) const;
1149@@ -299,9 +275,7 @@
1150
1151 void OnIconAdded(AbstractLauncherIcon::Ptr const& icon);
1152 void OnIconRemoved(AbstractLauncherIcon::Ptr const& icon);
1153- void OnOrderChanged();
1154
1155- void OnIconNeedsRedraw(AbstractLauncherIcon::Ptr const& icon);
1156 void OnTooltipVisible(nux::ObjectPtr<nux::View> view);
1157
1158 void OnOverlayHidden(GVariant* data);
1159@@ -344,8 +318,6 @@
1160 nux::ObjectPtr<nux::View> _active_tooltip;
1161 QuicklistView* _active_quicklist;
1162
1163- nux::HLayout* m_Layout;
1164-
1165 // used by keyboard/a11y-navigation
1166 AbstractLauncherIcon::Ptr _icon_under_mouse;
1167 AbstractLauncherIcon::Ptr _icon_mouse_down;
1168@@ -362,18 +334,10 @@
1169 bool _initial_drag_animation;
1170 bool _dash_is_open;
1171 bool _hud_is_open;
1172-
1173- float _folded_angle;
1174- float _neg_folded_angle;
1175- float _folded_z_distance;
1176- float _edge_overcome_pressure;
1177+ bool _folded;
1178
1179 LauncherActionState _launcher_action_state;
1180
1181- int _space_between_icons;
1182- int _icon_image_size;
1183- int _icon_image_size_delta;
1184- int _icon_glow_size;
1185 int _icon_size;
1186 int _dnd_delta_y;
1187 int _dnd_delta_x;
1188@@ -393,7 +357,7 @@
1189 bool _drag_gesture_ongoing;
1190 float _last_reveal_progress;
1191
1192- nux::Point2 _mouse_position;
1193+ nux::Point _mouse_position;
1194 LauncherDragWindow::Ptr _drag_window;
1195 LauncherHideMachine _hide_machine;
1196 LauncherHoverMachine _hover_machine;
1197@@ -402,14 +366,19 @@
1198 unity::DndData _dnd_data;
1199 nux::DndAction _drag_action;
1200 Atom _selection_atom;
1201-
1202- struct timespec _times[TIME_LAST];
1203 struct timespec _urgent_finished_time;
1204
1205 BaseTexturePtr launcher_sheen_;
1206 BaseTexturePtr launcher_pressure_effect_;
1207
1208- nux::animation::AnimateValue<double> dash_showing_animation_;
1209+ nux::animation::AnimateValue<float> auto_hide_animation_;
1210+ nux::animation::AnimateValue<float> hover_animation_;
1211+ nux::animation::AnimateValue<float> drag_over_animation_;
1212+ nux::animation::AnimateValue<float> drag_out_animation_;
1213+ nux::animation::AnimateValue<float> drag_icon_animation_;
1214+ nux::animation::AnimateValue<float> dnd_hide_animation_;
1215+ nux::animation::AnimateValue<float> dash_showing_animation_;
1216+
1217 ui::AbstractIconRenderer::Ptr icon_renderer;
1218 BackgroundEffectHelper bg_effect_helper_;
1219
1220
1221=== modified file 'plugins/unityshell/src/unityshell.cpp'
1222--- plugins/unityshell/src/unityshell.cpp 2013-09-12 03:12:04 +0000
1223+++ plugins/unityshell/src/unityshell.cpp 2013-09-16 17:01:30 +0000
1224@@ -2979,11 +2979,11 @@
1225
1226 for (auto const& launcher : launchers)
1227 {
1228- nux::Geometry geo = launcher->GetAbsoluteGeometry();
1229-
1230 if (launcher->options()->hide_mode == LAUNCHER_HIDE_AUTOHIDE && launcher->Hidden())
1231 continue;
1232
1233+ auto const& geo = launcher->GetAbsoluteGeometry();
1234+
1235 if (geo.IsInside(result))
1236 {
1237 if (geo.x + geo.width + 1 + window_geo.width() < target_monitor.x + target_monitor.width)
1238
1239=== modified file 'tests/test_launcher.cpp'
1240--- tests/test_launcher.cpp 2013-09-11 13:27:17 +0000
1241+++ tests/test_launcher.cpp 2013-09-16 17:01:30 +0000
1242@@ -77,6 +77,11 @@
1243 return GetActionState() == Launcher::LauncherActionState::ACTION_DRAG_EXTERNAL;
1244 }
1245
1246+ bool IsActionStateDragCancelled()
1247+ {
1248+ return GetActionState() == Launcher::LauncherActionState::ACTION_DRAG_ICON_CANCELLED;
1249+ }
1250+
1251 AbstractLauncherIcon::Ptr MouseIconIntersection(int x, int y) const
1252 {
1253 for (auto const& icon : *_model)
1254@@ -318,6 +323,7 @@
1255
1256 // Emitting the drag cancel request
1257 launcher_->GetDraggedIcon()->drag_cancel_request.emit();
1258+ EXPECT_TRUE(launcher_->IsActionStateDragCancelled());
1259
1260 // The icon order should be reset
1261 it = model_->begin();
1262
1263=== modified file 'unity-shared/UBusMessages.h'
1264--- unity-shared/UBusMessages.h 2013-03-19 18:47:01 +0000
1265+++ unity-shared/UBusMessages.h 2013-09-16 17:01:30 +0000
1266@@ -51,12 +51,6 @@
1267 #define UBUS_QUICKLIST_START_KEY_NAV "QUICKLIST_START_KEY_NAV"
1268 #define UBUS_QUICKLIST_END_KEY_NAV "QUICKLIST_END_KEY_NAV"
1269
1270-// Signals that fired on various launcher dnd tasks
1271-#define UBUS_LAUNCHER_START_DND "LAUNCHER_START_DRAG"
1272-#define UBUS_LAUNCHER_END_DND "LAUNCHER_END_DRAG"
1273-#define UBUS_LAUNCHER_ICON_START_DND "LAUNCHER_ICON_START_DND"
1274-#define UBUS_LAUNCHER_ICON_END_DND "LAUNCHER_ICON_END_DND"
1275-
1276 // Signal to force the launcher into locked mode, (b)
1277 #define UBUS_LAUNCHER_LOCK_HIDE "LAUNCHER_LOCK_HIDE"
1278