Merge lp:~sil2100/unity/fix_draging_last_position_out_of_launcher_5.0 into lp:unity/5.0

Proposed by Łukasz Zemczak
Status: Merged
Approved by: Marco Trevisan (Treviño)
Approved revision: no longer in the source branch.
Merged at revision: 2365
Proposed branch: lp:~sil2100/unity/fix_draging_last_position_out_of_launcher_5.0
Merge into: lp:unity/5.0
Diff against target: 227 lines (+164/-2)
3 files modified
plugins/unityshell/src/Launcher.cpp (+30/-2)
tests/autopilot/autopilot/emulators/unity/launcher.py (+78/-0)
tests/autopilot/autopilot/tests/test_launcher.py (+56/-0)
To merge this branch: bzr merge lp:~sil2100/unity/fix_draging_last_position_out_of_launcher_5.0
Reviewer Review Type Date Requested Status
Marco Trevisan (Treviño) Approve
Review via email: mp+110855@code.launchpad.net

Commit message

Cherry-picked from unity trunk (rev2407):
Launcher: Fix dragging to the last position when out of the launcher

Description of the change

Cherry-picked from upstream. Original description:

Launcher: Fix dragging to the last position when out of the launcher

Without this patch there is the following bug:
 * Have a launcher with free space under the workspace switcher
 * Start dragging a tile from the launcher
 * Move it outside (to the right) of the launcher
 * See how a horizontal bar shows where the icon will land once you release the mouse button
 * Move the mouse down so the horizontal bar should go just before the worspace switcher
 * See that it doesn't go there, it keeps itself one icon before that

With this patch this behaviour is fixed

