Move Event Handler acceptedButtons check back up to QQPDeviceHandler

Reverts what's left of e535109441
(amends 73258eca7a):
MultiPointHandler is not only for touch handling anymore.
DragHandler in particular needs to respect the acceptedButtons property.

Fixes: QTBUG-76875
Fixes: QTBUG-76582
Change-Id: I414e785dd09b297c93e5e9f162be23e4a44eca54
Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
This commit is contained in:
Shawn Rutledge 2019-07-04 11:44:52 +02:00
parent 9b01e2e5d4
commit 1982d1b1aa
4 changed files with 62 additions and 30 deletions

View File

@ -38,6 +38,7 @@
****************************************************************************/ ****************************************************************************/
#include "qquickhoverhandler_p.h" #include "qquickhoverhandler_p.h"
#include <private/qquickpointerdevicehandler_p_p.h>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@ -59,6 +60,8 @@ Q_LOGGING_CATEGORY(lcHoverHandler, "qt.quick.handler.hover")
QQuickHoverHandler::QQuickHoverHandler(QQuickItem *parent) QQuickHoverHandler::QQuickHoverHandler(QQuickItem *parent)
: QQuickSinglePointHandler(parent) : QQuickSinglePointHandler(parent)
{ {
// Tell QQuickPointerDeviceHandler::wantsPointerEvent() to ignore button state
d_func()->acceptedButtons = Qt::NoButton;
// Rule out the touchscreen for now (can be overridden in QML in case a hover-detecting touchscreen exists) // Rule out the touchscreen for now (can be overridden in QML in case a hover-detecting touchscreen exists)
setAcceptedDevices(static_cast<QQuickPointerDevice::DeviceType>( setAcceptedDevices(static_cast<QQuickPointerDevice::DeviceType>(
static_cast<int>(QQuickPointerDevice::AllDevices) ^ static_cast<int>(QQuickPointerDevice::TouchScreen))); static_cast<int>(QQuickPointerDevice::AllDevices) ^ static_cast<int>(QQuickPointerDevice::TouchScreen)));

View File

@ -256,6 +256,10 @@ bool QQuickPointerDeviceHandler::wantsPointerEvent(QQuickPointerEvent *event)
return false; return false;
if (d->acceptedModifiers != Qt::KeyboardModifierMask && event->modifiers() != d->acceptedModifiers) if (d->acceptedModifiers != Qt::KeyboardModifierMask && event->modifiers() != d->acceptedModifiers)
return false; return false;
// HoverHandler sets acceptedButtons to Qt::NoButton to indicate that button state is irrelevant.
if (event->device()->pointerType() != QQuickPointerDevice::Finger && acceptedButtons() != Qt::NoButton &&
(event->buttons() & acceptedButtons()) == 0 && (event->button() & acceptedButtons()) == 0)
return false;
return true; return true;
} }

View File

