0134d56
From 1b0e366092bcfae0392592c3b7891f0e47af1018 Mon Sep 17 00:00:00 2001
0134d56
From: Oliver Eftevaag <oliver.eftevaag@qt.io>
0134d56
Date: Fri, 9 Dec 2022 18:40:54 +0100
0134d56
Subject: [PATCH 30/30] Flickable: prevent fixup() from being called while
0134d56
 dragging
0134d56
MIME-Version: 1.0
0134d56
Content-Type: text/plain; charset=UTF-8
0134d56
Content-Transfer-Encoding: 8bit
0134d56
0134d56
A previous patch 5647527a8cde84b51fff66fc482f02435770b3dd causes
0134d56
a regression. The purpose of the patch, that caused this regression,
0134d56
was to update the pressPos variables, in cases where the contentItem's
0134d56
geometry was modified externally, while a user were dragging the
0134d56
contentItem around.
0134d56
0134d56
The mistake that was made, was how width and height changes were
0134d56
handled. We had previously added logic in setContentWidth() and
0134d56
setContentHeight() that would call fixup() (with immediate fixupMode)
0134d56
to ensure that the contentItem would immediately be repositioned
0134d56
inside the flickable's viewport, if the contentItem was being dragged.
0134d56
0134d56
It turns out that setContentWidth() and setContentHeight() are being
0134d56
called from QQuickItemViewPrivate::updateViewport(), which happens
0134d56
quite often, while dragging. This would make fixup() and dragging
0134d56
constantly interfere with each other, since they'd not always agree on
0134d56
a specific position for the contentItem.
0134d56
0134d56
This patch reverts the changes made to setContentWidth() and
0134d56
setContentHeight(), since it turns out that those changes weren't
0134d56
necessary after all. QQuickFlickablePrivate::itemGeometryChanged() only
0134d56
calls viewportMoved() on x and y changes anyways.
0134d56
0134d56
Done-with: Jan Arve Sæther <jan-arve.saether@qt.io>
0134d56
Done-with: Santhosh Kumar Selvaraj <santhosh.kumar.selvaraj@qt.io>
0134d56
Fixes: QTBUG-109140
0134d56
Pick-to: 5.15 6.2 6.3 6.4 6.5
0134d56
Change-Id: I0bddf8685d3afc1ae04b2c092212d3c1bd742c3b
0134d56
Reviewed-by: Paul Wicking <paul.wicking@qt.io>
0134d56
(cherry picked from commit b307bf3c4f63c6e04874a972c747f18e18ddc199)
0134d56
---
0134d56
 src/quick/items/qquickflickable.cpp                      | 8 ++------
0134d56
 src/quick/items/qquickflickable_p_p.h                    | 1 +
0134d56
 tests/auto/quick/qquickflickable/tst_qquickflickable.cpp | 8 +++++++-
0134d56
 3 files changed, 10 insertions(+), 7 deletions(-)
0134d56
0134d56
diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp
0134d56
index ea357d819d..2634b68248 100644
0134d56
--- a/src/quick/items/qquickflickable.cpp
0134d56
+++ b/src/quick/items/qquickflickable.cpp
0134d56
@@ -2120,11 +2120,9 @@ void QQuickFlickable::setContentWidth(qreal w)
0134d56
         d->contentItem->setWidth(w);
0134d56
     d->hData.markExtentsDirty();
0134d56
     // Make sure that we're entirely in view.
0134d56
-    if ((!d->pressed && !d->hData.moving && !d->vData.moving) || d->hData.dragging) {
0134d56
-        d->hData.contentPositionChangedExternallyDuringDrag = d->hData.dragging;
0134d56
+    if (!d->pressed && !d->hData.moving && !d->vData.moving) {
0134d56
         d->fixupMode = QQuickFlickablePrivate::Immediate;
0134d56
         d->fixupX();
0134d56
-        d->hData.contentPositionChangedExternallyDuringDrag = false;
0134d56
     } else if (!d->pressed && d->hData.fixingUp) {
0134d56
         d->fixupMode = QQuickFlickablePrivate::ExtentChanged;
0134d56
         d->fixupX();
0134d56
@@ -2151,11 +2149,9 @@ void QQuickFlickable::setContentHeight(qreal h)
0134d56
         d->contentItem->setHeight(h);
0134d56
     d->vData.markExtentsDirty();
0134d56
     // Make sure that we're entirely in view.
0134d56
-    if ((!d->pressed && !d->hData.moving && !d->vData.moving) || d->vData.dragging) {
0134d56
-        d->vData.contentPositionChangedExternallyDuringDrag = d->vData.dragging;
0134d56
+    if (!d->pressed && !d->hData.moving && !d->vData.moving) {
0134d56
         d->fixupMode = QQuickFlickablePrivate::Immediate;
0134d56
         d->fixupY();
0134d56
-        d->vData.contentPositionChangedExternallyDuringDrag = false;
0134d56
     } else if (!d->pressed && d->vData.fixingUp) {
0134d56
         d->fixupMode = QQuickFlickablePrivate::ExtentChanged;
0134d56
         d->fixupY();
0134d56
diff --git a/src/quick/items/qquickflickable_p_p.h b/src/quick/items/qquickflickable_p_p.h
0134d56
index d5d838eaea..aef15e150a 100644
0134d56
--- a/src/quick/items/qquickflickable_p_p.h
0134d56
+++ b/src/quick/items/qquickflickable_p_p.h
0134d56
@@ -120,6 +120,7 @@ public:
0134d56
             dragStartOffset = 0;
0134d56
             fixingUp = false;
0134d56
             inOvershoot = false;
0134d56
+            contentPositionChangedExternallyDuringDrag = false;
0134d56
         }
0134d56
 
0134d56
         void markExtentsDirty() {
0134d56
diff --git a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp
0134d56
index d092cd0170..62f7c67dd4 100644
0134d56
--- a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp
0134d56
+++ b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp
0134d56
@@ -2642,7 +2642,12 @@ void tst_qquickflickable::setContentPositionWhileDragging() // QTBUG-104966
0134d56
     } else if (newExtent >= 0) {
0134d56
         // ...or reduce the content size be be less than current (contentX, contentY) position
0134d56
         // This forces the content item to move.
0134d56
-        expectedContentPos = moveDelta;
0134d56
+        // contentY: 150
0134d56
+        // 320 - 150 = 170 pixels down to bottom
0134d56
+        // Now reduce contentHeight to 200
0134d56
+        // since we are at the bottom, and the flickable is 100 pixels tall, contentY must land
0134d56
+        // at newExtent - 100.
0134d56
+
0134d56
         if (isHorizontal) {
0134d56
             flickable->setContentWidth(newExtent);
0134d56
         } else {
0134d56
@@ -2652,6 +2657,7 @@ void tst_qquickflickable::setContentPositionWhileDragging() // QTBUG-104966
0134d56
         // We therefore cannot scroll/flick it further down. Drag it up towards the top instead
0134d56
         // (by moving mouse down).
0134d56
         pos += moveDelta;
0134d56
+        expectedContentPos = unitDelta * (newExtent - (isHorizontal ? flickable->width() : flickable->height()));
0134d56
     }
0134d56
 
0134d56
     QTest::mouseMove(window.data(), pos);
0134d56
-- 
0134d56
2.41.0
0134d56