Make QEvent::setAccepted() virtual; set QEventPoints state the same

In Qt Quick, when we deliver an item-specific QTouchEvent that contains
only the subset of eventpoints that are inside the Item's bounds,
traditionally the Item can accept the event to tell the delivery logic
that the event is handled and doesn't need to be delivered further.
But an Item cannot be expected to have total scene awareness; so now,
the delivery is "done" only when all eventpoints in the original event
are accepted.  This behavior has been working well enough already due to
logic in QQuickWindow that iterates the points and accepts them if the
event is accepted; but it seems appropriate to move this enforcement
into QPointerEvent itself.  Making setAccepted() virtual gives us a
useful degree of freedom.

Event-handling code should alternatively use QEventPoint:setAccepted()
or QPointerEvent::setExclusiveGrabber() to take resonsibility for only
a subset of the touchpoints.

Another way to put it is that we treat QPointerEvent::setAccepted() as a
convenience method: accepting the QEventPoints is what counts (at least
in Qt Quick).

Change-Id: Icec42dc980f407bb5116f5c0852c051a4521105a
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
This commit is contained in:
Shawn Rutledge 2020-10-14 12:39:38 +02:00
parent 3310e13a17
commit 0e5bbf3507
5 changed files with 26 additions and 1 deletions

View File

