diff options
author | Fabian Kosmale <fabian.kosmale@qt.io> | 2024-04-08 16:34:00 +0200 |
---|---|---|
committer | Fabian Kosmale <fabian.kosmale@qt.io> | 2024-04-11 17:26:23 +0200 |
commit | 60194389cd68f51376f611fe878a395c39e6f0eb (patch) | |
tree | 65bdc12501ff5305bb01b3bbf02305343ece882b /tests | |
parent | 9d8c749854bff84046fa2c3c7f7d7039609facc1 (diff) |
ItemView: Avoid undesired repositioning in updateCurrent
When updateCurrent is called, it in turn calls updateHighlight.
updateHighlight already takes autoHighlight into consideration for some
of its logic, but still calls unconditionally into updateTrackedItem.
That in turn will trigger some movement of the list, to position the
tracked item, which is the highlight.
That movement is already only done for the case where the move reason is
setIndex. We add an additional condition to check that we really need to
track the highlight (either autoHighlight needs to be true, or
highlightRange is unequal to NoHighlightRange).
This does have the effect that the currentItem can be completely outside
of the viewport.
[ChangeLog][Important Behavior Change][QtQuick][ListView] If
highlightFollowsCurrentItem is set to false, and highlightRangeMode is
set to NoHighlightRange, then programatically setting the currentIndex
of the list will no longer scroll the view to that item.
Fixes: QTBUG-68527
Pick-to: 6.7
Change-Id: I32aeec2621524d72981ec5d9b933d3f608d89390
Reviewed-by: Santhosh Kumar <santhosh.kumar.selvaraj@qt.io>
Diffstat (limited to 'tests')
-rw-r--r-- | tests/auto/quick/qquicklistview2/data/viewportAvoidUndesiredMovementOnSetCurrentIndex.qml | 47 | ||||
-rw-r--r-- | tests/auto/quick/qquicklistview2/tst_qquicklistview2.cpp | 28 |
2 files changed, 75 insertions, 0 deletions
diff --git a/tests/auto/quick/qquicklistview2/data/viewportAvoidUndesiredMovementOnSetCurrentIndex.qml b/tests/auto/quick/qquicklistview2/data/viewportAvoidUndesiredMovementOnSetCurrentIndex.qml new file mode 100644 index 0000000000..cd3865d55b --- /dev/null +++ b/tests/auto/quick/qquicklistview2/data/viewportAvoidUndesiredMovementOnSetCurrentIndex.qml @@ -0,0 +1,47 @@ +import QtQuick + +Item { + id: root + width: 400 + height: 600 + + ListView { + id: rawList + objectName: "list" + anchors.top: parent.top + anchors.left: parent.left + anchors.right: parent.right + height: 300 + + // full disabling of automatic viewport positioning + highlightFollowsCurrentItem: false + snapMode: ListView.NoSnap + highlightRangeMode: ListView.NoHighlightRange + + delegate: Rectangle { + color: model.index === rawList.currentIndex ? "red" : "white" + border.color: rawList.currentItem === this ? "red" : "black" + height: 100 + width: 400 + + Text { + anchors.centerIn: parent + text: model.index + font.pixelSize: 50 + } + + MouseArea { + // only for using this file to do manual testing + // autotest calls setCurrentIndex + anchors.fill: parent + + onClicked: { + rawList.currentIndex = model.index; + } + } + } + + model: 30 + } + +} diff --git a/tests/auto/quick/qquicklistview2/tst_qquicklistview2.cpp b/tests/auto/quick/qquicklistview2/tst_qquicklistview2.cpp index 931d785d84..bdac2112b6 100644 --- a/tests/auto/quick/qquicklistview2/tst_qquicklistview2.cpp +++ b/tests/auto/quick/qquicklistview2/tst_qquicklistview2.cpp @@ -55,6 +55,7 @@ private slots: void sectionIsCompatibleWithBoundComponents(); void sectionGeometryChange(); void areaZeroviewDoesNotNeedlesslyPopulateWholeModel(); + void viewportAvoidUndesiredMovementOnSetCurrentIndex(); void delegateContextHandling(); void fetchMore_data(); @@ -134,6 +135,33 @@ void tst_QQuickListView2::dragDelegateWithMouseArea_data() } } +void tst_QQuickListView2::viewportAvoidUndesiredMovementOnSetCurrentIndex() +{ + QScopedPointer<QQuickView> window(createView()); + QVERIFY(window); + window->setFlag(Qt::FramelessWindowHint); + window->setSource(testFileUrl("viewportAvoidUndesiredMovementOnSetCurrentIndex.qml")); + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window.data())); + QVERIFY(window->rootObject()); + QQuickListView *listview = findItem<QQuickListView>(window->rootObject(), "list"); + QVERIFY(listview); + listview->setCurrentIndex(2); // change current item + // partially obscure first item + QCOMPARE(listview->contentY(), 0); + listview->setContentY(50); + QTRY_COMPARE(listview->contentY(), 50); + listview->setCurrentIndex(0); // change current item back to first one + QVERIFY(QQuickTest::qWaitForPolish(listview)); + // that shouldn't have caused any movement + QCOMPARE(listview->contentY(), 50); + + // that even applies to the case where the current item is completely out of the viewport + listview->setCurrentIndex(25); + QVERIFY(QQuickTest::qWaitForPolish(listview)); + QCOMPARE(listview->contentY(), 50); +} + void tst_QQuickListView2::dragDelegateWithMouseArea() { QFETCH(QQuickItemView::LayoutDirection, layoutDirection); |