@ -67,9 +67,6 @@ bool QQuickSinglePointHandler::wantsPointerEvent(QQuickPointerEvent *event)
{ {
if (!QQuickPointerDeviceHandler::wantsPointerEvent(event)) if (!QQuickPointerDeviceHandler::wantsPointerEvent(event))
return false; return false;
if (event->device()->pointerType() != QQuickPointerDevice::Finger &&
(event->buttons() & acceptedButtons()) == 0 && (event->button() & acceptedButtons()) == 0)
return false;
if (m_pointInfo.m_id) { if (m_pointInfo.m_id) {
// We already know which one we want, so check whether it's there. // We already know which one we want, so check whether it's there.

View File

@ -54,6 +54,7 @@ private slots:
void defaultPropertyValues(); void defaultPropertyValues();
void touchDrag(); void touchDrag();
void mouseDrag_data();
void mouseDrag(); void mouseDrag();
void dragFromMargin(); void dragFromMargin();
void touchDragMulti(); void touchDragMulti();
@ -193,8 +194,22 @@ void tst_DragHandler::touchDrag()
QCOMPARE(centroidChangedSpy.count(), 5); QCOMPARE(centroidChangedSpy.count(), 5);
} }
void tst_DragHandler::mouseDrag_data()
{
QTest::addColumn<Qt::MouseButtons>("acceptedButtons");
QTest::addColumn<Qt::MouseButtons>("dragButton");
QTest::newRow("left: drag") << Qt::MouseButtons(Qt::LeftButton) << Qt::MouseButtons(Qt::LeftButton);
QTest::newRow("right: don't drag") << Qt::MouseButtons(Qt::LeftButton) << Qt::MouseButtons(Qt::RightButton);
QTest::newRow("left: don't drag") << Qt::MouseButtons(Qt::RightButton | Qt::MiddleButton) << Qt::MouseButtons(Qt::LeftButton);
QTest::newRow("right or middle: drag") << Qt::MouseButtons(Qt::RightButton | Qt::MiddleButton) << Qt::MouseButtons(Qt::MiddleButton);
}
void tst_DragHandler::mouseDrag() void tst_DragHandler::mouseDrag()
{ {
QFETCH(Qt::MouseButtons, acceptedButtons);
QFETCH(Qt::MouseButtons, dragButton);
bool shouldDrag = bool(acceptedButtons & dragButton);
const int dragThreshold = QGuiApplication::styleHints()->startDragDistance(); const int dragThreshold = QGuiApplication::styleHints()->startDragDistance();
QScopedPointer<QQuickView> windowPtr; QScopedPointer<QQuickView> windowPtr;
createView(windowPtr, "draggables.qml"); createView(windowPtr, "draggables.qml");
@ -204,6 +219,7 @@ void tst_DragHandler::mouseDrag()
QVERIFY(ball); QVERIFY(ball);
QQuickDragHandler *dragHandler = ball->findChild<QQuickDragHandler*>(); QQuickDragHandler *dragHandler = ball->findChild<QQuickDragHandler*>();
QVERIFY(dragHandler); QVERIFY(dragHandler);
dragHandler->setAcceptedButtons(acceptedButtons); // QTBUG-76875
QSignalSpy translationChangedSpy(dragHandler, SIGNAL(translationChanged())); QSignalSpy translationChangedSpy(dragHandler, SIGNAL(translationChanged()));
QSignalSpy centroidChangedSpy(dragHandler, SIGNAL(centroidChanged())); QSignalSpy centroidChangedSpy(dragHandler, SIGNAL(centroidChanged()));
@ -211,45 +227,57 @@ void tst_DragHandler::mouseDrag()
QPointF ballCenter = ball->clipRect().center(); QPointF ballCenter = ball->clipRect().center();
QPointF scenePressPos = ball->mapToScene(ballCenter); QPointF scenePressPos = ball->mapToScene(ballCenter);
QPoint p1 = scenePressPos.toPoint(); QPoint p1 = scenePressPos.toPoint();
QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, p1); QTest::mousePress(window, static_cast<Qt::MouseButton>(int(dragButton)), Qt::NoModifier, p1);
QVERIFY(!dragHandler->active()); QVERIFY(!dragHandler->active());
QCOMPARE(dragHandler->centroid().position(), ballCenter); if (shouldDrag) {
QCOMPARE(dragHandler->centroid().pressPosition(), ballCenter); QCOMPARE(dragHandler->centroid().position(), ballCenter);
QCOMPARE(dragHandler->centroid().scenePosition(), scenePressPos); QCOMPARE(dragHandler->centroid().pressPosition(), ballCenter);
QCOMPARE(dragHandler->centroid().scenePressPosition(), scenePressPos); QCOMPARE(dragHandler->centroid().scenePosition(), scenePressPos);
QCOMPARE(dragHandler->centroid().velocity(), QVector2D()); QCOMPARE(dragHandler->centroid().scenePressPosition(), scenePressPos);
QCOMPARE(centroidChangedSpy.count(), 1); QCOMPARE(dragHandler->centroid().velocity(), QVector2D());
QCOMPARE(centroidChangedSpy.count(), 1);
}
p1 += QPoint(dragThreshold, 0); p1 += QPoint(dragThreshold, 0);
QTest::mouseMove(window, p1); QTest::mouseMove(window, p1);
QTRY_VERIFY(dragHandler->centroid().velocity().x() > 0); if (shouldDrag) {
QCOMPARE(centroidChangedSpy.count(), 2); QTRY_VERIFY(dragHandler->centroid().velocity().x() > 0);
QVERIFY(!dragHandler->active()); QCOMPARE(centroidChangedSpy.count(), 2);
QVERIFY(!dragHandler->active());
}
p1 += QPoint(1, 0); p1 += QPoint(1, 0);
QTest::mouseMove(window, p1); QTest::mouseMove(window, p1);
QTRY_VERIFY(dragHandler->active()); if (shouldDrag)
QTRY_VERIFY(dragHandler->active());
else
QVERIFY(!dragHandler->active());
QCOMPARE(translationChangedSpy.count(), 0); QCOMPARE(translationChangedSpy.count(), 0);
QCOMPARE(centroidChangedSpy.count(), 3); if (shouldDrag)
QCOMPARE(centroidChangedSpy.count(), 3);
QCOMPARE(dragHandler->translation().x(), 0.0); QCOMPARE(dragHandler->translation().x(), 0.0);
QPointF sceneGrabPos = p1; QPointF sceneGrabPos = p1;
QCOMPARE(dragHandler->centroid().sceneGrabPosition(), sceneGrabPos); if (shouldDrag)
QCOMPARE(dragHandler->centroid().sceneGrabPosition(), sceneGrabPos);
p1 += QPoint(19, 0); p1 += QPoint(19, 0);
QTest::mouseMove(window, p1); QTest::mouseMove(window, p1);
QTRY_VERIFY(dragHandler->active()); QVERIFY(shouldDrag ? dragHandler->active() : !dragHandler->active());
QCOMPARE(dragHandler->centroid().position(), ballCenter); if (shouldDrag) {
QCOMPARE(dragHandler->centroid().pressPosition(), ballCenter); QCOMPARE(dragHandler->centroid().position(), ballCenter);
QCOMPARE(dragHandler->centroid().scenePosition(), ball->mapToScene(ballCenter)); QCOMPARE(dragHandler->centroid().pressPosition(), ballCenter);
QCOMPARE(dragHandler->centroid().scenePressPosition(), scenePressPos); QCOMPARE(dragHandler->centroid().scenePosition(), ball->mapToScene(ballCenter));
QCOMPARE(dragHandler->centroid().sceneGrabPosition(), sceneGrabPos); QCOMPARE(dragHandler->centroid().scenePressPosition(), scenePressPos);
QCOMPARE(dragHandler->translation().x(), dragThreshold + 20.0); QCOMPARE(dragHandler->centroid().sceneGrabPosition(), sceneGrabPos);
QCOMPARE(dragHandler->translation().y(), 0.0); QCOMPARE(dragHandler->translation().x(), dragThreshold + 20.0);
QVERIFY(dragHandler->centroid().velocity().x() > 0); QCOMPARE(dragHandler->translation().y(), 0.0);
QCOMPARE(centroidChangedSpy.count(), 4); QVERIFY(dragHandler->centroid().velocity().x() > 0);
QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, p1); QCOMPARE(centroidChangedSpy.count(), 4);
}
QTest::mouseRelease(window, static_cast<Qt::MouseButton>(int(dragButton)), Qt::NoModifier, p1);
QTRY_VERIFY(!dragHandler->active()); QTRY_VERIFY(!dragHandler->active());
QCOMPARE(dragHandler->centroid().pressedButtons(), Qt::NoButton); QCOMPARE(dragHandler->centroid().pressedButtons(), Qt::NoButton);
QCOMPARE(ball->mapToScene(ballCenter).toPoint(), p1); if (shouldDrag)
QCOMPARE(translationChangedSpy.count(), 1); QCOMPARE(ball->mapToScene(ballCenter).toPoint(), p1);
QCOMPARE(centroidChangedSpy.count(), 5); QCOMPARE(translationChangedSpy.count(), shouldDrag ? 1 : 0);
QCOMPARE(centroidChangedSpy.count(), shouldDrag ? 5 : 0);
} }
void tst_DragHandler::dragFromMargin() // QTBUG-74966 void tst_DragHandler::dragFromMargin() // QTBUG-74966