@ -375,6 +375,10 @@ QEvent::~QEvent()
For convenience, the accept flag can also be set with accept(), For convenience, the accept flag can also be set with accept(),
and cleared with ignore(). and cleared with ignore().
\note Accepting a QPointerEvent implicitly
\l {QEventPoint::setAccepted()}{accepts} all the
\l {QPointerEvent::points()}{points} that the event carries.
*/ */
/*! /*!

View File

@ -300,7 +300,7 @@ public:
inline Type type() const { return static_cast<Type>(t); } inline Type type() const { return static_cast<Type>(t); }
inline bool spontaneous() const { return spont; } inline bool spontaneous() const { return spont; }
inline void setAccepted(bool accepted) { m_accept = accepted; } inline virtual void setAccepted(bool accepted) { m_accept = accepted; }
inline bool isAccepted() const { return m_accept; } inline bool isAccepted() const { return m_accept; }
inline void accept() { m_accept = true; } inline void accept() { m_accept = true; }

View File

@ -683,6 +683,16 @@ bool QPointerEvent::allPointsAccepted() const
return true; return true;
} }
/*!
\reimp
*/
void QPointerEvent::setAccepted(bool accepted)
{
QEvent::setAccepted(accepted);
for (auto &p : m_points)
p.setAccepted(accepted);
}
/*! /*!
Returns the source device from which this event originates. Returns the source device from which this event originates.

View File

@ -220,6 +220,7 @@ public:
virtual bool isUpdateEvent() const { return false; } virtual bool isUpdateEvent() const { return false; }
virtual bool isEndEvent() const { return false; } virtual bool isEndEvent() const { return false; }
bool allPointsAccepted() const; bool allPointsAccepted() const;
virtual void setAccepted(bool accepted) override;
QObject *exclusiveGrabber(const QEventPoint &point) const; QObject *exclusiveGrabber(const QEventPoint &point) const;
void setExclusiveGrabber(const QEventPoint &point, QObject *exclusiveGrabber); void setExclusiveGrabber(const QEventPoint &point, QObject *exclusiveGrabber);
QList<QPointer <QObject>> passiveGrabbers(const QEventPoint &point) const; QList<QPointer <QObject>> passiveGrabbers(const QEventPoint &point) const;

View File

@ -442,6 +442,7 @@ void tst_QTouchEvent::touchEventAcceptedByDefault()
touchEvent.ignore(); touchEvent.ignore();
QVERIFY(QApplication::sendEvent(&touchWidget, &touchEvent)); QVERIFY(QApplication::sendEvent(&touchWidget, &touchEvent));
QVERIFY(touchEvent.isAccepted()); QVERIFY(touchEvent.isAccepted());
QVERIFY(touchEvent.allPointsAccepted());
} }
// QGraphicsView // QGraphicsView
@ -470,6 +471,7 @@ void tst_QTouchEvent::touchEventAcceptedByDefault()
(QList<QEventPoint>() << touchPoint)); (QList<QEventPoint>() << touchPoint));
QVERIFY(QApplication::sendEvent(view.viewport(), &touchEvent)); QVERIFY(QApplication::sendEvent(view.viewport(), &touchEvent));
QVERIFY(touchEvent.isAccepted()); QVERIFY(touchEvent.isAccepted());
QVERIFY(touchEvent.allPointsAccepted());
QVERIFY(item.seenTouchBegin); QVERIFY(item.seenTouchBegin);
} }
} }
@ -496,6 +498,7 @@ void tst_QTouchEvent::touchBeginPropagatesWhenIgnored()
touchPoints); touchPoints);
QVERIFY(QApplication::sendEvent(&grandchild, &touchEvent)); QVERIFY(QApplication::sendEvent(&grandchild, &touchEvent));
QVERIFY(touchEvent.isAccepted()); QVERIFY(touchEvent.isAccepted());
QVERIFY(touchEvent.allPointsAccepted());
QVERIFY(grandchild.seenTouchBegin); QVERIFY(grandchild.seenTouchBegin);
QVERIFY(child.seenTouchBegin); QVERIFY(child.seenTouchBegin);
QVERIFY(!window.seenTouchBegin); QVERIFY(!window.seenTouchBegin);
@ -510,6 +513,7 @@ void tst_QTouchEvent::touchBeginPropagatesWhenIgnored()
touchEvent.ignore(); touchEvent.ignore();
QVERIFY(QApplication::sendEvent(&grandchild, &touchEvent)); QVERIFY(QApplication::sendEvent(&grandchild, &touchEvent));
QVERIFY(touchEvent.isAccepted()); QVERIFY(touchEvent.isAccepted());
QVERIFY(touchEvent.allPointsAccepted());
QVERIFY(!grandchild.seenTouchBegin); QVERIFY(!grandchild.seenTouchBegin);
QVERIFY(child.seenTouchBegin); QVERIFY(child.seenTouchBegin);
QVERIFY(!window.seenTouchBegin); QVERIFY(!window.seenTouchBegin);
@ -544,6 +548,7 @@ void tst_QTouchEvent::touchBeginPropagatesWhenIgnored()
(QList<QEventPoint>() << touchPoint)); (QList<QEventPoint>() << touchPoint));
QVERIFY(QApplication::sendEvent(view.viewport(), &touchEvent)); QVERIFY(QApplication::sendEvent(view.viewport(), &touchEvent));
QVERIFY(touchEvent.isAccepted()); QVERIFY(touchEvent.isAccepted());
QVERIFY(touchEvent.allPointsAccepted());
QVERIFY(grandchild.seenTouchBegin); QVERIFY(grandchild.seenTouchBegin);
QVERIFY(child.seenTouchBegin); QVERIFY(child.seenTouchBegin);
QVERIFY(!root.seenTouchBegin); QVERIFY(!root.seenTouchBegin);
@ -578,6 +583,7 @@ void tst_QTouchEvent::touchBeginPropagatesWhenIgnored()
(QList<QEventPoint>() << touchPoint)); (QList<QEventPoint>() << touchPoint));
QVERIFY(QApplication::sendEvent(view.viewport(), &touchEvent)); QVERIFY(QApplication::sendEvent(view.viewport(), &touchEvent));
QVERIFY(touchEvent.isAccepted()); QVERIFY(touchEvent.isAccepted());
QVERIFY(touchEvent.allPointsAccepted());
QVERIFY(!grandchild.seenTouchBegin); QVERIFY(!grandchild.seenTouchBegin);
QVERIFY(child.seenTouchBegin); QVERIFY(child.seenTouchBegin);
QVERIFY(!root.seenTouchBegin); QVERIFY(!root.seenTouchBegin);
@ -604,6 +610,7 @@ void tst_QTouchEvent::touchUpdateAndEndNeverPropagate()
touchPoints); touchPoints);
QVERIFY(QApplication::sendEvent(&child, &touchBeginEvent)); QVERIFY(QApplication::sendEvent(&child, &touchBeginEvent));
QVERIFY(touchBeginEvent.isAccepted()); QVERIFY(touchBeginEvent.isAccepted());
QVERIFY(touchBeginEvent.allPointsAccepted());
QVERIFY(child.seenTouchBegin); QVERIFY(child.seenTouchBegin);
QVERIFY(!window.seenTouchBegin); QVERIFY(!window.seenTouchBegin);
@ -614,6 +621,7 @@ void tst_QTouchEvent::touchUpdateAndEndNeverPropagate()
touchPoints); touchPoints);
QVERIFY(QApplication::sendEvent(&child, &touchUpdateEvent)); QVERIFY(QApplication::sendEvent(&child, &touchUpdateEvent));
QVERIFY(!touchUpdateEvent.isAccepted()); QVERIFY(!touchUpdateEvent.isAccepted());
QVERIFY(!touchBeginEvent.allPointsAccepted());
QVERIFY(child.seenTouchUpdate); QVERIFY(child.seenTouchUpdate);
QVERIFY(!window.seenTouchUpdate); QVERIFY(!window.seenTouchUpdate);
@ -624,6 +632,7 @@ void tst_QTouchEvent::touchUpdateAndEndNeverPropagate()
touchPoints); touchPoints);
QVERIFY(QApplication::sendEvent(&child, &touchEndEvent)); QVERIFY(QApplication::sendEvent(&child, &touchEndEvent));
QVERIFY(!touchEndEvent.isAccepted()); QVERIFY(!touchEndEvent.isAccepted());
QVERIFY(!touchBeginEvent.allPointsAccepted());
QVERIFY(child.seenTouchEnd); QVERIFY(child.seenTouchEnd);
QVERIFY(!window.seenTouchEnd); QVERIFY(!window.seenTouchEnd);
} }
@ -657,6 +666,7 @@ void tst_QTouchEvent::touchUpdateAndEndNeverPropagate()
(QList<QEventPoint>() << touchPoint)); (QList<QEventPoint>() << touchPoint));
QVERIFY(QApplication::sendEvent(view.viewport(), &touchBeginEvent)); QVERIFY(QApplication::sendEvent(view.viewport(), &touchBeginEvent));
QVERIFY(touchBeginEvent.isAccepted()); QVERIFY(touchBeginEvent.isAccepted());
QVERIFY(touchBeginEvent.allPointsAccepted());
QVERIFY(child.seenTouchBegin); QVERIFY(child.seenTouchBegin);
QVERIFY(!root.seenTouchBegin); QVERIFY(!root.seenTouchBegin);