QQuickItem: item stays pressed after DoubleClicks

Amends 72651a50f8.
This commit decided to ignore double clicks in the virtual
QQuickItem::mouseDoubleClickEvent().
If a subclass inheriting from QQuickItem wants to not ignore
a double click, it should override mouseDoubleClickEvent()
and handle the double click event accordingly.

Fix QQuickMouseArea::mouseDoubleClickEvent(QMouseEvent *event) to *not*
call the base implementation in QQuickItem after handling a double
click, because QQuickItem sets that double-click MouseEvent back to
the ignored state.

This was leading to weird behavior on platforms with touch
screens like Android or IOS where buttons "got stuck" after
a double click.

Fixes: QTBUG-112434
Fixes: QTBUG-109393
Pick-to: 6.5
Change-Id: I774189fbcb356b07336f35f053e05a12c34ce602
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
This commit is contained in:
Sami Shalayel 2023-04-17 18:03:09 +02:00
parent 8d902def13
commit d7fac6923a
3 changed files with 49 additions and 0 deletions

View File

@ -795,6 +795,11 @@ void QQuickMouseArea::mouseDoubleClickEvent(QMouseEvent *event)
d->propagate(&me, QQuickMouseAreaPrivate::DoubleClick);
if (d->pressed)
d->doubleClick = d->isDoubleClickConnected() || me.isAccepted();
// do not call the base implementation if the event is accepted
// because it will revert the event back to ignored state
if (me.isAccepted())
return;
}
QQuickItem::mouseDoubleClickEvent(event);
}

View File

@ -0,0 +1,23 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Window
Rectangle {
width: 200; height: 200
color: mouseArea.pressed ? "red" : "orange"
Popup {
visible: true
closePolicy: Popup.NoAutoClose
width: 100
height: 100
contentItem: MouseArea {
id: mouseArea
anchors.fill: parent
}
background: Rectangle {
color: "green"
}
}
}

View File

@ -32,6 +32,7 @@ private slots:
void dragHandlerInSiblingStealingGrabFromMouseAreaViaTouch();
void hoverHandlerDoesntHoverOnPress();
void doubleClickInMouseAreaWithDragHandlerInGrandparent();
void doubleClickInMouseArea();
private:
void createView(QScopedPointer<QQuickView> &window, const char *fileName);
@ -204,6 +205,26 @@ void tst_MouseAreaInterop::doubleClickInMouseAreaWithDragHandlerInGrandparent()
QCOMPARE(dragActiveSpy.size(), 0);
}
void tst_MouseAreaInterop::doubleClickInMouseArea()
{
QQuickView window;
QVERIFY(QQuickTest::showView(window, testFileUrl("doubleClickInMouseArea.qml")));
auto *ma = window.rootObject()->findChild<QQuickMouseArea *>();
QVERIFY(ma);
QSignalSpy doubleClickSpy(ma, &QQuickMouseArea::doubleClicked);
QSignalSpy longPressSpy(ma, &QQuickMouseArea::pressAndHold);
QPoint p = ma->mapToScene(ma->boundingRect().center()).toPoint();
// check with normal double click
QTest::mouseDClick(&window, Qt::LeftButton, Qt::NoModifier, p);
QCOMPARE(doubleClickSpy.count(), 1);
// wait enough time for a wrong long press to happen
QTest::qWait(QGuiApplication::styleHints()->mousePressAndHoldInterval() + 10);
QCOMPARE(longPressSpy.count(), 0);
}
QTEST_MAIN(tst_MouseAreaInterop)
#include "tst_mousearea_interop.moc"