summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVolker Hilsheimer <volker.hilsheimer@qt.io>2020-11-05 18:11:56 +0100
committerVolker Hilsheimer <volker.hilsheimer@qt.io>2020-11-07 06:24:28 +0100
commitbdec189ecbc2cabbfa803a571b49533f190f053d (patch)
treea061307e207cfbdb989e463c9535208a822fab78
parent1c6d6cbb62c5e93cbcad2d740c3b0ed01095618c (diff)
Move QEventPoint and QPointingDeviceUniqueId out of qevent
qevent.h/cpp are huge already, no need for more classes. Move QEventPoint into new qeventpoint.h/cpp files, and QPointingDeviceUniqueId into qpointingdevice.cpp; the class is already declared in qpointingdevice.h. Move the documentation of QEventPoint APIs next to the implementation, and document all APIs as properties. Add Q_PROPERTY macro where missing. QEventPoint::device needs a workaround of qdoc due to the type being a pointer-to-const; qdoc doesn't know how to tie a \property to it, but documents it correctly. While at it, move the logging category declarations to the header matching the .cpp file where they are defined. Change-Id: I096e609edbb760b5686d577e7fe47eea0807904e Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
-rw-r--r--src/gui/.prev_CMakeLists.txt1
-rw-r--r--src/gui/CMakeLists.txt1
-rw-r--r--src/gui/kernel/kernel.pri3
-rw-r--r--src/gui/kernel/qevent.cpp648
-rw-r--r--src/gui/kernel/qevent.h110
-rw-r--r--src/gui/kernel/qevent_p.h134
-rw-r--r--src/gui/kernel/qeventpoint.cpp664
-rw-r--r--src/gui/kernel/qeventpoint.h172
-rw-r--r--src/gui/kernel/qeventpoint_p.h200
-rw-r--r--src/gui/kernel/qinputdevice.cpp4
-rw-r--r--src/gui/kernel/qpointingdevice.cpp91
-rw-r--r--src/gui/kernel/qpointingdevice_p.h3
-rw-r--r--src/gui/kernel/qwindowsysteminterface_p.h3
13 files changed, 1140 insertions, 894 deletions
diff --git a/src/gui/.prev_CMakeLists.txt b/src/gui/.prev_CMakeLists.txt
index 981a88c603..f86e2bd89f 100644
--- a/src/gui/.prev_CMakeLists.txt
+++ b/src/gui/.prev_CMakeLists.txt
@@ -35,6 +35,7 @@ qt_internal_add_module(Gui
image/qxpmhandler.cpp image/qxpmhandler_p.h
kernel/qclipboard.cpp kernel/qclipboard.h
kernel/qcursor.cpp kernel/qcursor.h kernel/qcursor_p.h
+ kernel/qeventpoint.cpp kernel/qeventpoint.h kernel/qeventpoint_p.h
kernel/qevent.cpp kernel/qevent.h kernel/qevent_p.h
kernel/qgenericplugin.cpp kernel/qgenericplugin.h
kernel/qgenericpluginfactory.cpp kernel/qgenericpluginfactory.h
diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt
index 5d7037079a..1d4d44894b 100644
--- a/src/gui/CMakeLists.txt
+++ b/src/gui/CMakeLists.txt
@@ -86,6 +86,7 @@ qt_internal_add_module(Gui
image/qxpmhandler.cpp image/qxpmhandler_p.h
kernel/qclipboard.cpp kernel/qclipboard.h
kernel/qcursor.cpp kernel/qcursor.h kernel/qcursor_p.h
+ kernel/qeventpoint.cpp kernel/qeventpoint.h kernel/qeventpoint_p.h
kernel/qevent.cpp kernel/qevent.h kernel/qevent_p.h
kernel/qgenericplugin.cpp kernel/qgenericplugin.h
kernel/qgenericpluginfactory.cpp kernel/qgenericpluginfactory.h
diff --git a/src/gui/kernel/kernel.pri b/src/gui/kernel/kernel.pri
index 48fd18f8d2..f6f6002f76 100644
--- a/src/gui/kernel/kernel.pri
+++ b/src/gui/kernel/kernel.pri
@@ -48,6 +48,8 @@ HEADERS += \
kernel/qcursor_p.h \
kernel/qevent.h \
kernel/qevent_p.h \
+ kernel/qeventpoint.h \
+ kernel/qeventpoint_p.h \
kernel/qinputdevice.h \
kernel/qinputdevice_p.h \
kernel/qinputmethod.h \
@@ -108,6 +110,7 @@ SOURCES += \
kernel/qclipboard.cpp \
kernel/qcursor.cpp \
kernel/qevent.cpp \
+ kernel/qeventpoint.cpp \
kernel/qinputdevice.cpp \
kernel/qinputmethod.cpp \
kernel/qinternalmimedata.cpp \
diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp
index a4e44f5b8d..9d27961071 100644
--- a/src/gui/kernel/qevent.cpp
+++ b/src/gui/kernel/qevent.cpp
@@ -61,10 +61,6 @@
QT_BEGIN_NAMESPACE
-Q_LOGGING_CATEGORY(lcPointerGrab, "qt.pointer.grab")
-Q_LOGGING_CATEGORY(lcPointerVel, "qt.pointer.velocity")
-Q_LOGGING_CATEGORY(lcEPDetach, "qt.pointer.eventpoint.detach")
-
/*!
\class QEnterEvent
\ingroup events
@@ -226,392 +222,6 @@ QInputEvent::~QInputEvent()
*/
/*!
- \internal
- 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>,
- as in qgraphicsscene_p.h.
-*/
-QEventPoint::QEventPoint(int id, const QPointingDevice *device)
- : d(new QEventPointPrivate(id, device)) {}
-
-/*!
- Constructs an event point with the given \a pointId, \a state,
- \a scenePosition and \a globalPosition.
-*/
-QEventPoint::QEventPoint(int pointId, State state, const QPointF &scenePosition, const QPointF &globalPosition)
- : d(new QEventPointPrivate(pointId, state, scenePosition, globalPosition)) {}
-
-/*!
- Constructs an event point by making a shallow copy of \a other.
-*/
-QEventPoint::QEventPoint(const QEventPoint &other)
- : d(other.d)
-{
- if (d)
- d->refCount++;
-}
-
-/*!
- Assigns \a other to this event point and returns a reference to this
- event point.
-*/
-QEventPoint &QEventPoint::operator=(const QEventPoint &other)
-{
- if (other.d)
- other.d->refCount++;
- if (d && !(--d->refCount))
- delete d;
- d = other.d;
- return *this;
-}
-
-/*!
- \fn QEventPoint::QEventPoint(QEventPoint &&other) noexcept
-
- Constructs an event point by moving \a other.
-*/
-
-/*!
- \fn QEventPoint &QEventPoint::operator=(QEventPoint &&other) noexcept
-
- Move-assigns \a other to this event point instance.
-*/
-
-/*!
- Returns \c true if this event point is equal to \a other, otherwise
- return \c false.
-*/
-bool QEventPoint::operator==(const QEventPoint &other) const noexcept
-{
- if (d == other.d)
- return true;
- if (!d || !other.d)
- return false;
- return *d == *other.d;
-}
-
-/*!
- \fn bool QEventPoint::operator!=(const QEventPoint &other) const noexcept
-
- Returns \c true if this event point is not equal to \a other, otherwise
- return \c false.
-*/
-
-/*!
- Destroys the event point.
-*/
-QEventPoint::~QEventPoint()
-{
- if (d && !(--d->refCount))
- delete d;
-}
-
-QPointF QEventPoint::position() const
-{ return d->pos; }
-
-QPointF QEventPoint::pressPosition() const
-{ return d->globalPressPos - d->globalPos + d->pos; }
-
-QPointF QEventPoint::grabPosition() const
-{ return d->globalGrabPos - d->globalPos + d->pos; }
-
-QPointF QEventPoint::lastPosition() const
-{ return d->globalLastPos - d->globalPos + d->pos; }
-
-QPointF QEventPoint::scenePosition() const
-{ return d->scenePos; }
-
-QPointF QEventPoint::scenePressPosition() const
-{ return d->globalPressPos - d->globalPos + d->scenePos; }
-
-QPointF QEventPoint::sceneGrabPosition() const
-{ return d->globalGrabPos - d->globalPos + d->scenePos; }
-
-QPointF QEventPoint::sceneLastPosition() const
-{ return d->globalLastPos - d->globalPos + d->scenePos; }
-
-QPointF QEventPoint::globalPosition() const
-{ return d->globalPos; }
-
-QPointF QEventPoint::globalPressPosition() const
-{ return d->globalPressPos; }
-
-QPointF QEventPoint::globalGrabPosition() const
-{ return d->globalGrabPos; }
-
-QPointF QEventPoint::globalLastPosition() const
-{ return d->globalLastPos; }
-
-QVector2D QEventPoint::velocity() const
-{ return d->velocity; }
-
-QEventPoint::State QEventPoint::state() const
-{ return d->state; }
-
-const QPointingDevice *QEventPoint::device() const
-{ return d->device; }
-
-int QEventPoint::id() const
-{ return d->pointId; }
-
-QPointingDeviceUniqueId QEventPoint::uniqueId() const
-{ return d->uniqueId; }
-
-ulong QEventPoint::timestamp() const
-{ return d->timestamp; }
-
-ulong QEventPoint::pressTimestamp() const
-{ return d->pressTimestamp; }
-
-qreal QEventPoint::timeHeld() const
-{ return (d->timestamp - d->pressTimestamp) / qreal(1000); }
-
-qreal QEventPoint::pressure() const
-{ return d->pressure; }
-
-qreal QEventPoint::rotation() const
-{ return d->rotation; }
-
-QSizeF QEventPoint::ellipseDiameters() const
-{ return d->ellipseDiameters; }
-
-bool QEventPoint::isAccepted() const
-{ return d->accept; }
-
-/*!
- Returns the time from the previous QPointerEvent that contained this point.
-
- \sa globalLastPosition()
-*/
-ulong QEventPoint::lastTimestamp() const
-{ return d->lastTimestamp; }
-
-/*!
- Sets the accepted state of the point to \a accepted.
-
- In widget-based applications, this function is not used so far, because
- it's only meaningful for a widget to accept or reject a complete QInputEvent.
-
- In Qt Quick however, it's normal for an Item or Event Handler to accept
- only the individual points in a QTouchEvent that are actually participating
- in a gesture, while other points can be delivered to other items or
- handlers. For the sake of consistency, that applies to any QPointerEvent;
- and delivery is done only when all points in a QPointerEvent have been
- accepted.
-
- \sa QEvent::setAccepted()
-*/
-void QEventPoint::setAccepted(bool accepted)
-{
- d->accept = accepted;
-}
-
-/*!
- \obsolete
- \fn QPointF QPointerEvent::normalizedPos() const
-
- Deprecated since Qt 6.0. Use normalizedPosition() instead.
-*/
-
-/*!
- Returns the normalized position of this point.
-
- The coordinates are calculated by transforming globalPosition() into the
- space of QInputDevice::availableVirtualGeometry(), i.e. \c (0, 0) is the
- top-left corner and \c (1, 1) is the bottom-right corner.
-
- \sa globalPosition()
-*/
-QPointF QEventPoint::normalizedPosition() const
-{
- auto geom = d->device->availableVirtualGeometry();
- if (geom.isNull())
- return QPointF();
- return (globalPosition() - geom.topLeft()) / geom.width();
-}
-
-/*!
- \obsolete
- Deprecated since Qt 6.0. Use globalPressPosition() instead.
-
- Returns the normalized press position of this point.
-*/
-QPointF QEventPoint::startNormalizedPos() const
-{
- auto geom = d->device->availableVirtualGeometry();
- if (geom.isNull())
- return QPointF();
- return (globalPressPosition() - geom.topLeft()) / geom.width();
-}
-
-/*!
- \obsolete
- Deprecated since Qt 6.0. Use globalLastPosition() instead.
-
- Returns the normalized position of this point from the previous press or
- move event.
-
- The coordinates are normalized to QInputDevice::availableVirtualGeometry(),
- i.e. \c (0, 0) is the top-left corner and \c (1, 1) is the bottom-right corner.
-
- \sa normalizedPos(), startNormalizedPos()
-*/
-QPointF QEventPoint::lastNormalizedPos() const
-{
- auto geom = d->device->availableVirtualGeometry();
- if (geom.isNull())
- return QPointF();
- return (globalLastPosition() - geom.topLeft()) / geom.width();
-}
-
-
-/*! \internal
- This class is explicitly shared, which means if you construct an event and
- then the point(s) that it holds are modified before the event is delivered,
- the event will be seen to hold the modified points. The workaround is that
- any code which modifies an eventpoint that could already be included in an
- event, or code that wants to save an eventpoint for later, has
- responsibility to detach before calling any setters, so as to hold and
- modify an independent copy. (The independent copy can then be used in a
- subsequent event.) If detaching is unnecessary, because refCount shows that
- there is only one QEventPoint referring to the QEventPointPrivate instance,
- this function does nothing.
-*/
-void QMutableEventPoint::detach()
-{
- if (d->refCount == 1)
- return; // no need: there is only one QEventPoint using it
- qCDebug(lcEPDetach) << "detaching: refCount" << d->refCount << this;
- auto old = d;
- d = new QEventPointPrivate(*d);
- d->refCount = 1;
- --old->refCount;
-}
-
-/*! \internal
- Update current state from the given \a other point, assuming that this
- instance contains state from the previous event and \a other contains new
- values that came in from a device.
-
- That is: global position and other valuators will be updated, but
- the following properties will not be updated:
-
- \list
- \li other properties that are not likely to be set after a fresh touchpoint
- has been received from a device
- \li properties that should be persistent between events (such as grabbers)
- \endlist
-*/
-void QMutableEventPoint::updateFrom(const QEventPoint &other)
-{
- detach();
- setPressure(other.pressure());
-
- switch (other.state()) {
- case QEventPoint::State::Pressed:
- setGlobalPressPosition(other.globalPosition());
- setGlobalLastPosition(other.globalPosition());
- if (pressure() < 0)
- setPressure(1);
- break;
-
- case QEventPoint::State::Released:
- if (globalPosition() != other.globalPosition())
- setGlobalLastPosition(globalPosition());
- setPressure(0);
- break;
-
- default: // update or stationary
- if (globalPosition() != other.globalPosition())
- setGlobalLastPosition(globalPosition());
- if (pressure() < 0)
- setPressure(1);
- break;
- }
-
- setState(other.state());
- setPosition(other.position());
- setScenePosition(other.scenePosition());
- setGlobalPosition(other.globalPosition());
- setEllipseDiameters(other.ellipseDiameters());
- setRotation(other.rotation());
- setVelocity(other.velocity());
-}
-
-/*! \internal
- Set the timestamp from the event that updated this point's positions,
- and calculate a new value for velocity().
-
- The velocity calculation is done here because none of the QPointerEvent
- subclass constructors take the timestamp directly, and because
- QGuiApplication traditionally constructs an event first and then sets its
- timestamp (see for example QGuiApplicationPrivate::processMouseEvent()).
-
- This function looks up the corresponding instance in QPointingDevicePrivate::activePoints,
- and assumes that its timestamp() still holds the previous time when this point
- was updated, its velocity() holds this point's last-known velocity, and
- its globalPosition() and globalLastPosition() hold this point's current
- and previous positions, respectively. We assume timestamps are in milliseconds.
-
- The velocity calculation is skipped if the platform has promised to
- provide velocities already by setting the QInputDevice::Velocity capability.
-*/
-void QMutableEventPoint::setTimestamp(const ulong t)
-{
- // On mouse press, if the mouse has moved from its last-known location,
- // QGuiApplicationPrivate::processMouseEvent() sends first a mouse move and
- // then a press. Both events will get the same timestamp. So we need to set
- // the press timestamp and position even when the timestamp isn't advancing,
- // but skip setting lastTimestamp and velocity because those need a time delta.
- if (state() == QEventPoint::State::Pressed) {
- d->pressTimestamp = t;
- d->globalPressPos = d->globalPos;
- }
- if (d->timestamp == t)
- return;
- detach();
- if (device()) {
- // get the persistent instance out of QPointingDevicePrivate::activePoints
- // (which sometimes might be the same as this instance)
- QEventPointPrivate *pd = QPointingDevicePrivate::get(
- const_cast<QPointingDevice *>(d->device))->pointById(id())->eventPoint.d;
- if (t > pd->timestamp) {
- pd->lastTimestamp = pd->timestamp;
- pd->timestamp = t;
- if (state() == QEventPoint::State::Pressed)
- pd->pressTimestamp = t;
- if (pd->lastTimestamp > 0 && !device()->capabilities().testFlag(QInputDevice::Capability::Velocity)) {
- // calculate instantaneous velocity according to time and distance moved since the previous point
- QVector2D newVelocity = QVector2D(pd->globalPos - pd->globalLastPos) / (t - pd->lastTimestamp) * 1000;
- // VERY simple kalman filter: does a weighted average
- // where the older velocities get less and less significant
- static const float KalmanGain = 0.7f;
- pd->velocity = newVelocity * KalmanGain + pd->velocity * (1.0f - KalmanGain);
- qCDebug(lcPointerVel) << "velocity" << newVelocity << "filtered" << pd->velocity <<
- "based on movement" << pd->globalLastPos << "->" << pd->globalPos <<
- "over time" << pd->lastTimestamp << "->" << pd->timestamp;
- }
- if (d != pd) {
- d->lastTimestamp = pd->lastTimestamp;
- d->velocity = pd->velocity;
- }
- }
- }
- d->timestamp = t;
-}
-
-/*! \internal
- void QMutableEventPoint::setPosition(const QPointF &pos)
- Sets the localized position.
- Often events need to be localized before delivery to specific widgets or
- items. This can be done directly, or in a copy (for which we have a copy
- constructor), depending on whether the original point needs to be retained.
- Usually it's calculated by mapping scenePosition() to the target anyway.
-*/
-
-/*!
\class QPointerEvent
\since 6.0
\inmodule QtGui
@@ -868,7 +478,7 @@ void QPointerEvent::clearPassiveGrabbers(const QEventPoint &point)
Returns the position of the point in this event, relative to the window or
scene.
- \sa QEventPoint::scenePosition()
+ \sa QEventPoint::scenePosition
*/
/*! \fn QPointF QSinglePointEvent::globalPosition() const
@@ -4843,177 +4453,6 @@ bool QTouchEvent::isEndEvent() const
\sa QPointerEvent::point(), QPointerEvent::pointCount()
*/
-/*! \class QEventPoint
- \brief The QEventPoint class provides information about a point in a QPointerEvent.
- \since 6.0
- \inmodule QtGui
-*/
-
-/*!
- \enum QEventPoint::State
-
- Specifies the state of this event point.
-
- \value Unknown
- Unknown state.
-
- \value Stationary
- The event point did not move.
-
- \value Pressed
- The touch point or button is pressed.
-
- \value Updated
- The event point was updated.
-
- \value Released
- The touch point or button was released.
-*/
-
-/*! \fn int QEventPoint::id() const
-
- Returns the ID number of this event point.
-
- \note Do not assume that ID numbers start at zero or that they are
- sequential. Such an assumption is often false due to the way
- the underlying drivers work.
-*/
-
-/*! \fn QPointingDeviceUniqueId QEventPoint::uniqueId() const
-
- Returns the unique ID of this point or token, if any.
-
- It is often invalid (see \l {QPointingDeviceUniqueId::isValid()} {isValid()}),
- because touchscreens cannot uniquely identify fingers.
-
- When it comes from a QTabletEvent, it identifies the serial number of the
- stylus in use.
-
- It may identify a specific token (fiducial object) when the TUIO driver is
- in use with a touchscreen that supports them.
-*/
-
-/*! \fn QEventPoint::State QEventPoint::state() const
- Returns the current state of this point.
-*/
-
-/*! \fn QPointF QEventPoint::position() const
-
- Returns the position of this point, relative to the widget
- or item that received the event.
-*/
-
-/*! \fn QPointF QEventPoint::pos() const
- \obsolete
- Deprecated since Qt 6.0. Use position() instead.
-
- Returns the position of this point, relative to the widget
- or item that received the event.
-*/
-
-/*! \fn QPointF QEventPoint::scenePosition() const
- Returns the position of this point relative to the window or scene.
-
- The scene position is the position relative to QQuickWindow if handled in QQuickItem::event(),
- in QGraphicsScene coordinates if handled by an override of QGraphicsItem::touchEvent(),
- or the window position in widget applications.
-
- \sa scenePressPosition(), position(), globalPosition()
-*/
-
-/*! \fn QPointF QEventPoint::globalPosition() const
- Returns the position of this point on the screen or virtual desktop.
-
- \sa globalPressPosition(), position(), scenePosition()
-*/
-
-/*! \fn QPointF QEventPoint::pressPosition() const
- Returns the position at which this point was pressed, relative to the
- widget or item that received the event.
-
- \sa position()
-*/
-
-/*! \fn QPointF QEventPoint::scenePressPosition() const
- Returns the scene position at which this point was pressed.
-
- The scene position is the position relative to QQuickWindow if handled in QQuickItem::event(),
- in QGraphicsScene coordinates if handled by an override of QGraphicsItem::touchEvent(),
- or the window position in widget applications.
-
- \sa scenePosition(), pressPosition(), globalPressPosition()
-*/
-
-/*! \fn QPointF QEventPoint::globalPressPosition() const
- Returns the position at which this point was pressed on the screen or virtual desktop.
-
- \sa globalPosition(), pressPosition(), scenePressPosition()
-*/
-
-/*! \fn QPointF QEventPoint::lastPosition() const
- Returns the position of this point from the previous press or move event,
- relative to the widget or QGraphicsItem that received the event.
-
- \sa position(), pressPosition()
-*/
-
-/*! \fn QPointF QEventPoint::sceneLastPosition() const
- Returns the scene position of this point from the previous press or move event.
-
- The scene position is the position in QGraphicsScene coordinates
- if the QTouchEvent is handled by a QGraphicsItem::touchEvent()
- reimplementation, and identical to the screen position for
- widgets.
-
- \sa scenePosition(), scenePressPosition()
-*/
-
-/*! \fn qreal QEventPoint::pressure() const
- Returns the pressure of this point. The return value is in
- the range \c 0.0 to \c 1.0.
-*/
-
-/*! \fn qreal QEventPoint::rotation() const
-
- Returns the angular orientation of this point. The return value is in degrees,
- where zero (the default) indicates the finger, token or stylus is pointing upwards,
- a negative angle means it's rotated to the left, and a positive angle means
- it's rotated to the right. Most touchscreens do not detect rotation, so
- zero is the most common value.
-*/
-
-/*! \fn QSizeF QEventPoint::ellipseDiameters() const
-
- Returns the width and height of the bounding ellipse of the touch point.
- The return value is in logical pixels. Most touchscreens do not detect the
- shape of the contact point, and no mice or tablet devices can detect it,
- so a null size is the most common value. On some touchscreens the diameters
- may be nonzero and always equal (the ellipse is approximated as a circle).
-*/
-
-/*!
- \fn QVector2D QEventPoint::velocity() const
- Returns a velocity vector, in units of pixels per second, in the coordinate
- system of the screen or desktop.
-
- \note If the device's capabilities include QInputDevice::Velocity, it means
- velocity comes from the operating system (perhaps the touch hardware or
- driver provides it). But usually the \c Velocity capability is not set,
- indicating that the velocity is calculated by Qt, using a simple Kalman
- filter to provide a smoothed average velocity rather than an instantaneous
- value. Effectively it tells how fast and in what direction the user has
- been dragging this point over the last few events, with the most recent
- event having the strongest influence.
-
- \sa QInputDevice::capabilities(), QInputEvent::device()
-*/
-
-/*! \fn ulong QEventPoint::timestamp() const
- Returns the most recent time at which this point was included in a QPointerEvent.
-
- \sa QPointerEvent::timestamp()
-*/
-
/*!
\class QScrollPrepareEvent
\since 4.8
@@ -5256,91 +4695,6 @@ void QMutableTouchEvent::addPoint(const QEventPoint &point)
m_touchPointStates |= point.state();
}
-/*!
- \class QPointingDeviceUniqueId
- \since 5.8
- \ingroup events
- \inmodule QtGui
-
- \brief QPointingDeviceUniqueId identifies a unique object, such as a tagged token
- or stylus, which is used with a pointing device.
-
- QPointingDeviceUniqueIds can be compared for equality, and can be used as keys in a QHash.
- You get access to the numerical ID via numericId(), if the device supports such IDs.
- For future extensions, though, you should not use that function, but compare objects
- of this type using the equality operator.
-
- This class is a thin wrapper around an integer ID. You pass it into and out of
- functions by value.
-
- \sa QEventPoint
-*/
-
-/*!
- \fn QPointingDeviceUniqueId::QPointingDeviceUniqueId()
- Constructs an invalid unique pointer ID.
-*/
-
-/*!
- Constructs a unique pointer ID from numeric ID \a id.
-*/
-QPointingDeviceUniqueId QPointingDeviceUniqueId::fromNumericId(qint64 id)
-{
- QPointingDeviceUniqueId result;
- result.m_numericId = id;
- return result;
-}
-
-/*!
- \fn bool QPointingDeviceUniqueId::isValid() const
-
- Returns whether this unique pointer ID is valid, that is, it represents an actual
- pointer.
-*/
-
-/*!
- \property QPointingDeviceUniqueId::numericId
- \brief the numeric unique ID of the token represented by a touchpoint
-
- If the device provides a numeric ID, isValid() returns true, and this
- property provides the numeric ID;
- otherwise it is -1.
-
- You should not use the value of this property in portable code, but
- instead rely on equality to identify pointers.
-
- \sa isValid()
-*/
-qint64 QPointingDeviceUniqueId::numericId() const noexcept
-{
- return m_numericId;
-}
-/*!
- \fn bool QPointingDeviceUniqueId::operator==(QPointingDeviceUniqueId lhs, QPointingDeviceUniqueId rhs)
- \since 5.8
-
- Returns whether the two unique pointer IDs \a lhs and \a rhs identify the same pointer
- (\c true) or not (\c false).
-*/
-
-/*!
- \fn bool QPointingDeviceUniqueId::operator!=(QPointingDeviceUniqueId lhs, QPointingDeviceUniqueId rhs)
- \since 5.8
-
- Returns whether the two unique pointer IDs \a lhs and \a rhs identify different pointers
- (\c true) or not (\c false).
-*/
-
-/*!
- \relates QPointingDeviceUniqueId
- \since 5.8
-
- Returns the hash value for \a key, using \a seed to seed the calculation.
-*/
-size_t qHash(QPointingDeviceUniqueId key, size_t seed) noexcept
-{
- return qHash(key.numericId(), seed);
-}
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h
index 2459f1ba9d..4bd7a54022 100644
--- a/src/gui/kernel/qevent.h
+++ b/src/gui/kernel/qevent.h
@@ -50,9 +50,9 @@
#include <QtCore/qstring.h>
#include <QtCore/qurl.h>
#include <QtCore/qvariant.h>
+#include <QtGui/qeventpoint.h>
#include <QtGui/qpointingdevice.h>
#include <QtGui/qregion.h>
-#include <QtGui/qvector2d.h>
#include <QtGui/qwindowdefs.h>
#if QT_CONFIG(shortcut)
@@ -93,114 +93,6 @@ protected:
qint64 m_extra = 0; // reserved, unused for now
};
-struct QEventPointPrivate;
-class Q_GUI_EXPORT QEventPoint
-{
- Q_GADGET
- Q_PROPERTY(const QPointingDevice *device READ device)
- Q_PROPERTY(int id READ id)
- Q_PROPERTY(QPointingDeviceUniqueId uniqueId READ uniqueId)
- Q_PROPERTY(State state READ state)
- Q_PROPERTY(ulong timestamp READ timestamp)
- Q_PROPERTY(qreal timeHeld READ timeHeld)
- Q_PROPERTY(qreal pressure READ pressure)
- Q_PROPERTY(qreal rotation READ rotation)
- Q_PROPERTY(QSizeF ellipseDiameters READ ellipseDiameters)
- Q_PROPERTY(QVector2D velocity READ velocity)
- Q_PROPERTY(QPointF position READ position)
- Q_PROPERTY(QPointF scenePosition READ scenePosition)
- Q_PROPERTY(QPointF globalPosition READ globalPosition)
-public:
- enum State : quint8 {
- Unknown = Qt::TouchPointUnknownState,
- Stationary = Qt::TouchPointStationary,
- Pressed = Qt::TouchPointPressed,
- Updated = Qt::TouchPointMoved,
- Released = Qt::TouchPointReleased
- };
- Q_DECLARE_FLAGS(States, State)
- Q_FLAG(States)
-
- QEventPoint(int id = -1, const QPointingDevice *device = nullptr);
- QEventPoint(int pointId, State state, const QPointF &scenePosition, const QPointF &globalPosition);
- QEventPoint(const QEventPoint &other);
- QEventPoint(QEventPoint && other) noexcept : d(std::move(other.d)) { other.d = nullptr; }
- QEventPoint &operator=(const QEventPoint &other);
- QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(QEventPoint)
- bool operator==(const QEventPoint &other) const noexcept;
- inline bool operator!=(const QEventPoint &other) const noexcept { return !operator==(other); }
- ~QEventPoint();
- inline void swap(QEventPoint &other) noexcept
- { qSwap(d, other.d); }
-
- QPointF position() const;
- QPointF pressPosition() const;
- QPointF grabPosition() const;
- QPointF lastPosition() const;
- QPointF scenePosition() const;
- QPointF scenePressPosition() const;
- QPointF sceneGrabPosition() const;
- QPointF sceneLastPosition() const;
- QPointF globalPosition() const;
- QPointF globalPressPosition() const;
- QPointF globalGrabPosition() const;
- QPointF globalLastPosition() const;
- QPointF normalizedPosition() const;
-
-#if QT_DEPRECATED_SINCE(6, 0)
- // QEventPoint replaces QTouchEvent::TouchPoint, so we need all its old accessors, for now
- QT_DEPRECATED_VERSION_X_6_0("Use position()")
- QPointF pos() const { return position(); }
- QT_DEPRECATED_VERSION_X_6_0("Use pressPosition()")
- QPointF startPos() const { return pressPosition(); }
- QT_DEPRECATED_VERSION_X_6_0("Use scenePosition()")
- QPointF scenePos() const { return scenePosition(); }
- QT_DEPRECATED_VERSION_X_6_0("Use scenePressPosition()")
- QPointF startScenePos() const { return scenePressPosition(); }
- QT_DEPRECATED_VERSION_X_6_0("Use globalPosition()")
- QPointF screenPos() const { return globalPosition(); }
- QT_DEPRECATED_VERSION_X_6_0("Use globalPressPosition()")
- QPointF startScreenPos() const { return globalPressPosition(); }
- QT_DEPRECATED_VERSION_X_6_0("Use globalPressPosition()")
- QPointF startNormalizedPos() const;
- QT_DEPRECATED_VERSION_X_6_0("Use normalizedPosition()")
- QPointF normalizedPos() const { return normalizedPosition(); }
- QT_DEPRECATED_VERSION_X_6_0("Use lastPosition()")
- QPointF lastPos() const { return lastPosition(); }
- QT_DEPRECATED_VERSION_X_6_0("Use sceneLastPosition()")
- QPointF lastScenePos() const { return sceneLastPosition(); }
- QT_DEPRECATED_VERSION_X_6_0("Use globalLastPosition()")
- QPointF lastScreenPos() const { return globalLastPosition(); }
- QT_DEPRECATED_VERSION_X_6_0("Use globalLastPosition()")
- QPointF lastNormalizedPos() const;
-#endif // QT_DEPRECATED_SINCE(6, 0)
- QVector2D velocity() const;
- State state() const;
- const QPointingDevice *device() const;
- int id() const;
- QPointingDeviceUniqueId uniqueId() const;
- ulong timestamp() const;
- ulong lastTimestamp() const;
- ulong pressTimestamp() const;
- qreal timeHeld() const;
- qreal pressure() const;
- qreal rotation() const;
- QSizeF ellipseDiameters() const;
-
- bool isAccepted() const;
- void setAccepted(bool accepted = true);
-
-private:
- QEventPointPrivate *d;
- friend class QMutableEventPoint;
- friend class QPointerEvent;
-};
-
-#ifndef QT_NO_DEBUG_STREAM
-Q_GUI_EXPORT QDebug operator<<(QDebug, const QEventPoint *);
-Q_GUI_EXPORT QDebug operator<<(QDebug, const QEventPoint &);
-#endif
-
class Q_GUI_EXPORT QPointerEvent : public QInputEvent
{
public:
diff --git a/src/gui/kernel/qevent_p.h b/src/gui/kernel/qevent_p.h
index 205673d53d..7c9974db7f 100644
--- a/src/gui/kernel/qevent_p.h
+++ b/src/gui/kernel/qevent_p.h
@@ -52,6 +52,7 @@
//
#include <QtGui/private/qtguiglobal_p.h>
+#include <QtGui/private/qeventpoint_p.h>
#include <QtCore/qurl.h>
#include <QtGui/qevent.h>
#include <QtGui/qwindow.h>
@@ -60,139 +61,6 @@ QT_BEGIN_NAMESPACE
class QPointingDevice;
-struct QEventPointPrivate {
- QEventPointPrivate(int id, const QPointingDevice *device)
- : device(device), pointId(id) { }
-
- QEventPointPrivate(int pointId, QEventPoint::State state, const QPointF &scenePosition, const QPointF &globalPosition)
- : scenePos(scenePosition), globalPos(globalPosition), pointId(pointId), state(state)
- {
- if (state == QEventPoint::State::Released)
- pressure = 0;
- }
- inline bool operator==(const QEventPointPrivate &other) const
- {
- return device == other.device
- && window == other.window
- && target == other.target
- && pos == other.pos
- && scenePos == other.scenePos
- && globalPos == other.globalPos
- && globalPressPos == other.globalPressPos
- && globalGrabPos == other.globalGrabPos
- && globalLastPos == other.globalLastPos
- && pressure == other.pressure
- && rotation == other.rotation
- && ellipseDiameters == other.ellipseDiameters
- && velocity == other.velocity
- && timestamp == other.timestamp
- && lastTimestamp == other.lastTimestamp
- && pressTimestamp == other.pressTimestamp
- && uniqueId == other.uniqueId
- && pointId == other.pointId
- && state == other.state;
- }
-
- const QPointingDevice *device = nullptr;
- QPointer<QWindow> window;
- QPointer<QObject> target;
- QPointF pos, scenePos, globalPos,
- globalPressPos, globalGrabPos, globalLastPos;
- qreal pressure = 1;
- qreal rotation = 0;
- QSizeF ellipseDiameters = QSizeF(0, 0);
- QVector2D velocity;
- ulong timestamp = 0;
- ulong lastTimestamp = 0;
- ulong pressTimestamp = 0;
- QPointingDeviceUniqueId uniqueId;
- int refCount = 1;
- int pointId = -1;
- QEventPoint::State state = QEventPoint::State::Unknown;
- bool accept = false;
-};
-
-// Private subclasses to allow accessing and modifying protected variables.
-// These should NOT hold any extra state.
-
-class Q_GUI_EXPORT QMutableEventPoint : public QEventPoint
-{
-public:
- QMutableEventPoint(int pointId = -1, State state = QEventPoint::State::Stationary,
- const QPointF &scenePosition = QPointF(), const QPointF &globalPosition = QPointF()) :
- QEventPoint(pointId, state, scenePosition, globalPosition) {}
-
- QMutableEventPoint(ulong timestamp, int pointId, State state,
- const QPointF &position, const QPointF &scenePosition, const QPointF &globalPosition) :
- QEventPoint(pointId, state, scenePosition, globalPosition)
- {
- d->timestamp = timestamp;
- d->pos = position;
- }
-
- void updateFrom(const QEventPoint &other);
-
- static QMutableEventPoint *from(QEventPoint *me) { return static_cast<QMutableEventPoint *>(me); }
-
- static QMutableEventPoint &from(QEventPoint &me) { return static_cast<QMutableEventPoint &>(me); }
-
- static const QMutableEventPoint &constFrom(const QEventPoint &me) { return static_cast<const QMutableEventPoint &>(me); }
-
- void detach();
-
- void setId(int pointId) { d->pointId = pointId; }
-
- void setDevice(const QPointingDevice *device) { d->device = device; }
-
- void setTimestamp(const ulong t);
-
- void setPressTimestamp(const ulong t) { d->pressTimestamp = t; }
-
- void setState(QEventPoint::State state) { d->state = state; }
-
- void setUniqueId(const QPointingDeviceUniqueId &uid) { d->uniqueId = uid; }
-
- void setPosition(const QPointF &pos) { d->pos = pos; }
-
- void setScenePosition(const QPointF &pos) { d->scenePos = pos; }
-
- void setGlobalPosition(const QPointF &pos) { d->globalPos = pos; }
-
-#if QT_DEPRECATED_SINCE(6, 0)
- // temporary replacements for QTouchEvent::TouchPoint setters, mainly to make porting easier
- QT_DEPRECATED_VERSION_X_6_0("Use setPosition()")
- void setPos(const QPointF &pos) { d->pos = pos; }
- QT_DEPRECATED_VERSION_X_6_0("Use setScenePosition()")
- void setScenePos(const QPointF &pos) { d->scenePos = pos; }
- QT_DEPRECATED_VERSION_X_6_0("Use setGlobalPosition()")
- void setScreenPos(const QPointF &pos) { d->globalPos = pos; }
-#endif
-
- void setGlobalPressPosition(const QPointF &pos) { d->globalPressPos = pos; }
-
- void setGlobalGrabPosition(const QPointF &pos) { d->globalGrabPos = pos; }
-
- void setGlobalLastPosition(const QPointF &pos) { d->globalLastPos = pos; }
-
- void setEllipseDiameters(const QSizeF &diams) { d->ellipseDiameters = diams; }
-
- void setPressure(qreal v) { d->pressure = v; }
-
- void setRotation(qreal v) { d->rotation = v; }
-
- void setVelocity(const QVector2D &v) { d->velocity = v; }
-
- QWindow *window() const { return d->window.data(); }
-
- void setWindow(const QPointer<QWindow> &w) { d->window = w; }
-
- QObject *target() const { return d->target.data(); }
-
- void setTarget(const QPointer<QObject> &t) { d->target = t; }
-};
-
-static_assert(sizeof(QMutableEventPoint) == sizeof(QEventPoint));
-
class Q_GUI_EXPORT QMutableTouchEvent : public QTouchEvent
{
public:
diff --git a/src/gui/kernel/qeventpoint.cpp b/src/gui/kernel/qeventpoint.cpp
new file mode 100644
index 0000000000..e8a366885f
--- /dev/null
+++ b/src/gui/kernel/qeventpoint.cpp
@@ -0,0 +1,664 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qeventpoint.h"
+#include "private/qeventpoint_p.h"
+#include "private/qpointingdevice_p.h"
+
+QT_BEGIN_NAMESPACE
+
+Q_LOGGING_CATEGORY(lcPointerVel, "qt.pointer.velocity")
+Q_LOGGING_CATEGORY(lcEPDetach, "qt.pointer.eventpoint.detach")
+
+/*! \class QEventPoint
+ \brief The QEventPoint class provides information about a point in a QPointerEvent.
+ \since 6.0
+ \inmodule QtGui
+*/
+
+/*!
+ \enum QEventPoint::State
+
+ Specifies the state of this event point.
+
+ \value Unknown
+ Unknown state.
+
+ \value Stationary
+ The event point did not move.
+
+ \value Pressed
+ The touch point or button is pressed.
+
+ \value Updated
+ The event point was updated.
+
+ \value Released
+ The touch point or button was released.
+*/
+
+/*!
+ \internal
+ 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>,
+ as in qgraphicsscene_p.h.
+*/
+QEventPoint::QEventPoint(int id, const QPointingDevice *device)
+ : d(new QEventPointPrivate(id, device)) {}
+
+/*!
+ Constructs an event point with the given \a pointId, \a state,
+ \a scenePosition and \a globalPosition.
+*/
+QEventPoint::QEventPoint(int pointId, State state, const QPointF &scenePosition, const QPointF &globalPosition)
+ : d(new QEventPointPrivate(pointId, state, scenePosition, globalPosition)) {}
+
+/*!
+ Constructs an event point by making a shallow copy of \a other.
+*/
+QEventPoint::QEventPoint(const QEventPoint &other)
+ : d(other.d)
+{
+ if (d)
+ d->refCount++;
+}
+
+/*!
+ Assigns \a other to this event point and returns a reference to this
+ event point.
+*/
+QEventPoint &QEventPoint::operator=(const QEventPoint &other)
+{
+ if (other.d)
+ other.d->refCount++;
+ if (d && !(--d->refCount))
+ delete d;
+ d = other.d;
+ return *this;
+}
+
+/*!
+ \fn QEventPoint::QEventPoint(QEventPoint &&other) noexcept
+
+ Constructs an event point by moving \a other.
+*/
+
+/*!
+ \fn QEventPoint &QEventPoint::operator=(QEventPoint &&other) noexcept
+
+ Move-assigns \a other to this event point instance.
+*/
+
+/*!
+ Returns \c true if this event point is equal to \a other, otherwise
+ return \c false.
+*/
+bool QEventPoint::operator==(const QEventPoint &other) const noexcept
+{
+ if (d == other.d)
+ return true;
+ if (!d || !other.d)
+ return false;
+ return *d == *other.d;
+}
+
+/*!
+ \fn bool QEventPoint::operator!=(const QEventPoint &other) const noexcept
+
+ Returns \c true if this event point is not equal to \a other, otherwise
+ return \c false.
+*/
+
+/*!
+ Destroys the event point.
+*/
+QEventPoint::~QEventPoint()
+{
+ if (d && !(--d->refCount))
+ delete d;
+}
+
+/*! \fn QPointF QEventPoint::pos() const
+ \obsolete
+ Deprecated since Qt 6.0. Use position() instead.
+
+ Returns the position of this point, relative to the widget
+ or item that received the event.
+*/
+
+/*!
+ \property QEventPoint::position
+ the position of this point
+
+ The position is relative to the widget or item that received the event.
+*/
+QPointF QEventPoint::position() const
+{ return d->pos; }
+
+/*!
+ \property QEventPoint::pressPosition
+ the position at which this point was pressed
+
+ The position is relative to the widget or item that received the event.
+
+ \sa position
+*/
+QPointF QEventPoint::pressPosition() const
+{ return d->globalPressPos - d->globalPos + d->pos; }
+
+/*!
+ \property QEventPoint::grabPosition
+ the position at which this point was grabbed
+
+ The position is relative to the widget or item that received the event.
+
+ \sa position
+*/
+QPointF QEventPoint::grabPosition() const
+{ return d->globalGrabPos - d->globalPos + d->pos; }
+
+/*!
+ \property QEventPoint::lastPosition
+ the position of this point from the previous press or move event
+
+ The position is relative to the widget or item that received the event.
+
+ \sa position, pressPosition
+*/
+QPointF QEventPoint::lastPosition() const
+{ return d->globalLastPos - d->globalPos + d->pos; }
+
+/*!
+ \property QEventPoint::scenePosition
+ the scene position of this point
+
+ The scene position is the position relative to QQuickWindow if handled in QQuickItem::event(),
+ in QGraphicsScene coordinates if handled by an override of QGraphicsItem::touchEvent(),
+ or the window position in widget applications.
+
+ \sa scenePressPosition, position, globalPosition
+*/
+QPointF QEventPoint::scenePosition() const
+{ return d->scenePos; }
+
+/*!
+ \property QEventPoint::scenePressPosition
+ the scene position at which this point was pressed
+
+ The scene position is the position relative to QQuickWindow if handled in QQuickItem::event(),
+ in QGraphicsScene coordinates if handled by an override of QGraphicsItem::touchEvent(),
+ or the window position in widget applications.
+
+ \sa scenePosition, pressPosition, globalPressPosition
+*/
+QPointF QEventPoint::scenePressPosition() const
+{ return d->globalPressPos - d->globalPos + d->scenePos; }
+
+/*!
+ \property QEventPoint::sceneGrabPosition
+ the scene position at which this point was grabbed
+
+ The scene position is the position relative to QQuickWindow if handled in QQuickItem::event(),
+ in QGraphicsScene coordinates if handled by an override of QGraphicsItem::touchEvent(),
+ or the window position in widget applications.
+
+ \sa scenePosition, grabPosition, globalGrabPosition
+*/
+QPointF QEventPoint::sceneGrabPosition() const
+{ return d->globalGrabPos - d->globalPos + d->scenePos; }
+
+/*!
+ \property QEventPoint::sceneLastPosition
+ the scene position of this point from the previous press or move event
+
+ The scene position is the position relative to QQuickWindow if handled in QQuickItem::event(),
+ in QGraphicsScene coordinates if handled by an override of QGraphicsItem::touchEvent(),
+ or the window position in widget applications.
+
+ \sa scenePosition, scenePressPosition
+*/
+QPointF QEventPoint::sceneLastPosition() const
+{ return d->globalLastPos - d->globalPos + d->scenePos; }
+
+/*!
+ \property QEventPoint::globalPosition
+ the global position of this point
+
+ The global position is relative to the screen or virtual desktop.
+
+ \sa globalPressPosition, position, scenePosition
+*/
+QPointF QEventPoint::globalPosition() const
+{ return d->globalPos; }
+
+/*!
+ \property QEventPoint::globalPressPosition
+ the global position at which this point was pressed
+
+ The global position is relative to the screen or virtual desktop.
+
+ \sa globalPosition, pressPosition, scenePressPosition
+*/
+QPointF QEventPoint::globalPressPosition() const
+{ return d->globalPressPos; }
+
+/*!
+ \property QEventPoint::globalGrabPosition
+ the global position at which this point was grabbed
+
+ The global position is relative to the screen or virtual desktop.
+
+ \sa globalPosition, grabPosition, sceneGrabPosition
+*/
+QPointF QEventPoint::globalGrabPosition() const
+{ return d->globalGrabPos; }
+
+/*!
+ \property QEventPoint::globalLastPosition
+ the global position of this point from the previous press or move event
+
+ The global position is relative to the screen or virtual desktop.
+
+ \sa globalPosition, lastPosition, sceneLastPosition
+*/
+QPointF QEventPoint::globalLastPosition() const
+{ return d->globalLastPos; }
+
+/*!
+ \property QEventPoint::velocity
+ a velocity vector, in units of pixels per second, in the coordinate
+ system of the screen or desktop.
+
+ \note If the device's capabilities include QInputDevice::Velocity, it means
+ velocity comes from the operating system (perhaps the touch hardware or
+ driver provides it). But usually the \c Velocity capability is not set,
+ indicating that the velocity is calculated by Qt, using a simple Kalman
+ filter to provide a smoothed average velocity rather than an instantaneous
+ value. Effectively it tells how fast and in what direction the user has
+ been dragging this point over the last few events, with the most recent
+ event having the strongest influence.
+
+ \sa QInputDevice::capabilities(), QInputEvent::device()
+*/
+QVector2D QEventPoint::velocity() const
+{ return d->velocity; }
+
+/*!
+ \property QEventPoint::state
+ the current state of the event point.
+*/
+QEventPoint::State QEventPoint::state() const
+{ return d->state; }
+
+/*!
+ \property QEventPoint::device
+ the pointing device from which this event point originates
+*/
+const QPointingDevice *QEventPoint::device() const
+{ return d->device; }
+
+/*!
+ \property QEventPoint::id
+ the ID number of this event point
+
+ \note Do not assume that ID numbers start at zero or that they are
+ sequential. Such an assumption is often false due to the way
+ the underlying drivers work.
+*/
+int QEventPoint::id() const
+{ return d->pointId; }
+
+/*!
+ \property QEventPoint::uniqueId
+ the unique ID of this point or token, if any
+
+ It is often invalid (see \l {QPointingDeviceUniqueId::isValid()} {isValid()}),
+ because touchscreens cannot uniquely identify fingers.
+
+ When it comes from a QTabletEvent, it identifies the serial number of the
+ stylus in use.
+
+ It may identify a specific token (fiducial object) when the TUIO driver is
+ in use with a touchscreen that supports them.
+*/
+QPointingDeviceUniqueId QEventPoint::uniqueId() const
+{ return d->uniqueId; }
+
+/*!
+ \property QEventPoint::timestamp
+ the most recent time at which this point was included in a QPointerEvent
+
+ \sa QPointerEvent::timestamp()
+*/
+ulong QEventPoint::timestamp() const
+{ return d->timestamp; }
+
+/*!
+ \property QEventPoint::lastTimestamp
+ the time from the previous QPointerEvent that contained this point
+
+ \sa globalLastPosition
+*/
+ulong QEventPoint::lastTimestamp() const
+{ return d->lastTimestamp; }
+
+/*!
+ \property QEventPoint::pressTimestamp
+ the most recent time at which this point was pressed
+
+ \sa timestamp
+*/
+ulong QEventPoint::pressTimestamp() const
+{ return d->pressTimestamp; }
+
+/*!
+ \property QEventPoint::timeHeld
+ the duration, in milliseconds, since this point was pressed and not released
+
+ \sa pressTimestamp, timestamp
+*/
+qreal QEventPoint::timeHeld() const
+{ return (d->timestamp - d->pressTimestamp) / qreal(1000); }
+
+/*!
+ \property QEventPoint::pressure
+ the pressure of this point
+
+ The return value is in the range \c 0.0 to \c 1.0.
+*/
+qreal QEventPoint::pressure() const
+{ return d->pressure; }
+
+/*!
+ \property QEventPoint::rotation
+ the angular orientation of this point
+
+ The return value is in degrees, where zero (the default) indicates the finger,
+ token or stylus is pointing upwards, a negative angle means it's rotated to the
+ left, and a positive angle means it's rotated to the right.
+ Most touchscreens do not detect rotation, so zero is the most common value.
+*/
+qreal QEventPoint::rotation() const
+{ return d->rotation; }
+
+/*!
+ \property QEventPoint::ellipseDiameters
+ the width and height of the bounding ellipse of the touch point
+
+ The return value is in logical pixels. Most touchscreens do not detect the
+ shape of the contact point, and no mice or tablet devices can detect it,
+ so a null size is the most common value. On some touchscreens the diameters
+ may be nonzero and always equal (the ellipse is approximated as a circle).
+*/
+QSizeF QEventPoint::ellipseDiameters() const
+{ return d->ellipseDiameters; }
+
+/*!
+ \property QEventPoint::accepted
+ the accepted state of the event point
+
+ In widget-based applications, this property is not used, as it's only meaningful
+ for a widget to accept or reject a complete QInputEvent.
+
+ In Qt Quick however, it's normal for an Item or Event Handler to accept
+ only the individual points in a QTouchEvent that are actually participating
+ in a gesture, while other points can be delivered to other items or
+ handlers. For the sake of consistency, that applies to any QPointerEvent;
+ and delivery is done only when all points in a QPointerEvent have been
+ accepted.
+
+ \sa QEvent::accepted
+*/
+void QEventPoint::setAccepted(bool accepted)
+{
+ d->accept = accepted;
+}
+
+bool QEventPoint::isAccepted() const
+{ return d->accept; }
+
+
+/*!
+ \obsolete
+ \fn QPointF QEventPoint::normalizedPos() const
+
+ Deprecated since Qt 6.0. Use normalizedPosition() instead.
+*/
+
+/*!
+ Returns the normalized position of this point.
+
+ The coordinates are calculated by transforming globalPosition() into the
+ space of QInputDevice::availableVirtualGeometry(), i.e. \c (0, 0) is the
+ top-left corner and \c (1, 1) is the bottom-right corner.
+
+ \sa globalPosition
+*/
+QPointF QEventPoint::normalizedPosition() const
+{
+ auto geom = d->device->availableVirtualGeometry();
+ if (geom.isNull())
+ return QPointF();
+ return (globalPosition() - geom.topLeft()) / geom.width();
+}
+
+/*!
+ \obsolete
+ Deprecated since Qt 6.0. Use globalPressPosition() instead.
+
+ Returns the normalized press position of this point.
+*/
+QPointF QEventPoint::startNormalizedPos() const
+{
+ auto geom = d->device->availableVirtualGeometry();
+ if (geom.isNull())
+ return QPointF();
+ return (globalPressPosition() - geom.topLeft()) / geom.width();
+}
+
+/*!
+ \obsolete
+ Deprecated since Qt 6.0. Use globalLastPosition() instead.
+
+ Returns the normalized position of this point from the previous press or
+ move event.
+
+ The coordinates are normalized to QInputDevice::availableVirtualGeometry(),
+ i.e. \c (0, 0) is the top-left corner and \c (1, 1) is the bottom-right corner.
+
+ \sa normalizedPos(), startNormalizedPos()
+*/
+QPointF QEventPoint::lastNormalizedPos() const
+{
+ auto geom = d->device->availableVirtualGeometry();
+ if (geom.isNull())
+ return QPointF();
+ return (globalLastPosition() - geom.topLeft()) / geom.width();
+}
+
+
+/*! \internal
+ This class is explicitly shared, which means if you construct an event and
+ then the point(s) that it holds are modified before the event is delivered,
+ the event will be seen to hold the modified points. The workaround is that
+ any code which modifies an eventpoint that could already be included in an
+ event, or code that wants to save an eventpoint for later, has
+ responsibility to detach before calling any setters, so as to hold and
+ modify an independent copy. (The independent copy can then be used in a
+ subsequent event.) If detaching is unnecessary, because refCount shows that
+ there is only one QEventPoint referring to the QEventPointPrivate instance,
+ this function does nothing.
+*/
+void QMutableEventPoint::detach()
+{
+ if (d->refCount == 1)
+ return; // no need: there is only one QEventPoint using it
+ qCDebug(lcEPDetach) << "detaching: refCount" << d->refCount << this;
+ auto old = d;
+ d = new QEventPointPrivate(*d);
+ d->refCount = 1;
+ --old->refCount;
+}
+
+/*! \internal
+ Update current state from the given \a other point, assuming that this
+ instance contains state from the previous event and \a other contains new
+ values that came in from a device.
+
+ That is: global position and other valuators will be updated, but
+ the following properties will not be updated:
+
+ \list
+ \li properties that are not likely to be set after a fresh touchpoint
+ has been received from a device
+ \li properties that should be persistent between events (such as grabbers)
+ \endlist
+*/
+void QMutableEventPoint::updateFrom(const QEventPoint &other)
+{
+ detach();
+ setPressure(other.pressure());
+
+ switch (other.state()) {
+ case QEventPoint::State::Pressed:
+ setGlobalPressPosition(other.globalPosition());
+ setGlobalLastPosition(other.globalPosition());
+ if (pressure() < 0)
+ setPressure(1);
+ break;
+
+ case QEventPoint::State::Released:
+ if (globalPosition() != other.globalPosition())
+ setGlobalLastPosition(globalPosition());
+ setPressure(0);
+ break;
+
+ default: // update or stationary
+ if (globalPosition() != other.globalPosition())
+ setGlobalLastPosition(globalPosition());
+ if (pressure() < 0)
+ setPressure(1);
+ break;
+ }
+
+ setState(other.state());
+ setPosition(other.position());
+ setScenePosition(other.scenePosition());
+ setGlobalPosition(other.globalPosition());
+ setEllipseDiameters(other.ellipseDiameters());
+ setRotation(other.rotation());
+ setVelocity(other.velocity());
+}
+
+/*! \internal
+ Set the timestamp from the event that updated this point's positions,
+ and calculate a new value for velocity().
+
+ The velocity calculation is done here because none of the QPointerEvent
+ subclass constructors take the timestamp directly, and because
+ QGuiApplication traditionally constructs an event first and then sets its
+ timestamp (see for example QGuiApplicationPrivate::processMouseEvent()).
+
+ This function looks up the corresponding instance in QPointingDevicePrivate::activePoints,
+ and assumes that its timestamp() still holds the previous time when this point
+ was updated, its velocity() holds this point's last-known velocity, and
+ its globalPosition() and globalLastPosition() hold this point's current
+ and previous positions, respectively. We assume timestamps are in milliseconds.
+
+ The velocity calculation is skipped if the platform has promised to
+ provide velocities already by setting the QInputDevice::Velocity capability.
+*/
+void QMutableEventPoint::setTimestamp(const ulong t)
+{
+ // On mouse press, if the mouse has moved from its last-known location,
+ // QGuiApplicationPrivate::processMouseEvent() sends first a mouse move and
+ // then a press. Both events will get the same timestamp. So we need to set
+ // the press timestamp and position even when the timestamp isn't advancing,
+ // but skip setting lastTimestamp and velocity because those need a time delta.
+ if (state() == QEventPoint::State::Pressed) {
+ d->pressTimestamp = t;
+ d->globalPressPos = d->globalPos;
+ }
+ if (d->timestamp == t)
+ return;
+ detach();
+ if (device()) {
+ // get the persistent instance out of QPointingDevicePrivate::activePoints
+ // (which sometimes might be the same as this instance)
+ QEventPointPrivate *pd = QPointingDevicePrivate::get(
+ const_cast<QPointingDevice *>(d->device))->pointById(id())->eventPoint.d;
+ if (t > pd->timestamp) {
+ pd->lastTimestamp = pd->timestamp;
+ pd->timestamp = t;
+ if (state() == QEventPoint::State::Pressed)
+ pd->pressTimestamp = t;
+ if (pd->lastTimestamp > 0 && !device()->capabilities().testFlag(QInputDevice::Capability::Velocity)) {
+ // calculate instantaneous velocity according to time and distance moved since the previous point
+ QVector2D newVelocity = QVector2D(pd->globalPos - pd->globalLastPos) / (t - pd->lastTimestamp) * 1000;
+ // VERY simple kalman filter: does a weighted average
+ // where the older velocities get less and less significant
+ static const float KalmanGain = 0.7f;
+ pd->velocity = newVelocity * KalmanGain + pd->velocity * (1.0f - KalmanGain);
+ qCDebug(lcPointerVel) << "velocity" << newVelocity << "filtered" << pd->velocity <<
+ "based on movement" << pd->globalLastPos << "->" << pd->globalPos <<
+ "over time" << pd->lastTimestamp << "->" << pd->timestamp;
+ }
+ if (d != pd) {
+ d->lastTimestamp = pd->lastTimestamp;
+ d->velocity = pd->velocity;
+ }
+ }
+ }
+ d->timestamp = t;
+}
+
+/*!
+ \fn void QMutableEventPoint::setPosition(const QPointF &pos)
+ \internal
+
+ Sets the localized position.
+ Often events need to be localized before delivery to specific widgets or
+ items. This can be done directly, or in a copy (for which we have a copy
+ constructor), depending on whether the original point needs to be retained.
+ Usually it's calculated by mapping scenePosition() to the target anyway.
+*/
+
+QT_END_NAMESPACE
diff --git a/src/gui/kernel/qeventpoint.h b/src/gui/kernel/qeventpoint.h
new file mode 100644
index 0000000000..d4cce66b90
--- /dev/null
+++ b/src/gui/kernel/qeventpoint.h
@@ -0,0 +1,172 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QEVENTPOINT_H
+#define QEVENTPOINT_H
+
+#include <QtGui/qtguiglobal.h>
+#include <QtGui/qvector2d.h>
+#include <QtGui/qpointingdevice.h>
+
+QT_BEGIN_NAMESPACE
+
+struct QEventPointPrivate;
+class Q_GUI_EXPORT QEventPoint
+{
+ Q_GADGET
+ Q_PROPERTY(bool accepted READ isAccepted WRITE setAccepted)
+ QDOC_PROPERTY(QPointingDevice *device READ device CONSTANT) // qdoc doesn't know const
+ Q_PROPERTY(const QPointingDevice *device READ device CONSTANT)
+ Q_PROPERTY(int id READ id CONSTANT)
+ Q_PROPERTY(QPointingDeviceUniqueId uniqueId READ uniqueId CONSTANT)
+ Q_PROPERTY(State state READ state CONSTANT)
+ Q_PROPERTY(ulong timestamp READ timestamp CONSTANT)
+ Q_PROPERTY(ulong pressTimestamp READ pressTimestamp CONSTANT)
+ Q_PROPERTY(ulong lastTimestamp READ lastTimestamp CONSTANT)
+ Q_PROPERTY(qreal timeHeld READ timeHeld CONSTANT)
+ Q_PROPERTY(qreal pressure READ pressure CONSTANT)
+ Q_PROPERTY(qreal rotation READ rotation CONSTANT)
+ Q_PROPERTY(QSizeF ellipseDiameters READ ellipseDiameters CONSTANT)
+ Q_PROPERTY(QVector2D velocity READ velocity CONSTANT)
+ Q_PROPERTY(QPointF position READ position CONSTANT)
+ Q_PROPERTY(QPointF pressPosition READ pressPosition CONSTANT)
+ Q_PROPERTY(QPointF grabPosition READ grabPosition CONSTANT)
+ Q_PROPERTY(QPointF lastPosition READ lastPosition CONSTANT)
+ Q_PROPERTY(QPointF scenePosition READ scenePosition CONSTANT)
+ Q_PROPERTY(QPointF scenePressPosition READ scenePressPosition CONSTANT)
+ Q_PROPERTY(QPointF sceneGrabPosition READ sceneGrabPosition CONSTANT)
+ Q_PROPERTY(QPointF sceneLastPosition READ sceneLastPosition CONSTANT)
+ Q_PROPERTY(QPointF globalPosition READ globalPosition CONSTANT)
+ Q_PROPERTY(QPointF globalPressPosition READ globalPressPosition CONSTANT)
+ Q_PROPERTY(QPointF globalGrabPosition READ globalGrabPosition CONSTANT)
+ Q_PROPERTY(QPointF globalLastPosition READ globalLastPosition CONSTANT)
+public:
+ enum State : quint8 {
+ Unknown = Qt::TouchPointUnknownState,
+ Stationary = Qt::TouchPointStationary,
+ Pressed = Qt::TouchPointPressed,
+ Updated = Qt::TouchPointMoved,
+ Released = Qt::TouchPointReleased
+ };
+ Q_DECLARE_FLAGS(States, State)
+ Q_FLAG(States)
+
+ QEventPoint(int id = -1, const QPointingDevice *device = nullptr);
+ QEventPoint(int pointId, State state, const QPointF &scenePosition, const QPointF &globalPosition);
+ QEventPoint(const QEventPoint &other);
+ QEventPoint(QEventPoint && other) noexcept : d(std::move(other.d)) { other.d = nullptr; }
+ QEventPoint &operator=(const QEventPoint &other);
+ QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(QEventPoint)
+ bool operator==(const QEventPoint &other) const noexcept;
+ inline bool operator!=(const QEventPoint &other) const noexcept { return !operator==(other); }
+ ~QEventPoint();
+ inline void swap(QEventPoint &other) noexcept
+ { qSwap(d, other.d); }
+
+ QPointF position() const;
+ QPointF pressPosition() const;
+ QPointF grabPosition() const;
+ QPointF lastPosition() const;
+ QPointF scenePosition() const;
+ QPointF scenePressPosition() const;
+ QPointF sceneGrabPosition() const;
+ QPointF sceneLastPosition() const;
+ QPointF globalPosition() const;
+ QPointF globalPressPosition() const;
+ QPointF globalGrabPosition() const;
+ QPointF globalLastPosition() const;
+ QPointF normalizedPosition() const;
+
+#if QT_DEPRECATED_SINCE(6, 0)
+ // QEventPoint replaces QTouchEvent::TouchPoint, so we need all its old accessors, for now
+ QT_DEPRECATED_VERSION_X_6_0("Use position()")
+ QPointF pos() const { return position(); }
+ QT_DEPRECATED_VERSION_X_6_0("Use pressPosition()")
+ QPointF startPos() const { return pressPosition(); }
+ QT_DEPRECATED_VERSION_X_6_0("Use scenePosition()")
+ QPointF scenePos() const { return scenePosition(); }
+ QT_DEPRECATED_VERSION_X_6_0("Use scenePressPosition()")
+ QPointF startScenePos() const { return scenePressPosition(); }
+ QT_DEPRECATED_VERSION_X_6_0("Use globalPosition()")
+ QPointF screenPos() const { return globalPosition(); }
+ QT_DEPRECATED_VERSION_X_6_0("Use globalPressPosition()")
+ QPointF startScreenPos() const { return globalPressPosition(); }
+ QT_DEPRECATED_VERSION_X_6_0("Use globalPressPosition()")
+ QPointF startNormalizedPos() const;
+ QT_DEPRECATED_VERSION_X_6_0("Use normalizedPosition()")
+ QPointF normalizedPos() const { return normalizedPosition(); }
+ QT_DEPRECATED_VERSION_X_6_0("Use lastPosition()")
+ QPointF lastPos() const { return lastPosition(); }
+ QT_DEPRECATED_VERSION_X_6_0("Use sceneLastPosition()")
+ QPointF lastScenePos() const { return sceneLastPosition(); }
+ QT_DEPRECATED_VERSION_X_6_0("Use globalLastPosition()")
+ QPointF lastScreenPos() const { return globalLastPosition(); }
+ QT_DEPRECATED_VERSION_X_6_0("Use globalLastPosition()")
+ QPointF lastNormalizedPos() const;
+#endif // QT_DEPRECATED_SINCE(6, 0)
+ QVector2D velocity() const;
+ State state() const;
+ const QPointingDevice *device() const;
+ int id() const;
+ QPointingDeviceUniqueId uniqueId() const;
+ ulong timestamp() const;
+ ulong lastTimestamp() const;
+ ulong pressTimestamp() const;
+ qreal timeHeld() const;
+ qreal pressure() const;
+ qreal rotation() const;
+ QSizeF ellipseDiameters() const;
+
+ bool isAccepted() const;
+ void setAccepted(bool accepted = true);
+
+private:
+ QEventPointPrivate *d;
+ friend class QMutableEventPoint;
+ friend class QPointerEvent;
+};
+
+#ifndef QT_NO_DEBUG_STREAM
+Q_GUI_EXPORT QDebug operator<<(QDebug, const QEventPoint *);
+Q_GUI_EXPORT QDebug operator<<(QDebug, const QEventPoint &);
+#endif
+
+QT_END_NAMESPACE
+
+#endif // QEVENTPOINT_H
diff --git a/src/gui/kernel/qeventpoint_p.h b/src/gui/kernel/qeventpoint_p.h
new file mode 100644
index 0000000000..147d134bda
--- /dev/null
+++ b/src/gui/kernel/qeventpoint_p.h
@@ -0,0 +1,200 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QEVENTPOINT_P_H
+#define QEVENTPOINT_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtGui/private/qtguiglobal_p.h>
+#include <QtGui/qevent.h>
+#include <QtCore/qloggingcategory.h>
+
+QT_BEGIN_NAMESPACE
+
+Q_DECLARE_LOGGING_CATEGORY(lcPointerVel);
+Q_DECLARE_LOGGING_CATEGORY(lcEPDetach);
+
+class QPointingDevice;
+
+struct QEventPointPrivate {
+ QEventPointPrivate(int id, const QPointingDevice *device)
+ : device(device), pointId(id) { }
+
+ QEventPointPrivate(int pointId, QEventPoint::State state, const QPointF &scenePosition, const QPointF &globalPosition)
+ : scenePos(scenePosition), globalPos(globalPosition), pointId(pointId), state(state)
+ {
+ if (state == QEventPoint::State::Released)
+ pressure = 0;
+ }
+ inline bool operator==(const QEventPointPrivate &other) const
+ {
+ return device == other.device
+ && window == other.window
+ && target == other.target
+ && pos == other.pos
+ && scenePos == other.scenePos
+ && globalPos == other.globalPos
+ && globalPressPos == other.globalPressPos
+ && globalGrabPos == other.globalGrabPos
+ && globalLastPos == other.globalLastPos
+ && pressure == other.pressure
+ && rotation == other.rotation
+ && ellipseDiameters == other.ellipseDiameters
+ && velocity == other.velocity
+ && timestamp == other.timestamp
+ && lastTimestamp == other.lastTimestamp
+ && pressTimestamp == other.pressTimestamp
+ && uniqueId == other.uniqueId
+ && pointId == other.pointId
+ && state == other.state;
+ }
+
+ const QPointingDevice *device = nullptr;
+ QPointer<QWindow> window;
+ QPointer<QObject> target;
+ QPointF pos, scenePos, globalPos,
+ globalPressPos, globalGrabPos, globalLastPos;
+ qreal pressure = 1;
+ qreal rotation = 0;
+ QSizeF ellipseDiameters = QSizeF(0, 0);
+ QVector2D velocity;
+ ulong timestamp = 0;
+ ulong lastTimestamp = 0;
+ ulong pressTimestamp = 0;
+ QPointingDeviceUniqueId uniqueId;
+ int refCount = 1;
+ int pointId = -1;
+ QEventPoint::State state = QEventPoint::State::Unknown;
+ bool accept = false;
+};
+
+// Private subclasses to allow accessing and modifying protected variables.
+// These should NOT hold any extra state.
+
+class Q_GUI_EXPORT QMutableEventPoint : public QEventPoint
+{
+public:
+ QMutableEventPoint(int pointId = -1, State state = QEventPoint::State::Stationary,
+ const QPointF &scenePosition = QPointF(), const QPointF &globalPosition = QPointF()) :
+ QEventPoint(pointId, state, scenePosition, globalPosition) {}
+
+ QMutableEventPoint(ulong timestamp, int pointId, State state,
+ const QPointF &position, const QPointF &scenePosition, const QPointF &globalPosition) :
+ QEventPoint(pointId, state, scenePosition, globalPosition)
+ {
+ d->timestamp = timestamp;
+ d->pos = position;
+ }
+
+ void updateFrom(const QEventPoint &other);
+
+ static QMutableEventPoint *from(QEventPoint *me) { return static_cast<QMutableEventPoint *>(me); }
+
+ static QMutableEventPoint &from(QEventPoint &me) { return static_cast<QMutableEventPoint &>(me); }
+
+ static const QMutableEventPoint &constFrom(const QEventPoint &me) { return static_cast<const QMutableEventPoint &>(me); }
+
+ void detach();
+
+ void setId(int pointId) { d->pointId = pointId; }
+
+ void setDevice(const QPointingDevice *device) { d->device = device; }
+
+ void setTimestamp(const ulong t);
+
+ void setPressTimestamp(const ulong t) { d->pressTimestamp = t; }
+
+ void setState(QEventPoint::State state) { d->state = state; }
+
+ void setUniqueId(const QPointingDeviceUniqueId &uid) { d->uniqueId = uid; }
+
+ void setPosition(const QPointF &pos) { d->pos = pos; }
+
+ void setScenePosition(const QPointF &pos) { d->scenePos = pos; }
+
+ void setGlobalPosition(const QPointF &pos) { d->globalPos = pos; }
+
+#if QT_DEPRECATED_SINCE(6, 0)
+ // temporary replacements for QTouchEvent::TouchPoint setters, mainly to make porting easier
+ QT_DEPRECATED_VERSION_X_6_0("Use setPosition()")
+ void setPos(const QPointF &pos) { d->pos = pos; }
+ QT_DEPRECATED_VERSION_X_6_0("Use setScenePosition()")
+ void setScenePos(const QPointF &pos) { d->scenePos = pos; }
+ QT_DEPRECATED_VERSION_X_6_0("Use setGlobalPosition()")
+ void setScreenPos(const QPointF &pos) { d->globalPos = pos; }
+#endif
+
+ void setGlobalPressPosition(const QPointF &pos) { d->globalPressPos = pos; }
+
+ void setGlobalGrabPosition(const QPointF &pos) { d->globalGrabPos = pos; }
+
+ void setGlobalLastPosition(const QPointF &pos) { d->globalLastPos = pos; }
+
+ void setEllipseDiameters(const QSizeF &diams) { d->ellipseDiameters = diams; }
+
+ void setPressure(qreal v) { d->pressure = v; }
+
+ void setRotation(qreal v) { d->rotation = v; }
+
+ void setVelocity(const QVector2D &v) { d->velocity = v; }
+
+ QWindow *window() const { return d->window.data(); }
+
+ void setWindow(const QPointer<QWindow> &w) { d->window = w; }
+
+ QObject *target() const { return d->target.data(); }
+
+ void setTarget(const QPointer<QObject> &t) { d->target = t; }
+};
+
+static_assert(sizeof(QMutableEventPoint) == sizeof(QEventPoint));
+
+QT_END_NAMESPACE
+
+#endif // QEVENTPOINT_P_H
diff --git a/src/gui/kernel/qinputdevice.cpp b/src/gui/kernel/qinputdevice.cpp
index 09b1939c29..eb3259347a 100644
--- a/src/gui/kernel/qinputdevice.cpp
+++ b/src/gui/kernel/qinputdevice.cpp
@@ -40,16 +40,14 @@
#include "qinputdevice.h"
#include "qinputdevice_p.h"
#include "qpointingdevice.h"
+#include "qwindowsysteminterface_p.h"
#include <QCoreApplication>
#include <QDebug>
-#include <QLoggingCategory>
#include <QMutex>
#include <QScreen>
QT_BEGIN_NAMESPACE
-Q_DECLARE_LOGGING_CATEGORY(lcQpaInputDevices)
-
/*!
\class QInputDevice
\brief The QInputDevice class describes a device from which a QInputEvent originates.
diff --git a/src/gui/kernel/qpointingdevice.cpp b/src/gui/kernel/qpointingdevice.cpp
index fa04ad21f6..24ce68e430 100644
--- a/src/gui/kernel/qpointingdevice.cpp
+++ b/src/gui/kernel/qpointingdevice.cpp
@@ -39,6 +39,7 @@
#include "qpointingdevice.h"
#include "qpointingdevice_p.h"
+#include "qwindowsysteminterface_p.h"
#include <QList>
#include <QLoggingCategory>
#include <QMutex>
@@ -48,8 +49,7 @@
QT_BEGIN_NAMESPACE
-Q_DECLARE_LOGGING_CATEGORY(lcQpaInputDevices)
-Q_DECLARE_LOGGING_CATEGORY(lcPointerGrab)
+Q_LOGGING_CATEGORY(lcPointerGrab, "qt.pointer.grab");
/*!
\class QPointingDevice
@@ -663,4 +663,91 @@ QDebug operator<<(QDebug debug, const QPointingDevice *device)
}
#endif // !QT_NO_DEBUG_STREAM
+/*!
+ \class QPointingDeviceUniqueId
+ \since 5.8
+ \ingroup events
+ \inmodule QtGui
+
+ \brief QPointingDeviceUniqueId identifies a unique object, such as a tagged token
+ or stylus, which is used with a pointing device.
+
+ QPointingDeviceUniqueIds can be compared for equality, and can be used as keys in a QHash.
+ You get access to the numerical ID via numericId(), if the device supports such IDs.
+ For future extensions, though, you should not use that function, but compare objects
+ of this type using the equality operator.
+
+ This class is a thin wrapper around an integer ID. You pass it into and out of
+ functions by value.
+
+ \sa QEventPoint
+*/
+
+/*!
+ \fn QPointingDeviceUniqueId::QPointingDeviceUniqueId()
+ Constructs an invalid unique pointer ID.
+*/
+
+/*!
+ Constructs a unique pointer ID from numeric ID \a id.
+*/
+QPointingDeviceUniqueId QPointingDeviceUniqueId::fromNumericId(qint64 id)
+{
+ QPointingDeviceUniqueId result;
+ result.m_numericId = id;
+ return result;
+}
+
+/*!
+ \fn bool QPointingDeviceUniqueId::isValid() const
+
+ Returns whether this unique pointer ID is valid, that is, it represents an actual
+ pointer.
+*/
+
+/*!
+ \property QPointingDeviceUniqueId::numericId
+ \brief the numeric unique ID of the token represented by a touchpoint
+
+ If the device provides a numeric ID, isValid() returns true, and this
+ property provides the numeric ID;
+ otherwise it is -1.
+
+ You should not use the value of this property in portable code, but
+ instead rely on equality to identify pointers.
+
+ \sa isValid()
+*/
+qint64 QPointingDeviceUniqueId::numericId() const noexcept
+{
+ return m_numericId;
+}
+
+/*!
+ \fn bool QPointingDeviceUniqueId::operator==(QPointingDeviceUniqueId lhs, QPointingDeviceUniqueId rhs)
+ \since 5.8
+
+ Returns whether the two unique pointer IDs \a lhs and \a rhs identify the same pointer
+ (\c true) or not (\c false).
+*/
+
+/*!
+ \fn bool QPointingDeviceUniqueId::operator!=(QPointingDeviceUniqueId lhs, QPointingDeviceUniqueId rhs)
+ \since 5.8
+
+ Returns whether the two unique pointer IDs \a lhs and \a rhs identify different pointers
+ (\c true) or not (\c false).
+*/
+
+/*!
+ \relates QPointingDeviceUniqueId
+ \since 5.8
+
+ Returns the hash value for \a key, using \a seed to seed the calculation.
+*/
+size_t qHash(QPointingDeviceUniqueId key, size_t seed) noexcept
+{
+ return qHash(key.numericId(), seed);
+}
+
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qpointingdevice_p.h b/src/gui/kernel/qpointingdevice_p.h
index 299b99959e..6f787b4159 100644
--- a/src/gui/kernel/qpointingdevice_p.h
+++ b/src/gui/kernel/qpointingdevice_p.h
@@ -51,6 +51,7 @@
// We mean it.
//
+#include <QtCore/qloggingcategory.h>
#include <QtGui/private/qevent_p.h>
#include <QtGui/qpointingdevice.h>
#include <QtGui/private/qtguiglobal_p.h>
@@ -59,6 +60,8 @@
QT_BEGIN_NAMESPACE
+Q_DECLARE_LOGGING_CATEGORY(lcPointerGrab);
+
class Q_GUI_EXPORT QPointingDevicePrivate : public QInputDevicePrivate
{
Q_DECLARE_PUBLIC(QPointingDevice)
diff --git a/src/gui/kernel/qwindowsysteminterface_p.h b/src/gui/kernel/qwindowsysteminterface_p.h
index a2927cbc02..af149cd2ab 100644
--- a/src/gui/kernel/qwindowsysteminterface_p.h
+++ b/src/gui/kernel/qwindowsysteminterface_p.h
@@ -60,9 +60,12 @@
#include <QList>
#include <QWaitCondition>
#include <QAtomicInt>
+#include <QLoggingCategory>
QT_BEGIN_NAMESPACE
+Q_DECLARE_LOGGING_CATEGORY(lcQpaInputDevices);
+
class QWindowSystemEventHandler;
class Q_GUI_EXPORT QWindowSystemInterfacePrivate {