QAbstractItemView: fix autoscroll immediately stopping

Adjust the draggedPosition calculation to changes in
QAbstractItemViewPrivate::offset(). The draggedPosition was previously
first calculated by adding mouse pos and offset() value, and mouse pos
was later extracted by subtracting the offset() from draggedPosition.

However, the offset() value no longer remains a constant between the
addition and subtraction, which makes it impossible to get the old
mouse position.

Store the offset and mouse position separately to make the
calculations deterministic across events.

Fixes: QTBUG-130978
Pick-to: 6.10 6.9 6.8 6.5
Change-Id: I5c601ff7ca40c9d8fb7ad949ff15520d199f5c1f
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
This commit is contained in:
Miika Pernu 2025-06-17 15:36:35 +09:00 committed by Volker Hilsheimer
parent 3183b7b791
commit 882a4df4fd
2 changed files with 12 additions and 6 deletions

View File

@ -1812,12 +1812,13 @@ void QAbstractItemView::mousePressEvent(QMouseEvent *event)
QItemSelectionModel::SelectionFlags command = selectionCommand(index, event);
d->noSelectionOnMousePress = command == QItemSelectionModel::NoUpdate || !index.isValid();
QPoint offset = d->offset();
d->draggedPosition = pos + offset;
d->draggedPosition = pos;
d->draggedPositionOffset = offset;
#if QT_CONFIG(draganddrop)
// update the pressed position when drag was enable
if (d->dragEnabled)
d->pressedPosition = d->draggedPosition;
d->pressedPosition = d->draggedPosition + d->draggedPositionOffset;
#endif
if (!(command & QItemSelectionModel::Current)) {
@ -1874,7 +1875,8 @@ void QAbstractItemView::mouseMoveEvent(QMouseEvent *event)
Q_D(QAbstractItemView);
QPoint bottomRight = event->position().toPoint();
d->draggedPosition = bottomRight + d->offset();
d->draggedPosition = bottomRight;
d->draggedPositionOffset = d->offset();
if (state() == ExpandingState || state() == CollapsingState)
return;
@ -2049,7 +2051,8 @@ void QAbstractItemView::dragEnterEvent(QDragEnterEvent *event)
void QAbstractItemView::dragMoveEvent(QDragMoveEvent *event)
{
Q_D(QAbstractItemView);
d->draggedPosition = event->position().toPoint() + d->offset();
d->draggedPosition = event->position().toPoint();
d->draggedPositionOffset = d->offset();
if (dragDropMode() == InternalMove
&& (event->source() != this || !(event->possibleActions() & Qt::MoveAction)))
return;
@ -4090,7 +4093,8 @@ void QAbstractItemView::doAutoScroll()
const int verticalValue = verticalScroll->value();
const int horizontalValue = horizontalScroll->value();
const QPoint pos = d->draggedPosition - d->offset();
const QPoint pos = d->draggedPosition;
const QRect area = QWidgetPrivate::get(d->viewport)->clipRect();
// do the scrolling if we are in the scroll margins
@ -4130,7 +4134,8 @@ void QAbstractItemView::doAutoScroll()
// update our dragged position manually after the scroll. "pos" is the old
// draggedPosition - d->offset(), and d->offset() is now updated after scrolling, so
// pos + d->offset() gives us the new position.
d->draggedPosition = pos + d->offset();
d->draggedPosition = pos;
d->draggedPositionOffset = d->offset();
break;
}
default:

View File

@ -351,6 +351,7 @@ public:
Qt::KeyboardModifiers pressedModifiers;
QPoint pressedPosition;
QPoint draggedPosition;
QPoint draggedPositionOffset;
bool pressedAlreadySelected;
bool releaseFromDoubleClick;