on xenial help sign in
Make sure we don't create/destroy delegates when we are in the middle of switching scopes
commit8a5aceacae54219bf2cfdca51ff3cea6b466863f authorAlbert Astals <albert.astals@canonical.com> dateTue 13 Jan 2015, 12:54 (12 years ago) parent513e2af
3 files changed+99−2
qml/Dash/GenericScopeView.qml+30−2 tests/qmltests/Dash/tst_DashContent.qml+57 tests/utils/modules/Unity/Test/UnityTestCase.qml+12
qml/Dash/GenericScopeView.qml+30−2
@@ -41,6 +41,7 @@ FocusScope {
4141 property bool visibleToParent: false
4242 property alias pageHeaderTotallyVisible: categoryView.pageHeaderTotallyVisible
4343 property var holdingList: null
44+ property bool wasCurrentOnMoveStart: false
4445
4546 property var scopeStyle: ScopeStyle {
4647 style: scope ? scope.customizations : {}
@@ -116,6 +117,9 @@ FocusScope {
116117 }
117118
118119 onIsCurrentChanged: {
120+ if (!holdingList || !holdingList.moving) {
121+ wasCurrentOnMoveStart = scopeView.isCurrent;
122+ }
119123 if (pageHeaderLoader.item && showPageHeader) {
120124 pageHeaderLoader.item.resetSearch();
121125 }
@@ -142,6 +146,15 @@ FocusScope {
142146 onHideDash: subPageLoader.closeSubPage()
143147 }
144148
149+ Connections {
150+ target: holdingList
151+ onMovingChanged: {
152+ if (!moving) {
153+ wasCurrentOnMoveStart = scopeView.isCurrent;
154+ }
155+ }
156+ }
157+
145158 Rectangle {
146159 anchors.fill: parent
147160 color: scopeView.scopeStyle ? scopeView.scopeStyle.background : "transparent"
@@ -367,7 +380,11 @@ FocusScope {
367380
368381 function updateRanges() {
369382 // Don't want to create stress by requesting more items during scope
370− // changes so unless you're not part of the visible scopes just return
383+ // changes so unless you're not part of the visible scopes just return.
384+ // For the visible scopes we need to do some work, the previously non visible
385+ // scope needs to adjust its ranges so that we define the new visible range,
386+ // that still means no creation/destruction of delegates, it's just about changing
387+ // the culling of the items so they are actually visible
371388 if (holdingList && holdingList.moving && !scopeView.visibleToParent) {
372389 return;
373390 }
@@ -412,7 +429,18 @@ FocusScope {
412429 if (scopeView.isCurrent || scopeView.visibleToParent) {
413430 item.displayMarginBeginning = displayMarginBeginning;
414431 item.displayMarginEnd = displayMarginEnd;
415− item.cacheBuffer = scopeView.isCurrent ? categoryView.height * 1.5 : 0;
432+ if (holdingList && holdingList.moving) {
433+ // If we are moving we need to reset the cache buffer of the
434+ // view that was not visible (i.e. !wasCurrentOnMoveStart) to 0 since
435+ // otherwise the cache buffer we had set to preload the items of the
436+ // visible range will trigger some item creations and we want move to
437+ // be as smooth as possible meaning no need creations
438+ if (!wasCurrentOnMoveStart) {
439+ item.cacheBuffer = 0;
440+ }
441+ } else {
442+ item.cacheBuffer = categoryView.height * 1.5;
443+ }
416444 } else {
417445 var visibleRange = baseItem.height + displayMarginEnd + displayMarginBeginning;
418446 if (visibleRange < 0) {
tests/qmltests/Dash/tst_DashContent.qml+57
@@ -537,5 +537,62 @@ Item {
537537
538538 compare(categoryListView.pageHeader.item.searchHint, "Search People");
539539 }
540+
541+ function compareArrays(a, b) {
542+ if (a.length != b.length) return false;
543+ for (var i in a) {
544+ if (a[i] != b[i]) return false;
545+ }
546+ return true;
547+ }
548+
549+ function getSettledButtons() {
550+ var buttons = findChildsByType(dashContent, "AbstractButton");
551+ wait(250);
552+ var aux = findChildsByType(dashContent, "AbstractButton");
553+ while (!compareArrays(aux, buttons)) {
554+ buttons = aux;
555+ wait(250);
556+ aux = findChildsByType(dashContent, "AbstractButton");
557+ }
558+ return buttons;
559+ }
560+
561+ function test_noDelegateCreationDestructionOnMove() {
562+ // Our cards are of type AbstractButton as defined in CardCreator.js
563+ // This gives also other things that are not cards but for our purpose it
564+ // does not matter
565+
566+ // Wait for the buttons to settle
567+ var buttons = getSettledButtons();
568+
569+ // Move the scopes so that the item on the right is the current one
570+ // without releasing the button
571+ mouseFlick(dashContent, dashContent.width - units.gu(1), units.gu(1), units.gu(1), units.gu(1), true, false);
572+
573+ // Make sure we have changed to a new scope
574+ compare(dashContent.currentIndex, 1);
575+
576+ // Wait for the buttons to settle
577+ var buttons2 = getSettledButtons();
578+
579+ // Verify we have exactly the same buttons as before starting to move
580+ verify(compareArrays(buttons2, buttons));
581+
582+ // Release the mouse
583+ mouseRelease(dashContent, units.gu(1), units.gu(1));
584+
585+ // Wait for the scopes list to stop moving
586+ var dashContentList = findChild(dashContent, "dashContentList");
587+ tryCompare(dashContentList, "moving", false);
588+ compare(dashContent.currentIndex, 1);
589+
590+ // Wait for the buttons to settle
591+ var buttons3 = getSettledButtons();
592+
593+ // Verify we have a different set of buttons now
594+ expectFail("", "There has to be new cards after releasing the list is not moving anymore");
595+ verify(compareArrays(buttons3, buttons));
596+ }
540597 }
541598}
tests/utils/modules/Unity/Test/UnityTestCase.qml+12
@@ -170,6 +170,18 @@ TestCase {
170170 return null;
171171 }
172172
173+ function findChildsByType(obj, typeName) {
174+ var res = new Array(0);
175+ for (var i in obj.children) {
176+ var c = obj.children[i];
177+ if (UT.Util.isInstanceOf(c, typeName)) {
178+ res.push(c)
179+ }
180+ res = res.concat(findChildsByType(c, typeName));
181+ }
182+ return res;
183+ }
184+
173185 // Type a full string instead of keyClick letter by letter
174186 // TODO: this is not ugly, this is uber-ugly and does not support
175187 // any special character. Remove the keyMap once keyClick(obj, char)