Merge lp:~mzanetti/unity8/launcher-improve-flicking-behavior into lp:unity8

Proposed by Michael Zanetti
Status: Merged
Approved by: MichaƂ Sawicz
Approved revision: 77
Merged at revision: 80
Proposed branch: lp:~mzanetti/unity8/launcher-improve-flicking-behavior
Merge into: lp:unity8
Diff against target: 319 lines (+143/-52)
3 files modified
Launcher/LauncherDelegate.qml (+0/-1)
Launcher/LauncherPanel.qml (+26/-14)
tests/qmltests/Launcher/tst_Launcher.qml (+117/-37)
To merge this branch: bzr merge lp:~mzanetti/unity8/launcher-improve-flicking-behavior
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Albert Astals Cid (community) Approve
Review via email: mp+172648@code.launchpad.net

Commit message

improve launcher flicking bahavior

- fix initial snapping
- improve foldingAreas behavior
- increase clickFlick speed to flick 4 items

To post a comment you must log in.
Revision history for this message
Michael Zanetti (mzanetti) wrote :

improving/changing flick behavior to reflect feedback from design.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Albert Astals Cid (aacid) wrote :

As discussed on IRC it'd be great if the comment of why a Timer is needed is improved and also to have a test that fails when the Timer is not there

review: Needs Fixing
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Albert Astals Cid (aacid) wrote :

Looks good to me (that have the fix for 32251 :D)

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) :
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/LauncherDelegate.qml'
2--- Launcher/LauncherDelegate.qml 2013-06-26 14:21:39 +0000
3+++ Launcher/LauncherDelegate.qml 2013-07-05 09:05:30 +0000
4@@ -65,7 +65,6 @@
5 onClicked: root.clicked()
6 onCanceled: root.released()
7 preventStealing: false
8- enabled: root.angle < 5
9
10 onPressAndHold: {
11 root.state = "moving"
12
13=== modified file 'Launcher/LauncherPanel.qml'
14--- Launcher/LauncherPanel.qml 2013-06-25 13:25:45 +0000
15+++ Launcher/LauncherPanel.qml 2013-07-05 09:05:30 +0000
16@@ -100,6 +100,7 @@
17 height: parent.height - dashItem.height - parent.spacing*2
18 ListView {
19 id: launcherListView
20+ objectName: "launcherListView"
21 anchors.fill: parent
22 anchors.topMargin: -itemSize
23 anchors.bottomMargin: -itemSize
24@@ -116,15 +117,7 @@
25 // The height of the area where icons start getting folded
26 property int foldingAreaHeight: itemSize * 0.75
27 property int itemSize: width
28-
29- Component.onCompleted: {
30- // This is needed because snapping would partially fold
31- // the first item on initialisation. This can only be
32- // overridden by mouse interactions - which is what flick()
33- // simulates. Setting contentY to 0 would not work because
34- // of this.
35- flick(0, units.gu(20))
36- }
37+ property int clickFlickSpeed: units.gu(60)
38
39 delegate: LauncherDelegate {
40 id: launcherDelegate
41@@ -139,7 +132,26 @@
42 maxAngle: 60
43
44 onClicked: {
45- root.applicationSelected(launcherModel.get(index).desktopFile);
46+ // First/last item do the scrolling at more than 12 degrees
47+ if (index == 0 || index == launcherListView.count -1) {
48+ if (angle > 12) {
49+ launcherListView.flick(0, -launcherListView.clickFlickSpeed);
50+ } else if (angle < -12) {
51+ launcherListView.flick(0, launcherListView.clickFlickSpeed);
52+ } else {
53+ root.applicationSelected(launcherModel.get(index).desktopFile);
54+ }
55+ return;
56+ }
57+
58+ // the rest launches apps up to an angle of 30 degrees
59+ if (angle > 30) {
60+ launcherListView.flick(0, -launcherListView.clickFlickSpeed);
61+ } else if (angle < -30) {
62+ launcherListView.flick(0, launcherListView.clickFlickSpeed);
63+ } else {
64+ root.applicationSelected(launcherModel.get(index).desktopFile);
65+ }
66 }
67 }
68
69@@ -151,9 +163,9 @@
70 top: parent.top
71 topMargin: launcherListView.topMargin
72 }
73- height: launcherListView.itemSize
74+ height: launcherListView.itemSize / 2
75 enabled: launcherListView.contentY > -launcherListView.topMargin
76- onClicked: launcherListView.flick(0, units.gu(40))
77+ onClicked: launcherListView.flick(0, launcherListView.clickFlickSpeed)
78 }
79
80 MouseArea {
81@@ -164,9 +176,9 @@
82 bottom: parent.bottom
83 bottomMargin: launcherListView.bottomMargin
84 }
85- height: launcherListView.itemSize
86+ height: launcherListView.itemSize / 2
87 enabled: launcherListView.contentHeight - launcherListView.height - launcherListView.contentY > -launcherListView.bottomMargin
88- onClicked: launcherListView.flick(0, -units.gu(40))
89+ onClicked: launcherListView.flick(0, -launcherListView.clickFlickSpeed)
90 }
91 }
92 }
93
94=== modified file 'tests/qmltests/Launcher/tst_Launcher.qml'
95--- tests/qmltests/Launcher/tst_Launcher.qml 2013-06-28 16:35:24 +0000
96+++ tests/qmltests/Launcher/tst_Launcher.qml 2013-07-05 09:05:30 +0000
97@@ -23,20 +23,21 @@
98 /* Nothing is shown at first. If you drag from left edge you will bring up the
99 launcher. */
100 Item {
101+ id: root
102 width: units.gu(50)
103- height: units.gu(81)
104+ height: units.gu(55)
105
106 Launcher {
107 id: launcher
108 x: 0
109 y: 0
110 width: units.gu(40)
111- height: units.gu(81)
112+ height: parent.height
113
114- property string latestApplicationSelected
115+ property string lastSelectedApplication
116
117 onLauncherApplicationSelected: {
118- latestApplicationSelected = desktopFile
119+ lastSelectedApplication = desktopFile
120 }
121
122 property int dashItemSelected_count: 0
123@@ -58,9 +59,33 @@
124 }
125
126 UT.UnityTestCase {
127+ id: revealer
128+
129+ function dragLauncherIntoView() {
130+ var startX = launcher.dragAreaWidth/2;
131+ var startY = launcher.height/2;
132+ touchFlick(launcher,
133+ startX, startY,
134+ startX+units.gu(8), startY);
135+
136+ var panel = findChild(launcher, "launcherPanel");
137+ verify(panel != undefined);
138+
139+ // wait until it gets fully extended
140+ tryCompare(panel, "x", 0);
141+ tryCompare(launcher, "state", "visible");
142+ }
143+
144+ function waitUntilLauncherDisappears() {
145+ var panel = findChild(launcher, "launcherPanel");
146+ tryCompare(panel, "x", -panel.width, 1000);
147+ }
148+ }
149+
150+ UT.UnityTestCase {
151 id: testCase
152 name: "Launcher"
153- when: windowShown
154+ when: windowShown && initTestCase.completed
155
156 // Drag from the left edge of the screen rightwards and check that the launcher
157 // appears (as if being dragged by the finger/pointer)
158@@ -71,7 +96,7 @@
159 // it starts out hidden just left of the left launcher edge
160 compare(panel.x, -panel.width)
161
162- dragLauncherIntoView()
163+ revealer.dragLauncherIntoView()
164
165 // tapping on the center of the screen should dismiss the launcher
166 mouseClick(launcher, launcher.width/2, launcher.height/2)
167@@ -85,20 +110,25 @@
168 corresponding desktop file. E.g. clicking on phone icon should yield
169 launcherApplicationSelected("[...]phone-app.desktop") */
170 function test_clickingOnAppIconCausesSignalEmission() {
171- launcher.latestApplicationSelected = ""
172-
173- dragLauncherIntoView()
174+ launcher.lastSelectedApplication = ""
175+
176+ revealer.dragLauncherIntoView()
177+
178+ var listView = findChild(launcher, "launcherListView");
179+ listView.flick(0, units.gu(500));
180+ tryCompare(listView, "flicking", false);
181
182 var appIcon = findChild(launcher, "launcherDelegate0")
183+
184 verify(appIcon != undefined)
185
186 mouseClick(appIcon, appIcon.width/2, appIcon.height/2)
187
188- tryCompare(launcher, "latestApplicationSelected",
189+ tryCompare(launcher, "lastSelectedApplication",
190 "/usr/share/applications/phone-app.desktop")
191
192 // Tapping on an application icon also dismisses the launcher
193- waitUntilLauncherDisappears()
194+ revealer.waitUntilLauncherDisappears()
195 }
196
197 /* If I click on the dash icon on the launcher
198@@ -106,7 +136,7 @@
199 function test_clickingOnDashIconCausesSignalEmission() {
200 launcher.dashItemSelected_count = 0
201
202- dragLauncherIntoView()
203+ revealer.dragLauncherIntoView()
204
205 var dashIcon = findChild(launcher, "dashItem")
206 verify(dashIcon != undefined)
207@@ -116,29 +146,8 @@
208 tryCompare(launcher, "dashItemSelected_count", 1)
209
210 // Tapping on the dash icon also dismisses the launcher
211- waitUntilLauncherDisappears()
212- }
213-
214- function dragLauncherIntoView() {
215- var startX = launcher.dragAreaWidth/2
216- var startY = launcher.height/2
217- touchFlick(launcher,
218- startX, startY,
219- startX+units.gu(8), startY)
220-
221- var panel = findChild(launcher, "launcherPanel")
222- verify(panel != undefined)
223-
224- // wait until it gets fully extended
225- tryCompare(panel, "x", 0)
226- tryCompare(launcher, "state", "visible")
227- }
228-
229- function waitUntilLauncherDisappears() {
230- var panel = findChild(launcher, "launcherPanel")
231- tryCompare(panel, "x", -panel.width, 1000)
232- }
233-
234+ revealer.waitUntilLauncherDisappears()
235+ }
236
237 function test_teaseLauncher_data() {
238 return [
239@@ -164,7 +173,78 @@
240 wait(100)
241 compare(launcher.maxPanelX, -launcher.panelWidth, "Launcher moved even if it shouldn't")
242 }
243- waitUntilLauncherDisappears();
244- }
245+ revealer.waitUntilLauncherDisappears();
246+ launcher.available = true;
247+ }
248+ }
249+
250+ UT.UnityTestCase {
251+ id: clickFlickTestCase
252+ when: windowShown && testCase.completed
253+
254+ function test_clickFlick_data() {
255+ var listView = findChild(launcher, "launcherListView");
256+ return [
257+ {tag: "unfolded top", flickSpeed: units.gu(200), clickY: listView.topMargin + units.gu(2), expectFlick: false},
258+ {tag: "folded top", flickSpeed: -units.gu(200), clickY: listView.topMargin + units.gu(2), expectFlick: true},
259+ {tag: "unfolded bottom", flickSpeed: -units.gu(200), clickY: listView.height - listView.topMargin - units.gu(1), expectFlick: false},
260+ {tag: "folded bottom", flickSpeed: units.gu(200), clickY: listView.height - listView.topMargin - units.gu(1), expectFlick: true},
261+ ];
262+ }
263+
264+ function test_clickFlick(data) {
265+ launcher.lastSelectedApplication = "";
266+ revealer.dragLauncherIntoView();
267+ var listView = findChild(launcher, "launcherListView");
268+
269+ listView.flick(0, data.flickSpeed);
270+ tryCompare(listView, "flicking", false);
271+
272+ var oldY = listView.contentY;
273+
274+ mouseClick(listView, listView.width / 2, data.clickY);
275+ tryCompare(listView, "flicking", false);
276+
277+ if (data.expectFlick) {
278+ verify(listView.contentY != oldY);
279+ compare(launcher.lastSelectedApplication, "", "Launcher app clicked signal emitted even though it should only flick");
280+ } else {
281+ verify(launcher.lastSelectedApplication != "");
282+ compare(listView.contentY, oldY, "Launcher was flicked even though it should only launch an app");
283+ }
284+
285+ // Restore position on top
286+ listView.flick(0, units.gu(200));
287+ tryCompare(listView, "flicking", false)
288+ // Click somewhere in the empty space to make it hide in case it isn't
289+ mouseClick(launcher, launcher.width - units.gu(1), units.gu(1));
290+ revealer.waitUntilLauncherDisappears();
291+ }
292+ }
293+
294+ UT.UnityTestCase {
295+ id: initTestCase
296+ name: "LauncherInit"
297+ when: windowShown
298+
299+ /*
300+ * FIXME: There is a bug in ListView which makes it snap to an item
301+ * instead of the edge at startup. Enable this test once our patch for
302+ * ListView has landed upstream.
303+ * https://bugreports.qt-project.org/browse/QTBUG-32251
304+
305+ function test_initFirstUnfolded() {
306+
307+ // Make sure noone changed the height of the window. The issue this test case
308+ // is verifying only happens on certain heights of the Launcher
309+ compare(root.height, units.gu(55));
310+
311+ var listView = findChild(launcher, "launcherListView");
312+ compare(listView.contentY, -listView.topMargin, "Launcher did not start up with first item unfolded");
313+
314+ // Now do check that snapping is in fact enabled
315+ compare(listView.snapMode, ListView.SnapToItem, "Snapping is not enabled");
316+ }
317+ */
318 }
319 }

Subscribers

People subscribed via source and target branches