To post a comment you must log in.
Revision history for this message
Marco Trevisan (Treviño) (3v1n0) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'plugins/unityshell/src/Launcher.cpp'
2--- plugins/unityshell/src/Launcher.cpp 2012-06-06 09:25:29 +0000
3+++ plugins/unityshell/src/Launcher.cpp 2012-06-18 16:32:24 +0000
4@@ -2272,8 +2272,36 @@
5
6 if (progress >= 1.0f)
7 _model->ReorderSmart(_drag_icon, hovered_icon, true);
8- else if (progress == 0.0f)
9- _model->ReorderBefore(_drag_icon, hovered_icon, false);
10+ else if (progress == 0.0f) {
11+ if (_drag_icon->GetIconType() == hovered_icon->GetIconType()) {
12+ _model->ReorderBefore(_drag_icon, hovered_icon, false);
13+ } else {
14+ // LauncherModel::ReorderBefore does not work on different icon types
15+ // so if hovered_icon is of a different type than _drag_icon
16+ // try to use LauncherModel::ReorderAfter with the icon that is before hovered_icon
17+ AbstractLauncherIcon::Ptr iconBeforeHover;
18+ LauncherModel::iterator it;
19+ LauncherModel::iterator prevIt = _model->end();
20+ for (it = _model->begin(); it != _model->end(); it++)
21+ {
22+ if (!(*it)->GetQuirk(AbstractLauncherIcon::QUIRK_VISIBLE) || !(*it)->IsVisibleOnMonitor(monitor))
23+ continue;
24+
25+ if ((*it) == hovered_icon) {
26+ if (prevIt != _model->end()) {
27+ iconBeforeHover = *prevIt;
28+ }
29+ break;
30+ }
31+
32+ prevIt = it;
33+ }
34+
35+ if (iconBeforeHover && _drag_icon != iconBeforeHover) {
36+ _model->ReorderAfter(_drag_icon, iconBeforeHover);
37+ }
38+ }
39+ }
40 }
41 }
42 }
43
44=== modified file 'tests/autopilot/autopilot/emulators/unity/launcher.py'
45--- tests/autopilot/autopilot/emulators/unity/launcher.py 2012-05-21 15:29:34 +0000
46+++ tests/autopilot/autopilot/emulators/unity/launcher.py 2012-06-18 16:32:24 +0000
47@@ -7,8 +7,10 @@
48 # by the Free Software Foundation.
49 #
50
51+from autopilot.utilities import get_compiz_option
52 import dbus
53 import logging
54+from math import floor
55 from testtools.matchers import NotEquals
56 from time import sleep
57
58@@ -22,6 +24,12 @@
59 logger = logging.getLogger(__name__)
60
61
62+class IconDragType:
63+ """Define possible positions to drag an icon onto another"""
64+ INSIDE = 0
65+ OUTSIDE = 1
66+
67+
68 class LauncherController(UnityIntrospectionObject):
69 """The LauncherController class."""
70
71@@ -116,6 +124,16 @@
72 logger.debug("Moving mouse to center of launcher.")
73 self._mouse.move(target_x, target_y)
74
75+ def move_mouse_to_icon(self, icon):
76+ # The icon may be off the bottom of screen, so we do this in a loop:
77+ while 1:
78+ target_x = icon.center_x + self.x
79+ target_y = icon.center_y
80+ if self._mouse.x == target_x and self._mouse.y == target_y:
81+ break
82+ self._mouse.move(target_x, target_y)
83+ sleep(0.5)
84+
85 def mouse_reveal_launcher(self):
86 """Reveal this launcher with the mouse."""
87 self._screen.move_mouse_to_monitor(self.monitor)
88@@ -246,6 +264,66 @@
89 self._mouse.click(button)
90 self.move_mouse_to_right_of_launcher()
91
92+ def drag_icon_to_position(self, icon, pos, drag_type=IconDragType.INSIDE):
93+ """Place the supplied icon above the icon in the position pos.
94+
95+ The icon is dragged inside or outside the launcher.
96+
97+ >>> drag_icon_to_position(calc_icon, 0, IconDragType.INSIDE)
98+
99+ This will drag the calculator icon above the bfb (but as you can't go
100+ above the bfb it will move below it (to position 1))
101+
102+ """
103+ if not isinstance(icon, BamfLauncherIcon):
104+ raise TypeError("icon must be a LauncherIcon")
105+
106+ [launcher_model] = LauncherModel.get_all_instances()
107+ all_icons = launcher_model.get_launcher_icons()
108+ all_icon_len = len(all_icons)
109+ if pos >= all_icon_len:
110+ raise ValueError("pos is outside valid range (0-%d)" % all_icon_len)
111+
112+ logger.debug("Dragging launcher icon %r on monitor %d to position %s"
113+ % (icon, self.monitor, pos))
114+ self.mouse_reveal_launcher()
115+
116+ icon_height = get_compiz_option("unityshell", "icon_size")
117+
118+ target_icon = all_icons[pos]
119+ if target_icon.id == icon.id:
120+ logger.warning("%s is already the icon in position %d. Nothing to do." % (icon, pos))
121+ return
122+
123+ self.move_mouse_to_icon(icon)
124+ self._mouse.press()
125+ sleep(2)
126+
127+ if drag_type == IconDragType.OUTSIDE:
128+ shift_over = self._mouse.x + (icon_height * 2)
129+ self._mouse.move(shift_over, self._mouse.y)
130+ sleep(0.5)
131+
132+ # find the target drop position, between the center & top of the target icon
133+ target_y = target_icon.center_y - floor(icon_height / 4)
134+
135+ # Need to move the icons top (if moving up) or bottom (if moving
136+ # downward) to the target position
137+ moving_up = True if icon.center_y > target_icon.center_y else False
138+ icon_half_height = floor(icon_height / 2)
139+ fudge_factor = 5
140+ if moving_up or drag_type == IconDragType.OUTSIDE:
141+ target_y += icon_half_height + fudge_factor
142+ else:
143+ target_y -= icon_half_height - fudge_factor
144+
145+ self._mouse.move(self._mouse.x, target_y, rate=20,
146+ time_between_events=0.05)
147+ sleep(1)
148+
149+ self._mouse.release()
150+ self.move_mouse_to_right_of_launcher()
151+
152 def lock_to_launcher(self, icon):
153 """lock 'icon' to the launcher, if it's not already.
154 `icon` must be an instance of BamfLauncherIcon.
155
156=== modified file 'tests/autopilot/autopilot/tests/test_launcher.py'
157--- tests/autopilot/autopilot/tests/test_launcher.py 2012-05-23 12:13:10 +0000
158+++ tests/autopilot/autopilot/tests/test_launcher.py 2012-06-18 16:32:24 +0000
159@@ -18,6 +18,7 @@
160 from autopilot.emulators.X11 import ScreenGeometry
161 from autopilot.matchers import Eventually
162 from autopilot.tests import AutopilotTestCase, multiply_scenarios
163+from unity.emulators.launcher import IconDragType
164
165 logger = logging.getLogger(__name__)
166
167@@ -460,6 +461,61 @@
168 self.assertThat(calc_icon, NotEquals(None))
169 self.assertThat(calc_icon.visible, Eventually(Equals(True)))
170
171+class LauncherDragIconsBehavior(LauncherTestCase):
172+ """Tests interation with dragging icons with the Launcher"""
173+
174+ scenarios = multiply_scenarios(_make_scenarios(),
175+ [
176+ ('inside', {'drag_type': IconDragType.INSIDE}),
177+ ('outside', {'drag_type': IconDragType.OUTSIDE}),
178+ ])
179+
180+ def ensure_calc_icon_not_in_launcher(self):
181+ while 1:
182+ icon = self.launcher.model.get_icon_by_desktop_id("gcalctool.desktop")
183+ if not icon:
184+ break
185+ sleep(1)
186+
187+ def test_can_drag_icon_below_bfb(self):
188+ """Application icons must be draggable to below the BFB."""
189+
190+ self.ensure_calc_icon_not_in_launcher()
191+ calc = self.start_app("Calculator")
192+ calc_icon = self.launcher.model.get_icon_by_desktop_id(calc.desktop_file)
193+
194+ bfb_icon_position = 0
195+ self.launcher_instance.drag_icon_to_position(calc_icon,
196+ bfb_icon_position,
197+ self.drag_type)
198+ moved_icon = self.launcher.model.\
199+ get_launcher_icons_for_monitor(self.launcher_monitor)[1]
200+ self.assertThat(moved_icon.id, Equals(calc_icon.id))
201+
202+ def test_can_drag_icon_above_window_switcher(self):
203+ """Launcher icons must be dragable to above the workspace switcher icon."""
204+
205+ self.ensure_calc_icon_not_in_launcher()
206+ calc = self.start_app("Calculator")
207+ calc_icon = self.launcher.model.get_icon_by_desktop_id(calc.desktop_file)
208+
209+ # Move a known icon to the top as it needs to be more than 2 icon
210+ # spaces away for this test to actually do anything
211+ bfb_icon_position = 0
212+ self.launcher_instance.drag_icon_to_position(calc_icon,
213+ bfb_icon_position,
214+ self.drag_type)
215+ sleep(1)
216+ switcher_pos = -2
217+ self.launcher_instance.drag_icon_to_position(calc_icon,
218+ switcher_pos,
219+ self.drag_type)
220+
221+ moved_icon = self.launcher.model.\
222+ get_launcher_icons_for_monitor(self.launcher_monitor)[-3]
223+ self.assertThat(moved_icon.id, Equals(calc_icon.id))
224+
225+
226 class LauncherRevealTests(LauncherTestCase):
227 """Test the launcher reveal behavior when in autohide mode."""
228

Subscribers

People subscribed via source and target branches

to all changes: