Remove QEventPoint::event() in favor of device()

event()->device() was the most common use case anyway.

The idea that the "parent" of a QEventPoint is the QPointerEvent
interferes with the ability to copy and move event objects: the parent
pointers are dangling unless we use the QPointerEvent subclass
destructors to set the points' parents to null.  Since there is no move
constructor, even returning a QEventPoint from a function by value
results in destroying the temporary instance and copying it to the
caller's space.  So the parent pointer is often useless, unless we do
even more work to maintain it when the event moves.

If we optimize to avoid copying QEventPoints too much (and perhaps
enable exposing _mutable_ points to QML) by storing reusable instances in
QPointingDevice (which is the current plan), then the actual parent will
no longer be the event.  Events are usually stack-allocated, thus
temporary and intended to be movable.

Change-Id: I24b648dcc046fc79d2401c781f1fda6cb00f47b0
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
This commit is contained in:
Shawn Rutledge 2020-08-06 17:28:06 +02:00
parent 0c52e600b3
commit 38806273e5
4 changed files with 17 additions and 18 deletions

View File

@ -65,9 +65,7 @@ Q_LOGGING_CATEGORY(lcPointerGrab, "qt.pointer.grab")
static const QString pointDeviceName(const QEventPoint *point) static const QString pointDeviceName(const QEventPoint *point)
{ {
if (!point->event()) const auto device = point->device();
return {};
auto device = point->event()->device();
QString deviceName = (device ? device->name() : QLatin1String("null device")); QString deviceName = (device ? device->name() : QLatin1String("null device"));
deviceName.resize(16, u' '); // shorten, and align in case of sequential output deviceName.resize(16, u' '); // shorten, and align in case of sequential output
return deviceName; return deviceName;
@ -228,13 +226,14 @@ QInputEvent::~QInputEvent()
/*! /*!
\internal \internal
Constructs an invalid event point with the given \a id and \a parent. Constructs an invalid event point with the given \a id and the \a device
from which it originated.
This acts as a default constructor in usages like QMap<int, QEventPoint>, This acts as a default constructor in usages like QMap<int, QEventPoint>,
as in qgraphicsscene_p.h. as in qgraphicsscene_p.h.
*/ */
QEventPoint::QEventPoint(int id, const QPointerEvent *parent) QEventPoint::QEventPoint(int id, const QPointingDevice *device)
: m_parent(parent), m_pointId(id), m_state(State::Unknown), m_accept(false), m_stationaryWithModifiedProperty(false), m_reserved(0) : m_device(device), m_pointId(id), m_state(State::Unknown), m_accept(false), m_stationaryWithModifiedProperty(false), m_reserved(0)
{ {
} }
@ -323,7 +322,7 @@ void QEventPoint::clearPassiveGrabbers()
QPointF QEventPoint::normalizedPos() const QPointF QEventPoint::normalizedPos() const
{ {
auto geom = event()->device()->availableVirtualGeometry(); auto geom = m_device->availableVirtualGeometry();
if (geom.isNull()) if (geom.isNull())
return QPointF(); return QPointF();
return (globalPosition() - geom.topLeft()) / geom.width(); return (globalPosition() - geom.topLeft()) / geom.width();
@ -331,7 +330,7 @@ QPointF QEventPoint::normalizedPos() const
QPointF QEventPoint::startNormalizedPos() const QPointF QEventPoint::startNormalizedPos() const
{ {
auto geom = event()->device()->availableVirtualGeometry(); auto geom = m_device->availableVirtualGeometry();
if (geom.isNull()) if (geom.isNull())
return QPointF(); return QPointF();
return (globalPressPosition() - geom.topLeft()) / geom.width(); return (globalPressPosition() - geom.topLeft()) / geom.width();
@ -339,7 +338,7 @@ QPointF QEventPoint::startNormalizedPos() const
QPointF QEventPoint::lastNormalizedPos() const QPointF QEventPoint::lastNormalizedPos() const
{ {
auto geom = event()->device()->availableVirtualGeometry(); auto geom = m_device->availableVirtualGeometry();
if (geom.isNull()) if (geom.isNull())
return QPointF(); return QPointF();
return (globalLastPosition() - geom.topLeft()) / geom.width(); return (globalLastPosition() - geom.topLeft()) / geom.width();
@ -369,7 +368,7 @@ const QPointingDevice *QPointerEvent::pointingDevice() const
QSinglePointEvent::QSinglePointEvent(QEvent::Type type, const QPointingDevice *dev, const QPointF &localPos, const QPointF &scenePos, 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) const QPointF &globalPos, Qt::MouseButton button, Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers)
: QPointerEvent(type, dev, modifiers), : QPointerEvent(type, dev, modifiers),
m_point(0, this), m_point(0, dev),
m_button(button), m_button(button),
m_mouseState(buttons), m_mouseState(buttons),
m_source(Qt::MouseEventNotSynthesized), m_source(Qt::MouseEventNotSynthesized),
@ -4243,7 +4242,7 @@ QTouchEvent::QTouchEvent(QEvent::Type eventType,
{ {
for (QEventPoint &point : m_touchPoints) { for (QEventPoint &point : m_touchPoints) {
m_touchPointStates |= point.state(); m_touchPointStates |= point.state();
QMutableEventPoint::from(point).setParent(this); QMutableEventPoint::from(point).setDevice(device);
} }
} }
@ -4266,7 +4265,7 @@ QTouchEvent::QTouchEvent(QEvent::Type eventType,
m_touchPoints(touchPoints) m_touchPoints(touchPoints)
{ {
for (QEventPoint &point : m_touchPoints) for (QEventPoint &point : m_touchPoints)
QMutableEventPoint::from(point).setParent(this); QMutableEventPoint::from(point).setDevice(device);
} }
/*! /*!

View File

@ -106,10 +106,9 @@ public:
Q_DECLARE_FLAGS(States, State) Q_DECLARE_FLAGS(States, State)
Q_FLAG(States) Q_FLAG(States)
QEventPoint(int id = -1, const QPointerEvent *parent = nullptr); QEventPoint(int id = -1, const QPointingDevice *device = nullptr);
QEventPoint(int pointId, State state, const QPointF &scenePosition, const QPointF &globalPosition); QEventPoint(int pointId, State state, const QPointF &scenePosition, const QPointF &globalPosition);
const QPointerEvent *event() const { return m_parent; }
QPointF position() const { return m_pos; } QPointF position() const { return m_pos; }
QPointF pressPosition() const { return m_globalPressPos - m_globalPos + m_pos; } QPointF pressPosition() const { return m_globalPressPos - m_globalPos + m_pos; }
QPointF grabPosition() const { return m_globalGrabPos - m_globalPos + m_pos; } QPointF grabPosition() const { return m_globalGrabPos - m_globalPos + m_pos; }
@ -152,6 +151,7 @@ public:
#endif // QT_DEPRECATED_SINCE(6, 0) #endif // QT_DEPRECATED_SINCE(6, 0)
QVector2D velocity() const { return m_velocity; } QVector2D velocity() const { return m_velocity; }
State state() const { return m_state; } State state() const { return m_state; }
const QPointingDevice *device() const { return m_device; }
int id() const { return m_pointId; } int id() const { return m_pointId; }
QPointingDeviceUniqueId uniqueId() const { return m_uniqueId; } QPointingDeviceUniqueId uniqueId() const { return m_uniqueId; }
ulong pressTimestamp() const { return m_pressTimestamp; } ulong pressTimestamp() const { return m_pressTimestamp; }
@ -169,7 +169,7 @@ public:
void clearPassiveGrabbers(); void clearPassiveGrabbers();
protected: protected:
const QPointerEvent *m_parent = nullptr; const QPointingDevice *m_device = nullptr;
QPointF m_pos, m_scenePos, m_globalPos, QPointF m_pos, m_scenePos, m_globalPos,
m_globalPressPos, m_globalGrabPos, m_globalLastPos; m_globalPressPos, m_globalGrabPos, m_globalLastPos;
qreal m_pressure = 1; qreal m_pressure = 1;
@ -178,7 +178,7 @@ protected:
QVector2D m_velocity; QVector2D m_velocity;
QPointer<QObject> m_exclusiveGrabber; QPointer<QObject> m_exclusiveGrabber;
QList<QPointer <QObject> > m_passiveGrabbers; QList<QPointer <QObject> > m_passiveGrabbers;
ulong m_timestamp = 0; // redundant with m_parent->timestamp(), but keeps timeHeld() working in a saved copy ulong m_timestamp = 0;
ulong m_pressTimestamp = 0; ulong m_pressTimestamp = 0;
QPointingDeviceUniqueId m_uniqueId; QPointingDeviceUniqueId m_uniqueId;
int m_pointId = -1; int m_pointId = -1;

View File

@ -84,7 +84,7 @@ public:
void setId(int pointId) { m_pointId = pointId; } void setId(int pointId) { m_pointId = pointId; }
void setParent(const QPointerEvent *p) { m_parent = p; } void setDevice(const QPointingDevice *device) { m_device = device; }
void setTimestamp(const ulong t) { m_timestamp = t; } void setTimestamp(const ulong t) { m_timestamp = t; }

View File

@ -79,7 +79,7 @@ public:
seenTouchBegin = !seenTouchBegin && !seenTouchUpdate && !seenTouchEnd; seenTouchBegin = !seenTouchBegin && !seenTouchUpdate && !seenTouchEnd;
auto touchEvent = static_cast<QTouchEvent *>(event); auto touchEvent = static_cast<QTouchEvent *>(event);
touchBeginPoints = touchEvent->touchPoints(); touchBeginPoints = touchEvent->touchPoints();
Q_ASSERT(touchBeginPoints.first().event() == event); Q_ASSERT(touchBeginPoints.first().device() == touchEvent->pointingDevice());
for (const QEventPoint &pt : touchEvent->touchPoints()) for (const QEventPoint &pt : touchEvent->touchPoints())
lastNormalizedPositions << pt.normalizedPos(); lastNormalizedPositions << pt.normalizedPos();
timestamp = touchEvent->timestamp(); timestamp = touchEvent->timestamp();