From 9a1a15b42fb526ad4f80944afb7761bfff1b5c9d Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Wed, 4 Nov 2020 22:10:35 +0100 Subject: [PATCH] Introduce QEvent::isSinglePointEvent() This makes high-level event dispatching easier: for example we often need to cast an event to access getters like button() and buttons(). We can so far assume that any QPointerEvent that is not a QTouchEvent is a QSinglePointEvent; but more explicit type-checking looks safer. Implemented in a similar way as c7f727996909338c3689396160f3060480521846. Change-Id: I980d759e2a7538b6b30fd3bdc3be0c351ec6c246 Reviewed-by: Volker Hilsheimer --- src/corelib/kernel/qcoreevent.cpp | 22 +++++++++++++++++-- src/corelib/kernel/qcoreevent.h | 6 ++++- src/gui/kernel/qevent.cpp | 19 ++++++++++++++-- src/gui/kernel/qevent.h | 5 ++++- .../kernel/qmouseevent/tst_qmouseevent.cpp | 2 ++ .../kernel/qtouchevent/tst_qtouchevent.cpp | 1 + 6 files changed, 49 insertions(+), 6 deletions(-) diff --git a/src/corelib/kernel/qcoreevent.cpp b/src/corelib/kernel/qcoreevent.cpp index 6fdc2a94af..af89524dc4 100644 --- a/src/corelib/kernel/qcoreevent.cpp +++ b/src/corelib/kernel/qcoreevent.cpp @@ -294,7 +294,8 @@ QT_BEGIN_NAMESPACE Contructs an event object of type \a type. */ QEvent::QEvent(Type type) - : d(nullptr), t(type), posted(false), spont(false), m_accept(true), m_inputEvent(false), m_pointerEvent(false) + : d(nullptr), t(type), posted(false), spont(false), m_accept(true), + m_inputEvent(false), m_pointerEvent(false), m_singlePointEvent(false) { Q_TRACE(QEvent_ctor, this, t); } @@ -305,7 +306,8 @@ QEvent::QEvent(Type type) */ QEvent::QEvent(const QEvent &other) : d(other.d), t(other.t), posted(other.posted), spont(other.spont), - m_accept(other.m_accept), m_inputEvent(other.m_inputEvent), m_pointerEvent(other.m_pointerEvent) + m_accept(other.m_accept), m_inputEvent(other.m_inputEvent), + m_pointerEvent(other.m_pointerEvent), m_singlePointEvent(other.m_singlePointEvent) { Q_TRACE(QEvent_ctor, this, t); // if QEventPrivate becomes available, make sure to implement a @@ -330,6 +332,15 @@ QEvent::QEvent(const QEvent &other) inputEvent flags to \c true. */ +/*! + \internal + \since 6.0 + \fn QEvent::QEvent(Type type, QEvent::SinglePointEventTag) + + Constructs an event object of type \a type, setting the singlePointEvent, + pointerEvent and inputEvent flags to \c true. +*/ + /*! \internal Attempts to copy the \a other event. @@ -438,6 +449,13 @@ QEvent::~QEvent() subclasses. */ +/*! + \fn bool QEvent::isSinglePointEvent() const + \since 6.0 + + Returns \c true if the event object is a subclass of QSinglePointEvent. +*/ + namespace { template struct QBasicAtomicBitField { diff --git a/src/corelib/kernel/qcoreevent.h b/src/corelib/kernel/qcoreevent.h index b56d5ab401..32f2ba75c7 100644 --- a/src/corelib/kernel/qcoreevent.h +++ b/src/corelib/kernel/qcoreevent.h @@ -308,6 +308,7 @@ public: inline bool isInputEvent() const noexcept { return m_inputEvent; } inline bool isPointerEvent() const noexcept { return m_pointerEvent; } + inline bool isSinglePointEvent() const noexcept { return m_singlePointEvent; } static int registerEventType(int hint = -1) noexcept; @@ -316,6 +317,8 @@ protected: QEvent(Type type, InputEventTag) : QEvent(type) { m_inputEvent = true; } struct PointerEventTag { explicit PointerEventTag() = default; }; QEvent(Type type, PointerEventTag) : QEvent(type, InputEventTag{}) { m_pointerEvent = true; } + struct SinglePointEventTag { explicit SinglePointEventTag() = default; }; + QEvent(Type type, SinglePointEventTag) : QEvent(type, PointerEventTag{}) { m_singlePointEvent = true; } QEventPrivate *d; ushort t; @@ -325,7 +328,8 @@ private: ushort m_accept : 1; ushort m_inputEvent : 1; ushort m_pointerEvent : 1; - ushort reserved : 11; + ushort m_singlePointEvent : 1; + ushort reserved : 10; friend class QCoreApplication; friend class QCoreApplicationPrivate; diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp index 9d27961071..5e9643d82f 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -161,6 +161,13 @@ QInputEvent::QInputEvent(QEvent::Type type, QEvent::PointerEventTag, const QInpu : QEvent(type, QEvent::PointerEventTag{}), m_dev(dev), m_modState(modifiers) {} +/*! + \internal +*/ +QInputEvent::QInputEvent(QEvent::Type type, QEvent::SinglePointEventTag, const QInputDevice *dev, Qt::KeyboardModifiers modifiers) + : QEvent(type, QEvent::SinglePointEventTag{}), m_dev(dev), m_modState(modifiers) +{} + /*! \internal */ @@ -256,6 +263,14 @@ QPointerEvent::QPointerEvent(QEvent::Type type, const QPointingDevice *dev, { } +/*! + \internal +*/ +QPointerEvent::QPointerEvent(QEvent::Type type, QEvent::SinglePointEventTag, const QInputDevice *dev, Qt::KeyboardModifiers modifiers) + : QInputEvent(type, QEvent::SinglePointEventTag{}, dev, modifiers) +{ +} + QPointerEvent::~QPointerEvent() { } @@ -500,7 +515,7 @@ void QPointerEvent::clearPassiveGrabbers(const QEventPoint &point) */ QSinglePointEvent::QSinglePointEvent(QEvent::Type type, const QPointingDevice *dev, const QPointF &localPos, const QPointF &scenePos, const QPointF &globalPos, Qt::MouseButton button, Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers) - : QPointerEvent(type, dev, modifiers), + : QPointerEvent(type, QEvent::SinglePointEventTag{}, dev, modifiers), m_button(button), m_mouseState(buttons), m_source(Qt::MouseEventNotSynthesized), @@ -548,7 +563,7 @@ QSinglePointEvent::QSinglePointEvent(QEvent::Type type, const QPointingDevice *d QSinglePointEvent::QSinglePointEvent(QEvent::Type type, const QPointingDevice *dev, const QEventPoint &point, Qt::MouseButton button, Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers, Qt::MouseEventSource source) - : QPointerEvent(type, dev, modifiers), + : QPointerEvent(type, QEvent::SinglePointEventTag{}, dev, modifiers), m_button(button), m_mouseState(buttons), m_source(source), diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h index 4bd7a54022..7e35a1b117 100644 --- a/src/gui/kernel/qevent.h +++ b/src/gui/kernel/qevent.h @@ -85,7 +85,8 @@ public: virtual void setTimestamp(ulong timestamp) { m_timeStamp = timestamp; } protected: - QInputEvent(Type type, PointerEventTag, const QInputDevice *m_dev, Qt::KeyboardModifiers modifiers = Qt::NoModifier); + QInputEvent(Type type, PointerEventTag, const QInputDevice *dev, Qt::KeyboardModifiers modifiers = Qt::NoModifier); + QInputEvent(Type type, SinglePointEventTag, const QInputDevice *dev, Qt::KeyboardModifiers modifiers = Qt::NoModifier); const QInputDevice *m_dev = nullptr; Qt::KeyboardModifiers m_modState = Qt::NoModifier; @@ -122,6 +123,8 @@ public: bool removePassiveGrabber(const QEventPoint &point, QObject *grabber); protected: + QPointerEvent(Type type, SinglePointEventTag, const QInputDevice *dev, Qt::KeyboardModifiers modifiers = Qt::NoModifier); + QList m_points; }; diff --git a/tests/auto/gui/kernel/qmouseevent/tst_qmouseevent.cpp b/tests/auto/gui/kernel/qmouseevent/tst_qmouseevent.cpp index 42a5f4d593..67fca910b9 100644 --- a/tests/auto/gui/kernel/qmouseevent/tst_qmouseevent.cpp +++ b/tests/auto/gui/kernel/qmouseevent/tst_qmouseevent.cpp @@ -159,6 +159,7 @@ void tst_QMouseEvent::mouseEventBasic() QMouseEvent me(QEvent::MouseButtonPress, local, scene, screen, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); QVERIFY(me.isInputEvent()); QVERIFY(me.isPointerEvent()); + QVERIFY(me.isSinglePointEvent()); QCOMPARE(me.isAccepted(), true); QCOMPARE(me.button(), Qt::LeftButton); QCOMPARE(me.buttons(), Qt::LeftButton); @@ -183,6 +184,7 @@ void tst_QMouseEvent::mouseEventBasic() QMouseEvent copy(me); QVERIFY(copy.isInputEvent()); QVERIFY(copy.isPointerEvent()); + QVERIFY(copy.isSinglePointEvent()); QVERIFY(!copy.isBeginEvent()); QVERIFY(copy.isEndEvent()); QCOMPARE(copy.position(), local); diff --git a/tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp b/tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp index bbd7cb22a0..58e7fd2eed 100644 --- a/tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp +++ b/tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp @@ -343,6 +343,7 @@ void tst_QTouchEvent::state() QVERIFY(!touchEvent.isEndEvent()); QVERIFY(touchEvent.isInputEvent()); QVERIFY(touchEvent.isPointerEvent()); + QVERIFY(!touchEvent.isSinglePointEvent()); touchEvent = QTouchEvent(QEvent::TouchBegin, touchScreenDevice, Qt::NoModifier, QList() <<