Merge lp:~aacid/unity8/dash_ranges_on_move into lp:unity8

Proposed by Albert Astals Cid on 2015-01-13
Status: Merged
Approved by: Michał Sawicz on 2015-01-13
Approved revision: 1546
Merged at revision: 1552
Proposed branch: lp:~aacid/unity8/dash_ranges_on_move
Merge into: lp:unity8
Diff against target: 160 lines (+99/-2)
3 files modified
qml/Dash/GenericScopeView.qml (+30/-2)
tests/qmltests/Dash/tst_DashContent.qml (+57/-0)
tests/utils/modules/Unity/Test/UnityTestCase.qml (+12/-0)
To merge this branch: bzr merge lp:~aacid/unity8/dash_ranges_on_move
Reviewer Review Type Date Requested Status
PS Jenkins bot continuous-integration Needs Fixing on 2015-01-13
Michał Sawicz 2015-01-13 Approve on 2015-01-13
Review via email: mp+246286@code.launchpad.net

Commit Message

Make sure changing a scope doesn't trigger creation/destruction of delegates until it's finished

Description of the Change

 * Are there any related MPs required for this MP to build/function as expected?
No

 * Did you perform an exploratory manual test run of your code change and any related functionality?
Yes

 * Did you make sure that your branch does not contain spurious tags?
Yes

 * If you changed the packaging (debian), did you subscribe the ubuntu-unity team to this MP?
N/A

 * If you changed the UI, has there been a design review?
N/A

To post a comment you must log in.
Michał Sawicz (saviq) wrote :

This test fails for me:

119 + verify(compareArrays(buttons2, buttons));

I've looked at the arrays and buttons kept about twice (~1200) as many items as buttons2 (~600).

It seems like a timing issue - i.e. we're creating too many items on startup?

review: Needs Fixing
Michał Sawicz (saviq) wrote :

Testing this manually (patched a live phone) and this doesn't seem to be doing what it advertises. I added some debug lines in onCompleted and onDestruction and I'm still getting a lot of those when switching scopes to the sides (and I can see stuttering, too).

What's also interesting is that I've seen at least a few destructions on startup, which we should avoid if at all possible.

Michał Sawicz (saviq) wrote :

OK there was some misunderstanding, it does indeed keep the margins and caches static *while* swiping. The creations I was seeing were due to the plugin querying next-to-adjacent scopes.

This does, however, fix the case when all the scopes are already loaded and you're swiping between them.

review: Approve
Michał Sawicz (saviq) wrote :

 * Did you perform an exploratory manual test run of the code change and any related functionality?
Y
 * Did CI run pass? If not, please explain why.
N, unstable tests :/
 * Did you make sure that the branch does not contain spurious tags?
Y

review: Approve
lp:~aacid/unity8/dash_ranges_on_move updated on 2015-01-13
1546. By Albert Astals Cid on 2015-01-13

Increase the busy loop a bit

Busy loops are nasty, but can't think of another way to test this at the moment

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'qml/Dash/GenericScopeView.qml'
2--- qml/Dash/GenericScopeView.qml 2015-01-09 10:40:33 +0000
3+++ qml/Dash/GenericScopeView.qml 2015-01-13 14:37:22 +0000
4@@ -41,6 +41,7 @@
5 property bool visibleToParent: false
6 property alias pageHeaderTotallyVisible: categoryView.pageHeaderTotallyVisible
7 property var holdingList: null
8+ property bool wasCurrentOnMoveStart: false
9
10 property var scopeStyle: ScopeStyle {
11 style: scope ? scope.customizations : {}
12@@ -116,6 +117,9 @@
13 }
14
15 onIsCurrentChanged: {
16+ if (!holdingList || !holdingList.moving) {
17+ wasCurrentOnMoveStart = scopeView.isCurrent;
18+ }
19 if (pageHeaderLoader.item && showPageHeader) {
20 pageHeaderLoader.item.resetSearch();
21 }
22@@ -142,6 +146,15 @@
23 onHideDash: subPageLoader.closeSubPage()
24 }
25
26+ Connections {
27+ target: holdingList
28+ onMovingChanged: {
29+ if (!moving) {
30+ wasCurrentOnMoveStart = scopeView.isCurrent;
31+ }
32+ }
33+ }
34+
35 Rectangle {
36 anchors.fill: parent
37 color: scopeView.scopeStyle ? scopeView.scopeStyle.background : "transparent"
38@@ -367,7 +380,11 @@
39
40 function updateRanges() {
41 // Don't want to create stress by requesting more items during scope
42- // changes so unless you're not part of the visible scopes just return
43+ // changes so unless you're not part of the visible scopes just return.
44+ // For the visible scopes we need to do some work, the previously non visible
45+ // scope needs to adjust its ranges so that we define the new visible range,
46+ // that still means no creation/destruction of delegates, it's just about changing
47+ // the culling of the items so they are actually visible
48 if (holdingList && holdingList.moving && !scopeView.visibleToParent) {
49 return;
50 }
51@@ -412,7 +429,18 @@
52 if (scopeView.isCurrent || scopeView.visibleToParent) {
53 item.displayMarginBeginning = displayMarginBeginning;
54 item.displayMarginEnd = displayMarginEnd;
55- item.cacheBuffer = scopeView.isCurrent ? categoryView.height * 1.5 : 0;
56+ if (holdingList && holdingList.moving) {
57+ // If we are moving we need to reset the cache buffer of the
58+ // view that was not visible (i.e. !wasCurrentOnMoveStart) to 0 since
59+ // otherwise the cache buffer we had set to preload the items of the
60+ // visible range will trigger some item creations and we want move to
61+ // be as smooth as possible meaning no need creations
62+ if (!wasCurrentOnMoveStart) {
63+ item.cacheBuffer = 0;
64+ }
65+ } else {
66+ item.cacheBuffer = categoryView.height * 1.5;
67+ }
68 } else {
69 var visibleRange = baseItem.height + displayMarginEnd + displayMarginBeginning;
70 if (visibleRange < 0) {
71
72=== modified file 'tests/qmltests/Dash/tst_DashContent.qml'
73--- tests/qmltests/Dash/tst_DashContent.qml 2015-01-09 10:42:42 +0000
74+++ tests/qmltests/Dash/tst_DashContent.qml 2015-01-13 14:37:22 +0000
75@@ -537,5 +537,62 @@
76
77 compare(categoryListView.pageHeader.item.searchHint, "Search People");
78 }
79+
80+ function compareArrays(a, b) {
81+ if (a.length != b.length) return false;
82+ for (var i in a) {
83+ if (a[i] != b[i]) return false;
84+ }
85+ return true;
86+ }
87+
88+ function getSettledButtons() {
89+ var buttons = findChildsByType(dashContent, "AbstractButton");
90+ wait(2500);
91+ var aux = findChildsByType(dashContent, "AbstractButton");
92+ while (!compareArrays(aux, buttons)) {
93+ buttons = aux;
94+ wait(2500);
95+ aux = findChildsByType(dashContent, "AbstractButton");
96+ }
97+ return buttons;
98+ }
99+
100+ function test_noDelegateCreationDestructionOnMove() {
101+ // Our cards are of type AbstractButton as defined in CardCreator.js
102+ // This gives also other things that are not cards but for our purpose it
103+ // does not matter
104+
105+ // Wait for the buttons to settle
106+ var buttons = getSettledButtons();
107+
108+ // Move the scopes so that the item on the right is the current one
109+ // without releasing the button
110+ mouseFlick(dashContent, dashContent.width - units.gu(1), units.gu(1), units.gu(1), units.gu(1), true, false);
111+
112+ // Make sure we have changed to a new scope
113+ compare(dashContent.currentIndex, 1);
114+
115+ // Wait for the buttons to settle
116+ var buttons2 = getSettledButtons();
117+
118+ // Verify we have exactly the same buttons as before starting to move
119+ verify(compareArrays(buttons2, buttons));
120+
121+ // Release the mouse
122+ mouseRelease(dashContent, units.gu(1), units.gu(1));
123+
124+ // Wait for the scopes list to stop moving
125+ var dashContentList = findChild(dashContent, "dashContentList");
126+ tryCompare(dashContentList, "moving", false);
127+ compare(dashContent.currentIndex, 1);
128+
129+ // Wait for the buttons to settle
130+ var buttons3 = getSettledButtons();
131+
132+ // Verify we have a different set of buttons now
133+ expectFail("", "There has to be new cards after releasing the list is not moving anymore");
134+ verify(compareArrays(buttons3, buttons));
135+ }
136 }
137 }
138
139=== modified file 'tests/utils/modules/Unity/Test/UnityTestCase.qml'
140--- tests/utils/modules/Unity/Test/UnityTestCase.qml 2015-01-09 10:42:42 +0000
141+++ tests/utils/modules/Unity/Test/UnityTestCase.qml 2015-01-13 14:37:22 +0000
142@@ -170,6 +170,18 @@
143 return null;
144 }
145
146+ function findChildsByType(obj, typeName) {
147+ var res = new Array(0);
148+ for (var i in obj.children) {
149+ var c = obj.children[i];
150+ if (UT.Util.isInstanceOf(c, typeName)) {
151+ res.push(c)
152+ }
153+ res = res.concat(findChildsByType(c, typeName));
154+ }
155+ return res;
156+ }
157+
158 // Type a full string instead of keyClick letter by letter
159 // TODO: this is not ugly, this is uber-ugly and does not support
160 // any special character. Remove the keyMap once keyClick(obj, char)

Subscribers

People subscribed via source and target branches