Refactor pointer event hierarchy

Some goals that have hopefully been achieved are:
- make QPointerEvent and QEventPoint resemble their Qt Quick
  counterparts to such an extent that we can remove those wrappers
  and go back to delivering the original events in Qt Quick
- make QEventPoint much smaller than QTouchEvent::TouchPoint, with no pimpl
- remove most public setters
- reduce the usage of complex constructors that take many arguments
- don't repeat ourselves: move accessors and storage upwards
  rather than having redundant ones in subclasses
- standardize the set of accessors in QPointerEvent
- maintain source compatibility as much as possible: do not require
  modifying event-handling code in any QWidget subclass

To avoid public setters we now introduce a few QMutable* subclasses.
This is a bit like the Builder pattern except that it doesn't involve
constructing a separate disposable object: the main event type can be
cast to the mutable type at any time to enable modifications, iff the
code is linked with gui-private. Therefore event classes can have
less-"complete" constructors, because internal Qt code can use setters
the same way it could use the ones in QTouchEvent before; and the event
classes don't need many friends. Even some read-accessors can be kept
private unless we are sure we want to expose them.

Task-number: QTBUG-46266
Fixes: QTBUG-72173
Change-Id: I740e4e40165b7bc41223d38b200bbc2b403e07b6
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
This commit is contained in:
Shawn Rutledge 2020-03-27 16:06:11 +00:00
parent 773a6bffd7
commit 4e400369c0
46 changed files with 1407 additions and 1886 deletions

View File

@ -1618,6 +1618,7 @@ namespace Qt {
};
enum TouchPointState {
TouchPointUnknownState = 0x00,
TouchPointPressed = 0x01,
TouchPointMoved = 0x02,
TouchPointStationary = 0x04,
@ -1707,6 +1708,7 @@ namespace Qt {
};
enum MouseEventFlag {
NoMouseEventFlag = 0x00,
MouseEventCreatedDoubleClick = 0x01,
MouseEventFlagMask = 0xFF
};

File diff suppressed because it is too large Load Diff

View File

@ -46,6 +46,7 @@
#include <QtCore/qiodevice.h>
#include <QtCore/qlist.h>
#include <QtCore/qnamespace.h>
#include <QtCore/qpointer.h>
#include <QtCore/qstring.h>
#include <QtCore/qurl.h>
#include <QtCore/qvariant.h>
@ -64,6 +65,7 @@ class QFile;
class QAction;
class QInputDevice;
class QPointingDevice;
class QPointerEvent;
class QScreen;
#if QT_CONFIG(gestures)
class QGesture;
@ -80,15 +82,130 @@ public:
inline void setModifiers(Qt::KeyboardModifiers amodifiers) { modState = amodifiers; }
inline ulong timestamp() const { return ts; }
inline void setTimestamp(ulong atimestamp) { ts = atimestamp; }
protected:
const QInputDevice *m_dev = nullptr;
Qt::KeyboardModifiers modState;
Qt::KeyboardModifiers modState = Qt::NoModifier;
ulong ts;
qint64 m_extra = 0; // reserved, unused for now
};
namespace QTest {
class QTouchEventSequence; // just for the friend declaration below
}
class Q_GUI_EXPORT QEventPoint
{
Q_GADGET
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 QPointerEvent *parent = nullptr);
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 pressPosition() const { return m_globalPressPos - m_globalPos + m_pos; }
QPointF grabPosition() const { return m_globalGrabPos - m_globalPos + m_pos; }
QPointF lastPosition() const { return m_globalLastPos - m_globalPos + m_pos; }
QPointF scenePosition() const { return m_scenePos; }
QPointF scenePressPosition() const { return m_globalPressPos - m_globalPos + m_scenePos; }
QPointF sceneGrabPosition() const { return m_globalGrabPos - m_globalPos + m_scenePos; }
QPointF sceneLastPosition() const { return m_globalLastPos - m_globalPos + m_scenePos; }
QPointF globalPosition() const { return m_globalPos; }
QPointF globalPressPosition() const { return m_globalPressPos; }
QPointF globalGrabPosition() const { return m_globalGrabPos; }
QPointF globalLastPosition() const { return m_globalLastPos; }
#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 globalPosition()")
QPointF normalizedPos() const;
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 { return m_velocity; }
State state() const { return m_state; }
int id() const { return m_pointId; }
QPointingDeviceUniqueId uniqueId() const { return m_uniqueId; }
qreal timeHeld() const { return (m_timestamp - m_pressTimestamp) / qreal(1000); }
qreal pressure() const { return m_pressure; }
qreal rotation() const { return m_rotation; }
QSizeF ellipseDiameters() const { return m_ellipseDiameters; }
bool isAccepted() const { return m_accept; }
void setAccepted(bool accepted = true);
QObject *exclusiveGrabber() const { return m_exclusiveGrabber.data(); }
void setExclusiveGrabber(QObject *exclusiveGrabber);
void cancelExclusiveGrab();
void cancelPassiveGrab(QObject *grabber);
bool removePassiveGrabber(QObject *grabber);
void cancelAllGrabs(QObject *grabber);
const QList<QPointer <QObject>> &passiveGrabbers() const { return m_passiveGrabbers; }
void setPassiveGrabbers(const QList<QPointer <QObject>> &grabbers);
void clearPassiveGrabbers();
protected:
const QPointerEvent *m_parent = nullptr;
QPointF m_pos, m_scenePos, m_globalPos,
m_globalPressPos, m_globalGrabPos, m_globalLastPos;
qreal m_pressure = 1;
qreal m_rotation = 0;
QSizeF m_ellipseDiameters = QSizeF(0, 0);
QVector2D m_velocity;
QPointer<QObject> m_exclusiveGrabber;
QList<QPointer <QObject> > m_passiveGrabbers;
ulong m_timestamp = 0;
ulong m_pressTimestamp = 0;
QPointingDeviceUniqueId m_uniqueId;
int m_pointId = -1;
State m_state : 8;
quint32 m_accept : 1;
quint32 m_stationaryWithModifiedProperty : 1;
quint32 m_reserved : 22;
friend class QTest::QTouchEventSequence;
};
#ifndef QT_NO_DEBUG_STREAM
Q_GUI_EXPORT QDebug operator<<(QDebug, const QEventPoint &);
#endif
class Q_GUI_EXPORT QPointerEvent : public QInputEvent
{
public:
virtual ~QPointerEvent();
virtual int pointCount() const = 0;
virtual const QEventPoint &point(int i) const = 0;
explicit QPointerEvent(Type type, const QPointingDevice *dev, Qt::KeyboardModifiers modifiers = Qt::NoModifier);
const QPointingDevice *pointingDevice() const;
QPointingDevice::PointerType pointerType() const {
@ -96,10 +213,38 @@ public:
}
};
class Q_GUI_EXPORT QEnterEvent : public QEvent
class Q_GUI_EXPORT QSinglePointEvent : public QPointerEvent
{
public:
QEnterEvent(const QPointF &localPos, const QPointF &scenePos, const QPointF &globalPos);
QSinglePointEvent();
QSinglePointEvent(Type type, const QPointingDevice *dev, const QPointF &localPos,
const QPointF &scenePos, const QPointF &globalPos,
Qt::MouseButton button = Qt::NoButton, Qt::MouseButtons buttons = Qt::NoButton,
Qt::KeyboardModifiers modifiers = Qt::NoModifier);
int pointCount() const override { return 1; }
const QEventPoint &point(int i) const override { Q_ASSERT(i == 0); return m_point; }
inline Qt::MouseButton button() const { return m_button; }
inline Qt::MouseButtons buttons() const { return m_mouseState; }
inline QPointF position() const { return m_point.position(); }
inline QPointF scenePosition() const { return m_point.scenePosition(); }
inline QPointF globalPosition() const { return m_point.globalPosition(); }
protected:
QEventPoint m_point;
Qt::MouseButton m_button = Qt::NoButton;
Qt::MouseButtons m_mouseState = Qt::NoButton;
quint32 m_source : 8; // actually Qt::MouseEventSource
quint32 m_doubleClick : 1;
quint32 m_reserved : 7; // subclasses dovetail their flags, so we don't reserve all 32 bits here
};
class Q_GUI_EXPORT QEnterEvent : public QSinglePointEvent
{
public:
QEnterEvent(const QPointF &localPos, const QPointF &scenePos, const QPointF &globalPos,
const QPointingDevice *device = QPointingDevice::primaryPointingDevice());
~QEnterEvent();
#if QT_DEPRECATED_SINCE(6, 0)
@ -124,29 +269,26 @@ public:
QT_DEPRECATED_VERSION_X_6_0("Use globalPosition()")
QPointF screenPos() const { return globalPosition(); }
#endif // QT_DEPRECATED_SINCE(6, 0)
QPointF position() const { return l; }
QPointF scenePosition() const { return s; }
QPointF globalPosition() const { return g; }
protected:
QPointF l, s, g;
};
class Q_GUI_EXPORT QMouseEvent : public QPointerEvent
class Q_GUI_EXPORT QMouseEvent : public QSinglePointEvent
{
public:
QMouseEvent(Type type, const QPointF &localPos, Qt::MouseButton button,
Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers);
Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers,
const QPointingDevice *device = QPointingDevice::primaryPointingDevice());
QMouseEvent(Type type, const QPointF &localPos, const QPointF &globalPos,
Qt::MouseButton button, Qt::MouseButtons buttons,
Qt::KeyboardModifiers modifiers);
Qt::KeyboardModifiers modifiers,
const QPointingDevice *device = QPointingDevice::primaryPointingDevice());
QMouseEvent(Type type, const QPointF &localPos, const QPointF &scenePos, const QPointF &globalPos,
Qt::MouseButton button, Qt::MouseButtons buttons,
Qt::KeyboardModifiers modifiers);
Qt::KeyboardModifiers modifiers,
const QPointingDevice *device = QPointingDevice::primaryPointingDevice());
QMouseEvent(Type type, const QPointF &localPos, const QPointF &scenePos, const QPointF &globalPos,
Qt::MouseButton button, Qt::MouseButtons buttons,
Qt::KeyboardModifiers modifiers, Qt::MouseEventSource source);
Qt::KeyboardModifiers modifiers, Qt::MouseEventSource source,
const QPointingDevice *device = QPointingDevice::primaryPointingDevice());
~QMouseEvent();
#ifndef QT_NO_INTEGER_EVENT_COORDINATES
@ -171,34 +313,18 @@ public:
QPointF windowPos() const { return scenePosition(); }
QT_DEPRECATED_VERSION_X_6_0("Use globalPosition()")
QPointF screenPos() const { return globalPosition(); }
#endif // QT_DEPRECATED_SINCE(6, 0)
QPointF position() const { return l; }
QPointF scenePosition() const { return w; }
QPointF globalPosition() const { return g; }
inline Qt::MouseButton button() const { return b; }
inline Qt::MouseButtons buttons() const { return mouseState; }
inline void setLocalPos(const QPointF &localPosition) { l = localPosition; }
Qt::MouseEventSource source() const;
QT_DEPRECATED_VERSION_X_6_0("Internal, don't use")
Qt::MouseEventFlags flags() const;
protected:
QPointF l, w, g;
Qt::MouseButton b;
Qt::MouseButtons mouseState;
int caps;
QVector2D velocity;
friend class QGuiApplicationPrivate;
#endif // QT_DEPRECATED_SINCE(6, 0)
};
class Q_GUI_EXPORT QHoverEvent : public QInputEvent
class Q_GUI_EXPORT QHoverEvent : public QSinglePointEvent
{
public:
QHoverEvent(Type type, const QPointF &pos, const QPointF &oldPos, Qt::KeyboardModifiers modifiers = Qt::NoModifier);
QHoverEvent(Type type, const QPointF &pos, const QPointF &oldPos,
Qt::KeyboardModifiers modifiers = Qt::NoModifier,
const QPointingDevice *device = QPointingDevice::primaryPointingDevice());
~QHoverEvent();
#if QT_DEPRECATED_SINCE(6, 0)
@ -215,63 +341,51 @@ public:
inline QPoint oldPos() const { return op.toPoint(); }
inline QPointF oldPosF() const { return op; }
QPointF position() const { return p; }
protected:
QPointF p, op;
quint32 mReserved : 16;
QPointF op; // TODO remove?
};
#if QT_CONFIG(wheelevent)
class Q_GUI_EXPORT QWheelEvent : public QPointerEvent
class Q_GUI_EXPORT QWheelEvent : public QSinglePointEvent
{
public:
enum { DefaultDeltasPerStep = 120 };
QWheelEvent(QPointF pos, QPointF globalPos, QPoint pixelDelta, QPoint angleDelta,
QWheelEvent(const QPointF &pos, const QPointF &globalPos, QPoint pixelDelta, QPoint angleDelta,
Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers, Qt::ScrollPhase phase,
bool inverted, Qt::MouseEventSource source = Qt::MouseEventNotSynthesized);
bool inverted, Qt::MouseEventSource source = Qt::MouseEventNotSynthesized,
const QPointingDevice *device = QPointingDevice::primaryPointingDevice());
~QWheelEvent();
inline QPoint pixelDelta() const { return m_pixelDelta; }
inline QPoint angleDelta() const { return m_angleDelta; }
inline QPoint pixelDelta() const { return pixelD; }
inline QPoint angleDelta() const { return angleD; }
inline Qt::ScrollPhase phase() const { return Qt::ScrollPhase(m_phase); }
inline bool inverted() const { return m_invertedScrolling; }
inline QPointF position() const { return p; }
inline QPointF globalPosition() const { return g; }
inline Qt::MouseButtons buttons() const { return mouseState; }
inline Qt::ScrollPhase phase() const { return Qt::ScrollPhase(ph); }
inline bool inverted() const { return invertedScrolling; }
Qt::MouseEventSource source() const { return Qt::MouseEventSource(src); }
Qt::MouseEventSource source() const { return Qt::MouseEventSource(m_source); }
protected:
QPointF p;
QPointF g;
QPoint pixelD;
QPoint angleD;
Qt::MouseButtons mouseState;
uint src: 2;
uint ph : 3;
bool invertedScrolling : 1;
int reserved : 26;
friend class QApplication;
quint32 m_phase : 3;
quint32 m_invertedScrolling : 1;
quint32 m_reserved : 12;
QPoint m_pixelDelta;
QPoint m_angleDelta;
};
#endif
#if QT_CONFIG(tabletevent)
class Q_GUI_EXPORT QTabletEvent : public QPointerEvent
class Q_GUI_EXPORT QTabletEvent : public QSinglePointEvent
{
Q_GADGET
public:
QTabletEvent(Type t, const QPointF &pos, const QPointF &globalPos,
int deviceType, int pointerType, qreal pressure, int xTilt, int yTilt,
qreal tangentialPressure, qreal rotation, int z,
Qt::KeyboardModifiers keyState, qint64 uniqueID,
Qt::MouseButton button, Qt::MouseButtons buttons);
QTabletEvent(Type t, const QPointingDevice *dev, const QPointF &pos, const QPointF &globalPos,
QTabletEvent(Type t, const QPointingDevice *device,
const QPointF &pos, const QPointF &globalPos,
qreal pressure, int xTilt, int yTilt,
qreal tangentialPressure, qreal rotation, int z,
Qt::KeyboardModifiers keyState,
@ -300,37 +414,31 @@ public:
inline qreal hiResGlobalX() const { return globalPosition().x(); }
QT_DEPRECATED_VERSION_X_6_0("use globalPosition().y()")
inline qreal hiResGlobalY() const { return globalPosition().y(); }
#endif
inline QPointF position() const { return mPos; }
inline QPointF globalPosition() const { return mGPos; }
QT_DEPRECATED_VERSION_X_6_0("use pointingDevice().uniqueId()")
inline qint64 uniqueId() const { return pointingDevice() ? pointingDevice()->uniqueId().numericId() : -1; }
inline qreal pressure() const { return mPress; }
#endif
inline qreal pressure() const { return point(0).pressure(); }
inline qreal rotation() const { return point(0).rotation(); }
inline int z() const { return mZ; }
inline qreal tangentialPressure() const { return mTangential; }
inline qreal rotation() const { return mRot; }
inline int xTilt() const { return mXT; }
inline int yTilt() const { return mYT; }
inline Qt::MouseButton button() const { return mButton; }
inline Qt::MouseButtons buttons() const { return mButtons; }
protected:
QPointF mPos, mGPos;
quint32 mReserved : 16;
int mXT, mYT, mZ;
qreal mPress, mTangential, mRot;
// TODO refactor to parent class along with QMouseEvent's button storage
Qt::MouseButton mButton;
Qt::MouseButtons mButtons;
qreal mTangential;
};
#endif // QT_CONFIG(tabletevent)
#if QT_CONFIG(gestures)
class Q_GUI_EXPORT QNativeGestureEvent : public QPointerEvent
class Q_GUI_EXPORT QNativeGestureEvent : public QSinglePointEvent
{
public:
QNativeGestureEvent(Qt::NativeGestureType type, const QPointingDevice *dev, const QPointF &localPos, const QPointF &scenePos,
const QPointF &globalPos, qreal value, ulong sequenceId, quint64 intArgument);
~QNativeGestureEvent();
Qt::NativeGestureType gestureType() const { return mGestureType; }
Qt::NativeGestureType gestureType() const { return Qt::NativeGestureType(mGestureType); }
qreal value() const { return mRealValue; }
#if QT_DEPRECATED_SINCE(6, 0)
@ -348,15 +456,9 @@ public:
QPointF screenPos() const { return globalPosition(); }
#endif
QPointF position() const { return mLocalPos; }
QPointF scenePosition() const { return mScenePos; }
QPointF globalPosition() const { return mGlobalPos; }
protected:
Qt::NativeGestureType mGestureType;
QPointF mLocalPos;
QPointF mScenePos;
QPointF mGlobalPos;
quint32 mGestureType : 4;
quint32 mReserved : 12;
qreal mRealValue;
ulong mSequenceId;
quint64 mIntValue;
@ -370,7 +472,8 @@ public:
bool autorep = false, ushort count = 1);
QKeyEvent(Type type, int key, Qt::KeyboardModifiers modifiers,
quint32 nativeScanCode, quint32 nativeVirtualKey, quint32 nativeModifiers,
const QString &text = QString(), bool autorep = false, ushort count = 1);
const QString &text = QString(), bool autorep = false, ushort count = 1,
const QInputDevice *device = QInputDevice::primaryKeyboard());
~QKeyEvent();
int key() const { return k; }
@ -829,156 +932,34 @@ class QTouchEventTouchPointPrivate;
class Q_GUI_EXPORT QTouchEvent : public QPointerEvent
{
public:
class Q_GUI_EXPORT TouchPoint
{
public:
enum InfoFlag {
Pen = 0x0001,
Token = 0x0002
};
#ifndef Q_MOC_RUN
// otherwise moc gives
// Error: Meta object features not supported for nested classes
Q_DECLARE_FLAGS(InfoFlags, InfoFlag)
#endif
explicit TouchPoint(int id = -1);
TouchPoint(const TouchPoint &other);
TouchPoint(TouchPoint &&other) noexcept
: d(nullptr)
{ qSwap(d, other.d); }
TouchPoint &operator=(TouchPoint &&other) noexcept
{ qSwap(d, other.d); return *this; }
~TouchPoint();
TouchPoint &operator=(const TouchPoint &other)
{ if ( d != other.d ) { TouchPoint copy(other); swap(copy); } return *this; }
void swap(TouchPoint &other) noexcept
{ qSwap(d, other.d); }
int id() const;
QPointingDeviceUniqueId uniqueId() const;
Qt::TouchPointState state() const;
#if QT_DEPRECATED_SINCE(6, 0)
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(); }
#endif // QT_DEPRECATED_SINCE(6, 0)
// TODO deprecate these after finding good replacements (use QPointingDevice::globalArea?)
QPointF normalizedPos() const;
QPointF startNormalizedPos() const;
// TODO deprecate these after finding good replacements (store longer history perhaps?)
QPointF lastPos() const;
QPointF lastScenePos() const;
QPointF lastScreenPos() const;
QPointF lastNormalizedPos() const;
QPointF position() const;
QPointF pressPosition() const;
QPointF scenePosition() const;
QPointF scenePressPosition() const;
QPointF globalPosition() const;
QPointF globalPressPosition() const;
qreal pressure() const;
qreal rotation() const;
QSizeF ellipseDiameters() const;
QVector2D velocity() const;
InfoFlags flags() const;
QList<QPointF> rawScreenPositions() const;
// internal
// ### Qt 6: move private, rename appropriately, only friends can call them
#if QT_DEPRECATED_SINCE(6, 0)
void setId(int id);
void setUniqueId(qint64 uid);
void setState(Qt::TouchPointStates state);
void setPos(const QPointF &pos);
void setScenePos(const QPointF &scenePos);
void setScreenPos(const QPointF &screenPos);
void setNormalizedPos(const QPointF &normalizedPos);
void setStartPos(const QPointF &startPos);
void setStartScenePos(const QPointF &startScenePos);
void setStartScreenPos(const QPointF &startScreenPos);
void setStartNormalizedPos(const QPointF &startNormalizedPos);
void setLastPos(const QPointF &lastPos);
void setLastScenePos(const QPointF &lastScenePos);
void setLastScreenPos(const QPointF &lastScreenPos);
void setLastNormalizedPos(const QPointF &lastNormalizedPos);
void setPressure(qreal pressure);
void setRotation(qreal angle);
void setEllipseDiameters(const QSizeF &dia);
void setVelocity(const QVector2D &v);
void setFlags(InfoFlags flags);
void setRawScreenPositions(const QList<QPointF> &positions);
#endif // QT_DEPRECATED_SINCE(6, 0)
private:
QTouchEventTouchPointPrivate *d;
friend class QGuiApplication;
friend class QGuiApplicationPrivate;
friend class QApplication;
friend class QApplicationPrivate;
friend class QQuickPointerTouchEvent;
friend class QQuickMultiPointTouchArea;
};
using TouchPoint = QEventPoint; // source compat
explicit QTouchEvent(QEvent::Type eventType,
const QPointingDevice *source = nullptr,
const QPointingDevice *device = nullptr,
Qt::KeyboardModifiers modifiers = Qt::NoModifier,
Qt::TouchPointStates touchPointStates = Qt::TouchPointStates(),
const QList<QTouchEvent::TouchPoint> &touchPoints = QList<QTouchEvent::TouchPoint>());
const QList<QEventPoint> &touchPoints = {});
#if QT_DEPRECATED_SINCE(6, 0)
QT_DEPRECATED_VERSION_X_6_0("Use another constructor")
explicit QTouchEvent(QEvent::Type eventType,
const QPointingDevice *device,
Qt::KeyboardModifiers modifiers,
QEventPoint::States touchPointStates,
const QList<QEventPoint> &touchPoints = {});
#endif
~QTouchEvent();
inline QWindow *window() const { return _window; }
inline QObject *target() const { return _target; }
inline Qt::TouchPointStates touchPointStates() const { return _touchPointStates; }
inline const QList<QTouchEvent::TouchPoint> &touchPoints() const { return _touchPoints; }
int pointCount() const override { return m_touchPoints.count(); }
const QEventPoint &point(int i) const override { return m_touchPoints.at(i); }
// ### Qt 6: move private, rename appropriately, only friends can call them; or just let friends modify variables directly
#if QT_DEPRECATED_SINCE(6, 0)
inline void setWindow(QWindow *awindow) { _window = awindow; }
inline void setTarget(QObject *atarget) { _target = atarget; }
inline void setTouchPoints(const QList<QTouchEvent::TouchPoint> &atouchPoints) { _touchPoints = atouchPoints; }
#endif // QT_DEPRECATED_SINCE(6, 0)
inline QObject *target() const { return m_target; }
inline QEventPoint::States touchPointStates() const { return m_touchPointStates; }
const QList<QEventPoint> &touchPoints() const { return m_touchPoints; }
protected:
QWindow *_window;
QObject *_target;
Qt::TouchPointStates _touchPointStates;
QList<QTouchEvent::TouchPoint> _touchPoints;
friend class QGuiApplication;
friend class QGuiApplicationPrivate;
friend class QApplication;
friend class QApplicationPrivate;
#ifndef QT_NO_GRAPHICSVIEW
friend class QGraphicsScenePrivate; // direct access to _touchPoints
#endif
QObject *m_target = nullptr;
QEventPoint::States m_touchPointStates = QEventPoint::State::Unknown;
QList<QEventPoint> m_touchPoints;
};
Q_DECLARE_TYPEINFO(QTouchEvent::TouchPoint, Q_MOVABLE_TYPE);
Q_DECLARE_OPERATORS_FOR_FLAGS(QTouchEvent::TouchPoint::InfoFlags)
#ifndef QT_NO_DEBUG_STREAM
Q_GUI_EXPORT QDebug operator<<(QDebug, const QTouchEvent::TouchPoint &);
#endif
class Q_GUI_EXPORT QScrollPrepareEvent : public QEvent
{

View File

@ -47,55 +47,113 @@
QT_BEGIN_NAMESPACE
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
// Private subclasses to allow accessing and modifying protected variables.
// These should NOT hold any extra state.
class QTouchEventTouchPointPrivate
class QMutableEventPoint : public QEventPoint
{
public:
inline QTouchEventTouchPointPrivate(int id)
: ref(1),
id(id),
state(Qt::TouchPointReleased),
pressure(-1),
rotation(0),
ellipseDiameters(0, 0),
stationaryWithModifiedProperty(false)
{ }
QMutableEventPoint(int pointId = -1, State state = QEventPoint::State::Stationary,
const QPointF &scenePosition = QPointF(), const QPointF &globalPosition = QPointF()) :
QEventPoint(pointId, state, scenePosition, globalPosition) {}
inline QTouchEventTouchPointPrivate *detach()
QMutableEventPoint(ulong timestamp, int pointId, State state,
const QPointF &position, const QPointF &scenePosition, const QPointF &globalPosition) :
QEventPoint(pointId, state, scenePosition, globalPosition)
{
QTouchEventTouchPointPrivate *d = new QTouchEventTouchPointPrivate(*this);
d->ref.storeRelaxed(1);
if (!this->ref.deref())
delete this;
return d;
m_timestamp = timestamp;
m_pos = position;
}
QAtomicInt ref;
int id;
QPointingDeviceUniqueId uniqueId;
Qt::TouchPointStates state;
QPointF pos, scenePos, screenPos, normalizedPos,
startPos, startScenePos, startScreenPos, startNormalizedPos,
lastPos, lastScenePos, lastScreenPos, lastNormalizedPos;
qreal pressure;
qreal rotation;
QSizeF ellipseDiameters;
QVector2D velocity;
QTouchEvent::TouchPoint::InfoFlags flags;
bool stationaryWithModifiedProperty : 1;
QList<QPointF> rawScreenPositions;
static QMutableEventPoint *from(QEventPoint *me) { return static_cast<QMutableEventPoint *>(me); }
static QMutableEventPoint &from(QEventPoint &me) { return static_cast<QMutableEventPoint &>(me); }
bool stationaryWithModifiedProperty() const { return m_stationaryWithModifiedProperty; }
void setId(int pointId) { m_pointId = pointId; }
void setParent(const QPointerEvent *p) { m_parent = p; }
void setTimestamp(const ulong t) { m_timestamp = t; }
void setState(QEventPoint::State state) { m_state = state; }
void setUniqueId(const QPointingDeviceUniqueId &uid) { m_uniqueId = uid; }
void setPosition(const QPointF &pos) { m_pos = pos; }
void setScenePosition(const QPointF &pos) { m_scenePos = pos; }
void setGlobalPosition(const QPointF &pos) { m_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) { m_pos = pos; }
QT_DEPRECATED_VERSION_X_6_0("Use setScenePosition()")
void setScenePos(const QPointF &pos) { m_scenePos = pos; }
QT_DEPRECATED_VERSION_X_6_0("Use setGlobalPosition()")
void setScreenPos(const QPointF &pos) { m_globalPos = pos; }
#endif
void setGlobalPressPosition(const QPointF &pos) { m_globalPressPos = pos; }
void setGlobalGrabPosition(const QPointF &pos) { m_globalGrabPos = pos; }
void setGlobalLastPosition(const QPointF &pos) { m_globalLastPos = pos; }
void setEllipseDiameters(const QSizeF &d) { m_ellipseDiameters = d; }
void setPressure(qreal v) { m_pressure = v; }
void setRotation(qreal v) { m_rotation = v; }
void setVelocity(const QVector2D &v) { m_velocity = v; }
void setStationaryWithModifiedProperty(bool s = true) { m_stationaryWithModifiedProperty = s; }
};
static_assert(sizeof(QMutableEventPoint) == sizeof(QEventPoint));
class QMutableTouchEvent : public QTouchEvent
{
public:
QMutableTouchEvent(QEvent::Type eventType,
const QPointingDevice *device = nullptr,
Qt::KeyboardModifiers modifiers = Qt::NoModifier,
const QList<QEventPoint> &touchPoints = QList<QEventPoint>()) :
QTouchEvent(eventType, device, modifiers, touchPoints) { }
static QMutableTouchEvent *from(QTouchEvent *e) { return static_cast<QMutableTouchEvent *>(e); }
static QMutableTouchEvent &from(QTouchEvent &e) { return static_cast<QMutableTouchEvent &>(e); }
void setTarget(QObject *target) { m_target = target; }
QList<QEventPoint> &touchPoints() { return m_touchPoints; }
};
static_assert(sizeof(QMutableTouchEvent) == sizeof(QTouchEvent));
class QMutableSinglePointEvent : public QSinglePointEvent
{
public:
static QMutableSinglePointEvent *from(QSinglePointEvent *e) { return static_cast<QMutableSinglePointEvent *>(e); }
static QMutableSinglePointEvent &from(QSinglePointEvent &e) { return static_cast<QMutableSinglePointEvent &>(e); }
QMutableEventPoint &mutablePoint() { return QMutableEventPoint::from(m_point); }
void setSource(Qt::MouseEventSource s) { m_source = s; }
bool isDoubleClick() { return m_doubleClick; }
void setDoubleClick(bool d = true) { m_doubleClick = d; }
};
static_assert(sizeof(QMutableSinglePointEvent) == sizeof(QSinglePointEvent));
QT_END_NAMESPACE
#endif // QEVENT_P_H

View File

@ -2159,8 +2159,8 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo
if (mouseMove) {
QGuiApplicationPrivate::lastCursorPosition = globalPoint;
const auto doubleClickDistance = e->source == Qt::MouseEventNotSynthesized ?
mouseDoubleClickDistance : touchDoubleTapDistance;
const auto doubleClickDistance = (e->device && e->device->type() == QInputDevice::DeviceType::Mouse ?
mouseDoubleClickDistance : touchDoubleTapDistance);
if (qAbs(globalPoint.x() - mousePressX) > doubleClickDistance ||
qAbs(globalPoint.y() - mousePressY) > doubleClickDistance)
mousePressButton = Qt::NoButton;
@ -2199,6 +2199,7 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo
if (!window)
return;
const QPointingDevice *device = static_cast<const QPointingDevice *>(e->device);
#ifndef QT_NO_CURSOR
if (!e->synthetic()) {
if (const QScreen *screen = window->screen())
@ -2206,14 +2207,14 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo
const QPointF nativeLocalPoint = QHighDpi::toNativePixels(localPoint, screen);
const QPointF nativeGlobalPoint = QHighDpi::toNativePixels(globalPoint, screen);
QMouseEvent ev(type, nativeLocalPoint, nativeLocalPoint, nativeGlobalPoint,
button, e->buttons, e->modifiers, e->source);
button, e->buttons, e->modifiers, e->source, device);
ev.setTimestamp(e->timestamp);
cursor->pointerEvent(ev);
}
}
#endif
QMouseEvent ev(type, localPoint, localPoint, globalPoint, button, e->buttons, e->modifiers, e->source);
QMouseEvent ev(type, localPoint, localPoint, globalPoint, button, e->buttons, e->modifiers, e->source, device);
ev.setTimestamp(e->timestamp);
if (window->d_func()->blockedByModalWindow && !qApp->d_func()->popupActive()) {
@ -2223,7 +2224,7 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo
if (doubleClick && (ev.type() == QEvent::MouseButtonPress)) {
// QtBUG-25831, used to suppress delivery in qwidgetwindow.cpp
setMouseEventFlags(&ev, ev.flags() | Qt::MouseEventCreatedDoubleClick);
QMutableSinglePointEvent::from(ev).setDoubleClick();
}
QGuiApplication::sendSpontaneousEvent(window, &ev);
@ -2244,11 +2245,11 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo
// avoid strange touch event sequences when several
// buttons are pressed
if (type == QEvent::MouseButtonPress && button == Qt::LeftButton) {
point.state = Qt::TouchPointPressed;
point.state = QEventPoint::State::Pressed;
} else if (type == QEvent::MouseButtonRelease && button == Qt::LeftButton) {
point.state = Qt::TouchPointReleased;
point.state = QEventPoint::State::Released;
} else if (type == QEvent::MouseMove && (e->buttons & Qt::LeftButton)) {
point.state = Qt::TouchPointMoved;
point.state = QEventPoint::State::Updated;
} else {
return;
}
@ -2256,7 +2257,7 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo
points << point;
QEvent::Type type;
QList<QTouchEvent::TouchPoint> touchPoints =
const QList<QEventPoint> &touchPoints =
QWindowSystemInterfacePrivate::fromNativeTouchPoints(points, window, &type);
QWindowSystemInterfacePrivate::TouchEvent fake(window, e->timestamp, type, m_fakeTouchDevice, touchPoints, e->modifiers);
@ -2268,7 +2269,7 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo
if (!e->window.isNull() || e->nullWindow()) { // QTBUG-36364, check if window closed in response to press
const QEvent::Type doubleClickType = e->nonClientArea ? QEvent::NonClientAreaMouseButtonDblClick : QEvent::MouseButtonDblClick;
QMouseEvent dblClickEvent(doubleClickType, localPoint, localPoint, globalPoint,
button, e->buttons, e->modifiers, e->source);
button, e->buttons, e->modifiers, e->source, device);
dblClickEvent.setTimestamp(e->timestamp);
QGuiApplication::sendSpontaneousEvent(window, &dblClickEvent);
}
@ -2301,10 +2302,11 @@ void QGuiApplicationPrivate::processWheelEvent(QWindowSystemInterfacePrivate::Wh
return;
}
QWheelEvent ev(localPoint, globalPoint, e->pixelDelta, e->angleDelta,
mouse_buttons, e->modifiers, e->phase, e->inverted, e->source);
ev.setTimestamp(e->timestamp);
QGuiApplication::sendSpontaneousEvent(window, &ev);
const QPointingDevice *device = static_cast<const QPointingDevice *>(e->device);
QWheelEvent ev(localPoint, globalPoint, e->pixelDelta, e->angleDelta,
mouse_buttons, e->modifiers, e->phase, e->inverted, e->source, device);
ev.setTimestamp(e->timestamp);
QGuiApplication::sendSpontaneousEvent(window, &ev);
#else
Q_UNUSED(e);
#endif // QT_CONFIG(wheelevent)
@ -2673,7 +2675,7 @@ void QGuiApplicationPrivate::processTabletEvent(QWindowSystemInterfacePrivate::T
}
}();
QWindowSystemInterfacePrivate::MouseEvent mouseEvent(window, e->timestamp, e->local,
e->global, e->buttons, e->modifiers, button, mouseType, Qt::MouseEventSynthesizedByQt);
e->global, e->buttons, e->modifiers, button, mouseType, Qt::MouseEventNotSynthesized, false, device);
mouseEvent.flags |= QWindowSystemInterfacePrivate::WindowSystemEvent::Synthetic;
processMouseEvent(&mouseEvent);
}
@ -2716,7 +2718,8 @@ void QGuiApplicationPrivate::processGestureEvent(QWindowSystemInterfacePrivate::
if (e->window.isNull())
return;
QNativeGestureEvent ev(e->type, e->device, e->pos, e->pos, e->globalPos, e->realValue, e->sequenceId, e->intValue);
const QPointingDevice *device = static_cast<const QPointingDevice *>(e->device);
QNativeGestureEvent ev(e->type, device, e->pos, e->pos, e->globalPos, e->realValue, e->sequenceId, e->intValue);
ev.setTimestamp(e->timestamp);
QGuiApplication::sendSpontaneousEvent(e->window, &ev);
}
@ -2765,11 +2768,12 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To
{
QGuiApplicationPrivate *d = self;
modifier_buttons = e->modifiers;
const QPointingDevice *device = static_cast<const QPointingDevice *>(e->device);
if (e->touchType == QEvent::TouchCancel) {
// The touch sequence has been canceled (e.g. by the compositor).
// Send the TouchCancel to all windows with active touches and clean up.
QTouchEvent touchEvent(QEvent::TouchCancel, static_cast<const QPointingDevice *>(e->device), e->modifiers);
QTouchEvent touchEvent(QEvent::TouchCancel, device, e->modifiers);
touchEvent.setTimestamp(e->timestamp);
QHash<ActiveTouchPointsKey, ActiveTouchPointsValue>::const_iterator it
= self->activeTouchPoints.constBegin(), ite = self->activeTouchPoints.constEnd();
@ -2782,7 +2786,6 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To
}
for (QSet<QWindow *>::const_iterator winIt = windowsNeedingCancel.constBegin(),
winItEnd = windowsNeedingCancel.constEnd(); winIt != winItEnd; ++winIt) {
touchEvent.setWindow(*winIt);
QGuiApplication::sendSpontaneousEvent(*winIt, &touchEvent);
}
if (!self->synthesizedMousePoints.isEmpty() && !e->synthetic()) {
@ -2798,7 +2801,9 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To
e->modifiers,
Qt::LeftButton,
QEvent::MouseButtonRelease,
Qt::MouseEventSynthesizedByQt);
Qt::MouseEventNotSynthesized,
false,
device);
fake.flags |= QWindowSystemInterfacePrivate::WindowSystemEvent::Synthetic;
processMouseEvent(&fake);
}
@ -2816,25 +2821,22 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To
self->lastTouchType = e->touchType;
QWindow *window = e->window.data();
typedef QPair<Qt::TouchPointStates, QList<QTouchEvent::TouchPoint> > StatesAndTouchPoints;
// TODO get rid of this QPair; we don't need to accumulate combined states here anymore
typedef QPair<QEventPoint::States, QList<QEventPoint> > StatesAndTouchPoints;
QHash<QWindow *, StatesAndTouchPoints> windowsNeedingEvents;
bool stationaryTouchPointChangedProperty = false;
for (int i = 0; i < e->points.count(); ++i) {
QTouchEvent::TouchPoint touchPoint = e->points.at(i);
// explicitly detach from the original touch point that we got, so even
// if the touchpoint structs are reused, we will make a copy that we'll
// deliver to the user (which might want to store the struct for later use).
touchPoint.d = touchPoint.d->detach();
QMutableEventPoint touchPoint = QMutableEventPoint::from(e->points[i]);
// update state
QPointer<QWindow> w;
QTouchEvent::TouchPoint previousTouchPoint;
ActiveTouchPointsKey touchInfoKey(static_cast<const QPointingDevice *>(e->device), touchPoint.id());
QEventPoint previousTouchPoint;
ActiveTouchPointsKey touchInfoKey(device, touchPoint.id());
ActiveTouchPointsValue &touchInfo = d->activeTouchPoints[touchInfoKey];
switch (touchPoint.state()) {
case Qt::TouchPointPressed:
if (e->device->type() == QInputDevice::DeviceType::TouchPad) {
case QEventPoint::State::Pressed:
if (e->device && e->device->type() == QInputDevice::DeviceType::TouchPad) {
// on touch-pads, send all touch points to the same widget
w = d->activeTouchPoints.isEmpty()
? QPointer<QWindow>()
@ -2851,30 +2853,23 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To
}
touchInfo.window = w;
touchPoint.d->startScreenPos = touchPoint.globalPosition();
touchPoint.d->lastScreenPos = touchPoint.globalPosition();
touchPoint.d->startNormalizedPos = touchPoint.normalizedPos();
touchPoint.d->lastNormalizedPos = touchPoint.normalizedPos();
if (touchPoint.pressure() < qreal(0.))
touchPoint.d->pressure = qreal(1.);
touchPoint.setGlobalPressPosition(touchPoint.globalPosition());
touchPoint.setGlobalLastPosition(touchPoint.globalPosition());
if (touchPoint.pressure() < 0)
touchPoint.setPressure(1);
touchInfo.touchPoint = touchPoint;
break;
case Qt::TouchPointReleased:
case QEventPoint::State::Released:
w = touchInfo.window;
if (!w)
continue;
previousTouchPoint = touchInfo.touchPoint;
touchPoint.d->startScreenPos = previousTouchPoint.globalPressPosition();
touchPoint.d->lastScreenPos = previousTouchPoint.globalPosition();
touchPoint.d->startPos = previousTouchPoint.pressPosition();
touchPoint.d->lastPos = previousTouchPoint.position();
touchPoint.d->startNormalizedPos = previousTouchPoint.startNormalizedPos();
touchPoint.d->lastNormalizedPos = previousTouchPoint.normalizedPos();
if (touchPoint.pressure() < qreal(0.))
touchPoint.d->pressure = qreal(0.);
touchPoint.setGlobalPressPosition(previousTouchPoint.globalPressPosition());
touchPoint.setGlobalLastPosition(previousTouchPoint.globalPosition());
touchPoint.setPressure(0);
break;
@ -2884,26 +2879,22 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To
continue;
previousTouchPoint = touchInfo.touchPoint;
touchPoint.d->startScreenPos = previousTouchPoint.globalPressPosition();
touchPoint.d->lastScreenPos = previousTouchPoint.globalPosition();
touchPoint.d->startPos = previousTouchPoint.pressPosition();
touchPoint.d->lastPos = previousTouchPoint.position();
touchPoint.d->startNormalizedPos = previousTouchPoint.startNormalizedPos();
touchPoint.d->lastNormalizedPos = previousTouchPoint.normalizedPos();
if (touchPoint.pressure() < qreal(0.))
touchPoint.d->pressure = qreal(1.);
touchPoint.setGlobalPressPosition(previousTouchPoint.globalPressPosition());
touchPoint.setGlobalLastPosition(previousTouchPoint.globalPosition());
if (touchPoint.pressure() < 0)
touchPoint.setPressure(1);
// Stationary points might not be delivered down to the receiving item
// and get their position transformed, keep the old values instead.
if (touchPoint.state() == Qt::TouchPointStationary) {
if (touchPoint.state() == QEventPoint::State::Stationary) {
if (touchInfo.touchPoint.velocity() != touchPoint.velocity()) {
touchInfo.touchPoint.setVelocity(touchPoint.velocity());
touchPoint.d->stationaryWithModifiedProperty = true;
touchPoint.setStationaryWithModifiedProperty();
stationaryTouchPointChangedProperty = true;
}
if (!qFuzzyCompare(touchInfo.touchPoint.pressure(), touchPoint.pressure())) {
touchInfo.touchPoint.setPressure(touchPoint.pressure());
touchPoint.d->stationaryWithModifiedProperty = true;
touchPoint.setStationaryWithModifiedProperty();
stationaryTouchPointChangedProperty = true;
}
} else {
@ -2914,13 +2905,9 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To
Q_ASSERT(w.data() != nullptr);
// make the *scene* functions return the same as the *screen* functions
// Note: touchPoint is a reference to the one from activeTouchPoints,
// so we can modify it as long as we're careful NOT to call setters and
// otherwise NOT to cause the d-pointer to be detached.
touchPoint.d->scenePos = touchPoint.globalPosition();
touchPoint.d->startScenePos = touchPoint.globalPressPosition();
touchPoint.d->lastScenePos = touchPoint.lastScreenPos();
// make the *scene* position the same as the *global* position
// Note: touchPoint is a reference to the one from activeTouchPoints, so we can modify it.
touchPoint.setScenePosition(touchPoint.globalPosition());
StatesAndTouchPoints &maskAndPoints = windowsNeedingEvents[w.data()];
maskAndPoints.first |= touchPoint.state();
@ -2937,13 +2924,13 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To
QEvent::Type eventType;
switch (it.value().first) {
case Qt::TouchPointPressed:
case QEventPoint::State::Pressed:
eventType = QEvent::TouchBegin;
break;
case Qt::TouchPointReleased:
case QEventPoint::State::Released:
eventType = QEvent::TouchEnd;
break;
case Qt::TouchPointStationary:
case QEventPoint::State::Stationary:
// don't send the event if nothing changed
if (!stationaryTouchPointChangedProperty)
continue;
@ -2961,39 +2948,26 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To
// but don't leave dangling state: e.g.
// QQuickWindowPrivate::itemForTouchPointId needs to be cleared.
QTouchEvent touchEvent(QEvent::TouchCancel,
static_cast<const QPointingDevice *>(e->device),
device,
e->modifiers);
touchEvent.setTimestamp(e->timestamp);
touchEvent.setWindow(w);
QGuiApplication::sendSpontaneousEvent(w, &touchEvent);
}
continue;
}
QTouchEvent touchEvent(eventType,
static_cast<const QPointingDevice *>(e->device),
e->modifiers,
it.value().first, // state flags
it.value().second); // list of touchpoints
const auto &touchpoints = it.value().second;
QMutableTouchEvent touchEvent(eventType, device, e->modifiers, touchpoints);
touchEvent.setTimestamp(e->timestamp);
touchEvent.setWindow(w);
const int pointCount = touchEvent.touchPoints().count();
for (int i = 0; i < pointCount; ++i) {
QTouchEvent::TouchPoint &touchPoint = touchEvent._touchPoints[i];
for (QEventPoint &pt : touchEvent.touchPoints()) {
auto &touchPoint = QMutableEventPoint::from(pt);
// preserve the sub-pixel resolution
const QPointF screenPos = touchPoint.globalPosition();
const QPointF delta = screenPos - screenPos.toPoint();
touchPoint.d->pos = w->mapFromGlobal(screenPos.toPoint()) + delta;
if (touchPoint.state() == Qt::TouchPointPressed) {
// touchPoint is actually a reference to one that is stored in activeTouchPoints,
// and we are now going to store the startPos and lastPos there, for the benefit
// of future moves and releases. It's important that the d-pointer is NOT detached.
touchPoint.d->startPos = w->mapFromGlobal(touchPoint.globalPressPosition().toPoint()) + delta;
touchPoint.d->lastPos = w->mapFromGlobal(touchPoint.lastScreenPos().toPoint()) + delta;
}
touchPoint.setPosition(w->mapFromGlobal(screenPos.toPoint()) + delta);
}
QGuiApplication::sendSpontaneousEvent(w, &touchEvent);
@ -3004,9 +2978,8 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To
if (eventType == QEvent::TouchEnd)
self->synthesizedMousePoints.clear();
const QList<QTouchEvent::TouchPoint> &touchPoints = touchEvent.touchPoints();
if (eventType == QEvent::TouchBegin)
m_fakeMouseSourcePointId = touchPoints.first().id();
m_fakeMouseSourcePointId = touchEvent.point(0).id();
const QEvent::Type mouseType = [&]() {
switch (eventType) {
@ -3020,8 +2993,8 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To
Qt::MouseButton button = mouseType == QEvent::MouseMove ? Qt::NoButton : Qt::LeftButton;
Qt::MouseButtons buttons = mouseType == QEvent::MouseButtonRelease ? Qt::NoButton : Qt::LeftButton;
for (int i = 0; i < touchPoints.count(); ++i) {
const QTouchEvent::TouchPoint &touchPoint = touchPoints.at(i);
const auto &points = touchEvent.touchPoints();
for (const QEventPoint &touchPoint : points) {
if (touchPoint.id() == m_fakeMouseSourcePointId) {
if (eventType != QEvent::TouchEnd)
self->synthesizedMousePoints.insert(w, SynthesizedMouseData(
@ -3035,7 +3008,9 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To
e->modifiers,
button,
mouseType,
Qt::MouseEventSynthesizedByQt);
Qt::MouseEventSynthesizedByQt,
false,
device);
fake.flags |= QWindowSystemInterfacePrivate::WindowSystemEvent::Synthetic;
processMouseEvent(&fake);
break;
@ -3049,10 +3024,9 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To
// delivered. When the receiver is a widget, QApplication will access
// activeTouchPoints during delivery and therefore nothing can be removed
// before sending the event.
for (int i = 0; i < e->points.count(); ++i) {
QTouchEvent::TouchPoint touchPoint = e->points.at(i);
if (touchPoint.state() == Qt::TouchPointReleased)
d->activeTouchPoints.remove(ActiveTouchPointsKey(static_cast<const QPointingDevice *>(e->device), touchPoint.id()));
for (const QEventPoint &touchPoint : e->points) {
if (touchPoint.state() == QEventPoint::State::Released)
d->activeTouchPoints.remove(ActiveTouchPointsKey(device, touchPoint.id()));
}
}
@ -4247,53 +4221,6 @@ enum MouseMasks {
MouseFlagsShift = 16
};
int QGuiApplicationPrivate::mouseEventCaps(QMouseEvent *event)
{
return event->caps & MouseCapsMask;
}
QVector2D QGuiApplicationPrivate::mouseEventVelocity(QMouseEvent *event)
{
return event->velocity;
}
void QGuiApplicationPrivate::setMouseEventCapsAndVelocity(QMouseEvent *event, int caps, const QVector2D &velocity)
{
Q_ASSERT(caps <= MouseCapsMask);
event->caps &= ~MouseCapsMask;
event->caps |= caps & MouseCapsMask;
event->velocity = velocity;
}
Qt::MouseEventSource QGuiApplicationPrivate::mouseEventSource(const QMouseEvent *event)
{
return Qt::MouseEventSource((event->caps & MouseSourceMaskDst) >> MouseSourceShift);
}
void QGuiApplicationPrivate::setMouseEventSource(QMouseEvent *event, Qt::MouseEventSource source)
{
// Mouse event synthesization status is encoded in the caps field because
// QPointingDevice::Capability uses only 6 bits from it.
int value = source;
Q_ASSERT(value <= MouseSourceMaskSrc);
event->caps &= ~MouseSourceMaskDst;
event->caps |= (value & MouseSourceMaskSrc) << MouseSourceShift;
}
Qt::MouseEventFlags QGuiApplicationPrivate::mouseEventFlags(const QMouseEvent *event)
{
return Qt::MouseEventFlags((event->caps & MouseFlagsCapsMask) >> MouseFlagsShift);
}
void QGuiApplicationPrivate::setMouseEventFlags(QMouseEvent *event, Qt::MouseEventFlags flags)
{
// use the 0x00FF0000 byte from caps (containing up to 7 mouse event flags)
unsigned int value = flags;
Q_ASSERT(value <= Qt::MouseEventFlagMask);
event->caps &= ~MouseFlagsCapsMask;
event->caps |= (value & Qt::MouseEventFlagMask) << MouseFlagsShift;
}
QInputDeviceManager *QGuiApplicationPrivate::inputDeviceManager()
{
Q_ASSERT(QGuiApplication::instance());

View File

@ -293,7 +293,7 @@ public:
struct ActiveTouchPointsValue {
QPointer<QWindow> window;
QPointer<QObject> target;
QTouchEvent::TouchPoint touchPoint;
QMutableEventPoint touchPoint;
};
QHash<ActiveTouchPointsKey, ActiveTouchPointsValue> activeTouchPoints;
QEvent::Type lastTouchType;
@ -306,16 +306,6 @@ public:
};
QHash<QWindow *, SynthesizedMouseData> synthesizedMousePoints;
static int mouseEventCaps(QMouseEvent *event);
static QVector2D mouseEventVelocity(QMouseEvent *event);
static void setMouseEventCapsAndVelocity(QMouseEvent *event, int caps, const QVector2D &velocity);
static Qt::MouseEventSource mouseEventSource(const QMouseEvent *event);
static void setMouseEventSource(QMouseEvent *event, Qt::MouseEventSource source);
static Qt::MouseEventFlags mouseEventFlags(const QMouseEvent *event);
static void setMouseEventFlags(QMouseEvent *event, Qt::MouseEventFlags flags);
static QInputDeviceManager *inputDeviceManager();
const QColorTrcLut *colorProfileForA8Text();

View File

@ -81,7 +81,6 @@ public:
Area = 0x0002,
Pressure = 0x0004,
Velocity = 0x0008,
RawPositions = 0x0010,
NormalizedPosition = 0x0020,
MouseEmulation = 0x0040,
Scroll = 0x0100,

View File

@ -79,7 +79,7 @@ Q_DECLARE_LOGGING_CATEGORY(lcQpaInputDevices)
In this type of device, the touch surface and display are integrated.
This means the surface and display typically have the same size, such
that there is a direct relationship between the touch points' physical
positions and the coordinate reported by QTouchEvent::TouchPoint. As a
positions and the coordinate reported by QEventPoint. As a
result, Qt allows the user to interact directly with multiple QWidgets,
QGraphicsItems, or Qt Quick Items at the same time.
@ -159,12 +159,6 @@ Q_DECLARE_LOGGING_CATEGORY(lcQpaInputDevices)
Indicates that velocity information is available, meaning that
QPointerEvent::EventPoint::velocity() returns a valid vector.
\value RawPositions
Indicates that the list returned by
QPointerEvent::EventPoint::rawScreenPositions() may contain one or more
positions for each touch point. This is relevant when the touch input
gets filtered or corrected on the driver level.
\value NormalizedPosition
Indicates that the normalized position is available, meaning that
QPointerEvent::EventPoint::normalizedPos() returns a valid value.

View File

@ -184,7 +184,7 @@ bool QBasicDrag::eventFilter(QObject *o, QEvent *e)
QMouseEvent *newRelease = new QMouseEvent(release->type(),
releaseWindowPos, releaseWindowPos, release->globalPosition(),
release->button(), release->buttons(),
release->modifiers(), release->source());
release->modifiers(), release->source(), release->pointingDevice());
QCoreApplication::postEvent(o, newRelease);
return true; // defer mouse release events until drag event loop has returned
}

View File

@ -623,37 +623,30 @@ void QWindowSystemInterface::registerInputDevice(const QInputDevice *device)
QInputDevicePrivate::registerDevice(device);
}
QList<QTouchEvent::TouchPoint>
QList<QEventPoint>
QWindowSystemInterfacePrivate::fromNativeTouchPoints(const QList<QWindowSystemInterface::TouchPoint> &points,
const QWindow *window, QEvent::Type *type)
{
QList<QTouchEvent::TouchPoint> touchPoints;
Qt::TouchPointStates states;
QTouchEvent::TouchPoint p;
QList<QEventPoint> touchPoints;
QEventPoint::States states;
touchPoints.reserve(points.count());
QList<QWindowSystemInterface::TouchPoint>::const_iterator point = points.constBegin();
QList<QWindowSystemInterface::TouchPoint>::const_iterator end = points.constEnd();
while (point != end) {
p.setId(point->id);
QPointF globalPos = QHighDpi::fromNativePixels(point->area.center(), window);
QMutableEventPoint p(point->id, point->state, globalPos, globalPos);
states |= point->state;
if (point->uniqueId >= 0)
p.setUniqueId(point->uniqueId);
p.setUniqueId(QPointingDeviceUniqueId::fromNumericId(point->uniqueId));
p.setPressure(point->pressure);
p.setRotation(point->rotation);
states |= point->state;
p.setState(point->state);
p.setScreenPos(QHighDpi::fromNativePixels(point->area.center(), window));
p.setEllipseDiameters(QHighDpi::fromNativePixels(point->area.size(), window));
p.setVelocity(QHighDpi::fromNativePixels(point->velocity, window));
// The local pos is not set: it will be calculated
// when the event gets processed by QGuiApplication.
p.setNormalizedPos(QHighDpi::fromNativePixels(point->normalPosition, window));
p.setVelocity(QHighDpi::fromNativePixels(point->velocity, window));
p.setFlags(point->flags);
p.setRawScreenPositions(QHighDpi::fromNativePixels(point->rawPositions, window));
touchPoints.append(p);
++point;
}
@ -661,37 +654,28 @@ QList<QTouchEvent::TouchPoint>
// Determine the event type based on the combined point states.
if (type) {
*type = QEvent::TouchUpdate;
if (states == Qt::TouchPointPressed)
if (states == QEventPoint::State::Pressed)
*type = QEvent::TouchBegin;
else if (states == Qt::TouchPointReleased)
else if (states == QEventPoint::State::Released)
*type = QEvent::TouchEnd;
}
return touchPoints;
}
QList<QWindowSystemInterface::TouchPoint>
QWindowSystemInterfacePrivate::toNativeTouchPoints(const QList<QTouchEvent::TouchPoint>& pointList,
const QWindow *window)
QWindowSystemInterface::TouchPoint
QWindowSystemInterfacePrivate::toNativeTouchPoint(const QEventPoint &pt, const QWindow *window)
{
QList<QWindowSystemInterface::TouchPoint> newList;
newList.reserve(pointList.size());
for (const QTouchEvent::TouchPoint &pt : pointList) {
QWindowSystemInterface::TouchPoint p;
p.id = pt.id();
p.flags = pt.flags();
p.normalPosition = QHighDpi::toNativeLocalPosition(pt.normalizedPos(), window);
QRectF area(QPointF(), pt.ellipseDiameters());
area.moveCenter(pt.globalPosition());
// TODO store ellipseDiameters in QWindowSystemInterface::TouchPoint or just use QTouchEvent::TouchPoint
p.area = QHighDpi::toNativePixels(area, window);
p.pressure = pt.pressure();
p.state = pt.state();
p.velocity = QHighDpi::toNativePixels(pt.velocity(), window);
p.rawPositions = QHighDpi::toNativePixels(pt.rawScreenPositions(), window);
newList.append(p);
}
return newList;
QWindowSystemInterface::TouchPoint p;
p.id = pt.id();
QRectF area(QPointF(), pt.ellipseDiameters());
area.moveCenter(pt.globalPosition());
// TODO store ellipseDiameters in QWindowSystemInterface::TouchPoint or just use QEventPoint
p.area = QHighDpi::toNativePixels(area, window);
p.pressure = pt.pressure();
p.state = pt.state();
p.velocity = QHighDpi::toNativePixels(pt.velocity(), window);
return p;
}
QT_DEFINE_QPA_EVENT_HANDLER(bool, handleTouchEvent, QWindow *window, const QPointingDevice *device,
@ -711,7 +695,7 @@ QT_DEFINE_QPA_EVENT_HANDLER(bool, handleTouchEvent, QWindow *window, ulong times
return false;
QEvent::Type type;
QList<QTouchEvent::TouchPoint> touchPoints =
QList<QEventPoint> touchPoints =
QWindowSystemInterfacePrivate::fromNativeTouchPoints(points, window, &type);
QWindowSystemInterfacePrivate::TouchEvent *e =
new QWindowSystemInterfacePrivate::TouchEvent(window, timestamp, type, device, touchPoints, mods);
@ -730,7 +714,7 @@ QT_DEFINE_QPA_EVENT_HANDLER(bool, handleTouchCancelEvent, QWindow *window, ulong
{
QWindowSystemInterfacePrivate::TouchEvent *e =
new QWindowSystemInterfacePrivate::TouchEvent(window, timestamp, QEvent::TouchCancel, device,
QList<QTouchEvent::TouchPoint>(), mods);
QList<QEventPoint>(), mods);
return QWindowSystemInterfacePrivate::handleWindowSystemEvent<Delivery>(e);
}
@ -1248,7 +1232,7 @@ namespace QTest
}
Q_GUI_EXPORT void qt_handleTouchEvent(QWindow *window, const QPointingDevice *device,
const QList<QTouchEvent::TouchPoint> &points,
const QList<QEventPoint> &points,
Qt::KeyboardModifiers mods = Qt::NoModifier)
{
QWindowSystemInterface::handleTouchEvent<QWindowSystemInterface::SynchronousDelivery>(window, device,

View File

@ -156,7 +156,7 @@ public:
bool inverted = false);
struct TouchPoint {
TouchPoint() : id(0), uniqueId(-1), pressure(0), rotation(0), state(Qt::TouchPointStationary) { }
TouchPoint() : id(0), uniqueId(-1), pressure(0), rotation(0), state(QEventPoint::State::Stationary) { }
int id; // for application use
qint64 uniqueId; // for TUIO: object/token ID; otherwise empty
// TODO for TUIO 2.0: add registerPointerUniqueID(QPointingDeviceUniqueId)
@ -166,9 +166,8 @@ public:
qreal pressure; // 0 to 1
qreal rotation; // rotation applied to the elliptical contact patch
// 0 means pointing straight up; 0 if unknown (like QTabletEvent::rotation)
Qt::TouchPointState state; //Qt::TouchPoint{Pressed|Moved|Stationary|Released}
QEventPoint::State state; // Pressed|Updated|Stationary|Released
QVector2D velocity; // in screen coordinate system, pixels / seconds
QTouchEvent::TouchPoint::InfoFlags flags;
QList<QPointF> rawPositions; // in screen coordinates
};

View File

@ -50,6 +50,7 @@
// We mean it.
//
#include <QtGui/private/qevent_p.h>
#include <QtGui/private/qtguiglobal_p.h>
#include "qwindowsysteminterface.h"
@ -234,14 +235,20 @@ public:
const QInputDevice *device;
};
class MouseEvent : public InputEvent {
class PointerEvent : public InputEvent {
public:
PointerEvent(QWindow * w, ulong time, EventType t, Qt::KeyboardModifiers mods, const QPointingDevice *device)
: InputEvent(w, time, t, mods, device) {}
};
class MouseEvent : public PointerEvent {
public:
MouseEvent(QWindow *w, ulong time, const QPointF &local, const QPointF &global,
Qt::MouseButtons state, Qt::KeyboardModifiers mods,
Qt::MouseButton b, QEvent::Type type,
Qt::MouseEventSource src = Qt::MouseEventNotSynthesized, bool frame = false,
const QPointingDevice *device = QPointingDevice::primaryPointingDevice())
: InputEvent(w, time, Mouse, mods, device), localPos(local), globalPos(global),
: PointerEvent(w, time, Mouse, mods, device), localPos(local), globalPos(global),
buttons(state), source(src), nonClientArea(frame), button(b), buttonType(type) { }
// ### In Qt6 this method can be removed as there won't be need for compatibility code path
@ -260,12 +267,12 @@ public:
QEvent::Type buttonType;
};
class WheelEvent : public InputEvent {
class WheelEvent : public PointerEvent {
public:
WheelEvent(QWindow *w, ulong time, const QPointF &local, const QPointF &global, QPoint pixelD, QPoint angleD, int qt4D, Qt::Orientation qt4O,
Qt::KeyboardModifiers mods, Qt::ScrollPhase phase = Qt::NoScrollPhase, Qt::MouseEventSource src = Qt::MouseEventNotSynthesized,
bool inverted = false, const QPointingDevice *device = QPointingDevice::primaryPointingDevice())
: InputEvent(w, time, Wheel, mods, device), pixelDelta(pixelD), angleDelta(angleD), qt4Delta(qt4D),
: PointerEvent(w, time, Wheel, mods, device), pixelDelta(pixelD), angleDelta(angleD), qt4Delta(qt4D),
qt4Orientation(qt4O), localPos(local), globalPos(global), phase(phase), source(src), inverted(inverted) { }
QPoint pixelDelta;
QPoint angleDelta;
@ -291,6 +298,7 @@ public:
: InputEvent(w, time, Key, mods, device), key(k), unicode(text), repeat(autorep),
repeatCount(count), keyType(t),
nativeScanCode(nativeSC), nativeVirtualKey(nativeVK), nativeModifiers(nativeMods) { }
const QInputDevice *source;
int key;
QString unicode;
bool repeat;
@ -301,13 +309,12 @@ public:
quint32 nativeModifiers;
};
class TouchEvent : public InputEvent {
class TouchEvent : public PointerEvent {
public:
TouchEvent(QWindow *w, ulong time, QEvent::Type t, const QPointingDevice *device,
const QList<QTouchEvent::TouchPoint> &p, Qt::KeyboardModifiers mods)
: InputEvent(w, time, Touch, mods, device), points(p), touchType(t) {
}
QList<QTouchEvent::TouchPoint> points;
const QList<QEventPoint> &p, Qt::KeyboardModifiers mods)
: PointerEvent(w, time, Touch, mods, device), points(p), touchType(t) { }
QList<QEventPoint> points;
QEvent::Type touchType;
};
@ -371,8 +378,9 @@ public:
QUrl url;
};
class Q_GUI_EXPORT TabletEvent : public InputEvent {
class Q_GUI_EXPORT TabletEvent : public PointerEvent {
public:
// TODO take QPointingDevice* instead of types and IDs
static void handleTabletEvent(QWindow *w, const QPointF &local, const QPointF &global,
int device, int pointerType, Qt::MouseButtons buttons, qreal pressure, int xTilt, int yTilt,
qreal tangentialPressure, qreal rotation, int z, qint64 uid,
@ -382,7 +390,7 @@ public:
TabletEvent(QWindow *w, ulong time, const QPointF &local, const QPointF &global,
const QPointingDevice *device, Qt::MouseButtons b, qreal pressure, int xTilt, int yTilt, qreal tpressure,
qreal rotation, int z, Qt::KeyboardModifiers mods)
: InputEvent(w, time, Tablet, mods, device),
: PointerEvent(w, time, Tablet, mods, device),
buttons(b), local(local), global(global),
pressure(pressure), xTilt(xTilt), yTilt(yTilt), tangentialPressure(tpressure),
rotation(rotation), z(z) { }
@ -398,16 +406,18 @@ public:
static bool platformSynthesizesMouse;
};
class TabletEnterProximityEvent : public InputEvent {
class TabletEnterProximityEvent : public PointerEvent {
public:
// TODO store more info: position and whatever else we can get on most platforms
TabletEnterProximityEvent(ulong time, const QPointingDevice *device)
: InputEvent(nullptr, time, TabletEnterProximity, Qt::NoModifier, device) { }
: PointerEvent(nullptr, time, TabletEnterProximity, Qt::NoModifier, device) { }
};
class TabletLeaveProximityEvent : public InputEvent {
class TabletLeaveProximityEvent : public PointerEvent {
public:
// TODO store more info: position and whatever else we can get on most platforms
TabletLeaveProximityEvent(ulong time, const QPointingDevice *device)
: InputEvent(nullptr, time, TabletLeaveProximity, Qt::NoModifier, device) { }
: PointerEvent(nullptr, time, TabletLeaveProximity, Qt::NoModifier, device) { }
};
class PlatformPanelEvent : public WindowSystemEvent {
@ -433,11 +443,11 @@ public:
#endif
#ifndef QT_NO_GESTURES
class GestureEvent : public InputEvent {
class GestureEvent : public PointerEvent {
public:
GestureEvent(QWindow *window, ulong time, Qt::NativeGestureType type, const QPointingDevice *dev, QPointF pos, QPointF globalPos)
: InputEvent(window, time, Gesture, Qt::NoModifier, dev), type(type), pos(pos), globalPos(globalPos),
realValue(0), sequenceId(0), intValue(0), device(dev) { }
: PointerEvent(window, time, Gesture, Qt::NoModifier, dev), type(type), pos(pos), globalPos(globalPos),
realValue(0), sequenceId(0), intValue(0) { }
Qt::NativeGestureType type;
QPointF pos;
QPointF globalPos;
@ -446,7 +456,6 @@ public:
// Windows
ulong sequenceId;
quint64 intValue;
const QPointingDevice *device;
};
#endif
@ -526,12 +535,22 @@ public:
static QMutex flushEventMutex;
static QAtomicInt eventAccepted;
static QList<QTouchEvent::TouchPoint>
static QList<QEventPoint>
fromNativeTouchPoints(const QList<QWindowSystemInterface::TouchPoint> &points,
const QWindow *window, QEvent::Type *type = nullptr);
template<class EventPointList>
static QList<QWindowSystemInterface::TouchPoint>
toNativeTouchPoints(const QList<QTouchEvent::TouchPoint>& pointList,
const QWindow *window);
toNativeTouchPoints(const EventPointList &pointList, const QWindow *window)
{
QList<QWindowSystemInterface::TouchPoint> newList;
newList.reserve(pointList.size());
for (const auto &point : pointList) {
newList.append(toNativeTouchPoint(point, window));
}
return newList;
}
static QWindowSystemInterface::TouchPoint
toNativeTouchPoint(const QEventPoint &point, const QWindow *window);
static void installWindowSystemEventHandler(QWindowSystemEventHandler *handler);
static void removeWindowSystemEventhandler(QWindowSystemEventHandler *handler);

View File

@ -126,8 +126,7 @@ public:
int y = 0;
int maj = -1;
int pressure = 0;
Qt::TouchPointState state = Qt::TouchPointPressed;
QTouchEvent::TouchPoint::InfoFlags flags;
QEventPoint::State state = QEventPoint::State::Pressed;
};
QHash<int, Contact> m_contacts; // The key is a tracking id for type A, slot number for type B.
QHash<int, Contact> m_lastContacts;
@ -138,7 +137,7 @@ public:
double m_lastTimeStamp;
int findClosestContact(const QHash<int, Contact> &contacts, int x, int y, int *dist);
void addTouchPoint(const Contact &contact, Qt::TouchPointStates *combinedStates);
void addTouchPoint(const Contact &contact, QEventPoint::States *combinedStates);
void reportPoints();
void loadMultiScreenMappings();
@ -474,11 +473,10 @@ void QEvdevTouchScreenHandler::unregisterPointingDevice()
m_device = nullptr;
}
void QEvdevTouchScreenData::addTouchPoint(const Contact &contact, Qt::TouchPointStates *combinedStates)
void QEvdevTouchScreenData::addTouchPoint(const Contact &contact, QEventPoint::States *combinedStates)
{
QWindowSystemInterface::TouchPoint tp;
tp.id = contact.trackingId;
tp.flags = contact.flags;
tp.state = contact.state;
*combinedStates |= tp.state;
@ -509,8 +507,8 @@ void QEvdevTouchScreenData::processInputEvent(input_event *data)
m_contacts[m_currentSlot].x = m_currentData.x;
if (m_typeB) {
m_contacts[m_currentSlot].x = m_currentData.x;
if (m_contacts[m_currentSlot].state == Qt::TouchPointStationary)
m_contacts[m_currentSlot].state = Qt::TouchPointMoved;
if (m_contacts[m_currentSlot].state == QEventPoint::State::Stationary)
m_contacts[m_currentSlot].state = QEventPoint::State::Updated;
}
} else if (data->code == ABS_MT_POSITION_Y || (m_singleTouch && data->code == ABS_Y)) {
m_currentData.y = qBound(hw_range_y_min, data->value, hw_range_y_max);
@ -518,23 +516,23 @@ void QEvdevTouchScreenData::processInputEvent(input_event *data)
m_contacts[m_currentSlot].y = m_currentData.y;
if (m_typeB) {
m_contacts[m_currentSlot].y = m_currentData.y;
if (m_contacts[m_currentSlot].state == Qt::TouchPointStationary)
m_contacts[m_currentSlot].state = Qt::TouchPointMoved;
if (m_contacts[m_currentSlot].state == QEventPoint::State::Stationary)
m_contacts[m_currentSlot].state = QEventPoint::State::Updated;
}
} else if (data->code == ABS_MT_TRACKING_ID) {
m_currentData.trackingId = data->value;
if (m_typeB) {
if (m_currentData.trackingId == -1) {
m_contacts[m_currentSlot].state = Qt::TouchPointReleased;
m_contacts[m_currentSlot].state = QEventPoint::State::Released;
} else {
m_contacts[m_currentSlot].state = Qt::TouchPointPressed;
m_contacts[m_currentSlot].state = QEventPoint::State::Pressed;
m_contacts[m_currentSlot].trackingId = m_currentData.trackingId;
}
}
} else if (data->code == ABS_MT_TOUCH_MAJOR) {
m_currentData.maj = data->value;
if (data->value == 0)
m_currentData.state = Qt::TouchPointReleased;
m_currentData.state = QEventPoint::State::Released;
if (m_typeB)
m_contacts[m_currentSlot].maj = m_currentData.maj;
} else if (data->code == ABS_PRESSURE || data->code == ABS_MT_PRESSURE) {
@ -550,7 +548,7 @@ void QEvdevTouchScreenData::processInputEvent(input_event *data)
} else if (data->type == EV_KEY && !m_typeB) {
if (data->code == BTN_TOUCH && data->value == 0)
m_contacts[m_currentSlot].state = Qt::TouchPointReleased;
m_contacts[m_currentSlot].state = QEventPoint::State::Released;
} else if (data->type == EV_SYN && data->code == SYN_MT_REPORT && m_lastEventType != EV_SYN) {
// If there is no tracking id, one will be generated later.
@ -578,7 +576,7 @@ void QEvdevTouchScreenData::processInputEvent(input_event *data)
m_lastTouchPoints = m_touchPoints;
m_touchPoints.clear();
Qt::TouchPointStates combinedStates;
QEventPoint::States combinedStates;
bool hasPressure = false;
for (auto it = m_contacts.begin(), end = m_contacts.end(); it != end; /*erasing*/) {
@ -590,19 +588,19 @@ void QEvdevTouchScreenData::processInputEvent(input_event *data)
int key = m_typeB ? it.key() : contact.trackingId;
if (!m_typeB && m_lastContacts.contains(key)) {
const Contact &prev(m_lastContacts.value(key));
if (contact.state == Qt::TouchPointReleased) {
if (contact.state == QEventPoint::State::Released) {
// Copy over the previous values for released points, just in case.
contact.x = prev.x;
contact.y = prev.y;
contact.maj = prev.maj;
} else {
contact.state = (prev.x == contact.x && prev.y == contact.y)
? Qt::TouchPointStationary : Qt::TouchPointMoved;
? QEventPoint::State::Stationary : QEventPoint::State::Updated;
}
}
// Avoid reporting a contact in released state more than once.
if (!m_typeB && contact.state == Qt::TouchPointReleased
if (!m_typeB && contact.state == QEventPoint::State::Released
&& !m_lastContacts.contains(key)) {
it = m_contacts.erase(it);
continue;
@ -621,12 +619,12 @@ void QEvdevTouchScreenData::processInputEvent(input_event *data)
int key = m_typeB ? it.key() : contact.trackingId;
if (m_typeB) {
if (contact.trackingId != m_contacts[key].trackingId && contact.state) {
contact.state = Qt::TouchPointReleased;
contact.state = QEventPoint::State::Released;
addTouchPoint(contact, &combinedStates);
}
} else {
if (!m_contacts.contains(key)) {
contact.state = Qt::TouchPointReleased;
contact.state = QEventPoint::State::Released;
addTouchPoint(contact, &combinedStates);
}
}
@ -639,15 +637,15 @@ void QEvdevTouchScreenData::processInputEvent(input_event *data)
if (!contact.state)
continue;
if (contact.state == Qt::TouchPointReleased) {
if (contact.state == QEventPoint::State::Released) {
if (m_typeB) {
contact.state = static_cast<Qt::TouchPointState>(0);
contact.state = QEventPoint::State::Stationary;
} else {
it = m_contacts.erase(it);
continue;
}
} else {
contact.state = Qt::TouchPointStationary;
contact.state = QEventPoint::State::Stationary;
}
++it;
}
@ -657,7 +655,7 @@ void QEvdevTouchScreenData::processInputEvent(input_event *data)
m_contacts.clear();
if (!m_touchPoints.isEmpty() && (hasPressure || combinedStates != Qt::TouchPointStationary))
if (!m_touchPoints.isEmpty() && (hasPressure || combinedStates != QEventPoint::State::Stationary))
reportPoints();
}
@ -780,7 +778,7 @@ void QEvdevTouchScreenData::reportPoints()
// Calculate normalized pressure.
if (!hw_pressure_min && !hw_pressure_max)
tp.pressure = tp.state == Qt::TouchPointReleased ? 0 : 1;
tp.pressure = tp.state == QEventPoint::State::Released ? 0 : 1;
else
tp.pressure = (tp.pressure - hw_pressure_min) / qreal(hw_pressure_max - hw_pressure_min);
@ -927,8 +925,8 @@ void QEvdevTouchScreenHandlerThread::filterAndSendTouchPoints()
f.y.initialize(pos.y(), velocity.y());
// Make sure the first instance of a touch point we send has the
// 'pressed' state.
if (tp.state != Qt::TouchPointPressed)
tp.state = Qt::TouchPointPressed;
if (tp.state != QEventPoint::State::Pressed)
tp.state = QEventPoint::State::Pressed;
}
tp.velocity = QVector2D(f.x.velocity() * winRect.width(), f.y.velocity() * winRect.height());
@ -950,14 +948,14 @@ void QEvdevTouchScreenHandlerThread::filterAndSendTouchPoints()
f.touchPoint = tp;
// Don't store the point for future reference if it is a release.
if (tp.state != Qt::TouchPointReleased)
if (tp.state != QEventPoint::State::Released)
filteredPoints[tp.id] = f;
}
for (QHash<int, FilteredTouchPoint>::const_iterator it = m_filteredPoints.constBegin(), end = m_filteredPoints.constEnd(); it != end; ++it) {
const FilteredTouchPoint &f = it.value();
QWindowSystemInterface::TouchPoint tp = f.touchPoint;
tp.state = Qt::TouchPointReleased;
tp.state = QEventPoint::State::Released;
tp.velocity = QVector2D();
points.append(tp);
}

View File

@ -133,7 +133,7 @@ void QLibInputTouch::processTouchDown(libinput_event_touch *e)
} else {
QWindowSystemInterface::TouchPoint newTp;
newTp.id = qMax(0, slot);
newTp.state = Qt::TouchPointPressed;
newTp.state = QEventPoint::State::Pressed;
newTp.area = QRect(0, 0, 8, 8);
newTp.area.moveCenter(getPos(e));
state->m_points.append(newTp);
@ -146,15 +146,15 @@ void QLibInputTouch::processTouchMotion(libinput_event_touch *e)
DeviceState *state = deviceState(e);
QWindowSystemInterface::TouchPoint *tp = state->point(slot);
if (tp) {
Qt::TouchPointState tmpState = Qt::TouchPointMoved;
QEventPoint::State tmpState = QEventPoint::State::Updated;
const QPointF p = getPos(e);
if (tp->area.center() == p)
tmpState = Qt::TouchPointStationary;
tmpState = QEventPoint::State::Stationary;
else
tp->area.moveCenter(p);
// 'down' may be followed by 'motion' within the same "frame".
// Handle this by compressing and keeping the Pressed state until the 'frame'.
if (tp->state != Qt::TouchPointPressed && tp->state != Qt::TouchPointReleased)
if (tp->state != QEventPoint::State::Pressed && tp->state != QEventPoint::State::Released)
tp->state = tmpState;
} else {
qWarning("Inconsistent touch state (got 'motion' without 'down')");
@ -167,12 +167,12 @@ void QLibInputTouch::processTouchUp(libinput_event_touch *e)
DeviceState *state = deviceState(e);
QWindowSystemInterface::TouchPoint *tp = state->point(slot);
if (tp) {
tp->state = Qt::TouchPointReleased;
tp->state = QEventPoint::State::Released;
// There may not be a Frame event after the last Up. Work this around.
Qt::TouchPointStates s;
QEventPoint::States s;
for (int i = 0; i < state->m_points.count(); ++i)
s |= state->m_points.at(i).state;
if (s == Qt::TouchPointReleased)
if (s == QEventPoint::State::Released)
processTouchFrame(e);
} else {
qWarning("Inconsistent touch state (got 'up' without 'down')");
@ -203,10 +203,10 @@ void QLibInputTouch::processTouchFrame(libinput_event_touch *e)
for (int i = 0; i < state->m_points.count(); ++i) {
QWindowSystemInterface::TouchPoint &tp(state->m_points[i]);
if (tp.state == Qt::TouchPointReleased)
if (tp.state == QEventPoint::State::Released)
state->m_points.removeAt(i--);
else if (tp.state == Qt::TouchPointPressed)
tp.state = Qt::TouchPointStationary;
else if (tp.state == QEventPoint::State::Pressed)
tp.state = QEventPoint::State::Stationary;
}
}

View File

@ -55,7 +55,7 @@ public:
, m_vx(0)
, m_vy(0)
, m_acceleration(0)
, m_state(Qt::TouchPointPressed)
, m_state(QEventPoint::State::Pressed)
{
}
@ -63,9 +63,9 @@ public:
void setX(float x)
{
if (state() == Qt::TouchPointStationary &&
if (state() == QEventPoint::State::Stationary &&
!qFuzzyCompare(m_x + 2.0, x + 2.0)) { // +2 because 1 is a valid value, and qFuzzyCompare can't cope with 0.0
setState(Qt::TouchPointMoved);
setState(QEventPoint::State::Updated);
}
m_x = x;
}
@ -73,9 +73,9 @@ public:
void setY(float y)
{
if (state() == Qt::TouchPointStationary &&
if (state() == QEventPoint::State::Stationary &&
!qFuzzyCompare(m_y + 2.0, y + 2.0)) { // +2 because 1 is a valid value, and qFuzzyCompare can't cope with 0.0
setState(Qt::TouchPointMoved);
setState(QEventPoint::State::Updated);
}
m_y = y;
}
@ -90,8 +90,8 @@ public:
void setAcceleration(float acceleration) { m_acceleration = acceleration; }
float acceleration() const { return m_acceleration; }
void setState(const Qt::TouchPointState &state) { m_state = state; }
Qt::TouchPointState state() const { return m_state; }
void setState(const QEventPoint::State &state) { m_state = state; }
QEventPoint::State state() const { return m_state; }
private:
int m_id;
@ -100,7 +100,7 @@ private:
float m_vx;
float m_vy;
float m_acceleration;
Qt::TouchPointState m_state;
QEventPoint::State m_state;
};
Q_DECLARE_TYPEINFO(QTuioCursor, Q_MOVABLE_TYPE); // Q_PRIMITIVE_TYPE: not possible, m_state is = 1, not 0.

View File

@ -260,12 +260,12 @@ void QTuioHandler::process2DCurAlive(const QOscMessage &message)
if (!oldActiveCursors.contains(cursorId)) {
// newly active
QTuioCursor cursor(cursorId);
cursor.setState(Qt::TouchPointPressed);
cursor.setState(QEventPoint::State::Pressed);
newActiveCursors.insert(cursorId, cursor);
} else {
// we already know about it, remove it so it isn't marked as released
QTuioCursor cursor = oldActiveCursors.value(cursorId);
cursor.setState(Qt::TouchPointStationary); // position change in SET will update if needed
cursor.setState(QEventPoint::State::Stationary); // position change in SET will update if needed
newActiveCursors.insert(cursorId, cursor);
oldActiveCursors.remove(cursorId);
}
@ -378,7 +378,7 @@ void QTuioHandler::process2DCurFseq(const QOscMessage &message)
for (const QTuioCursor &tc : qAsConst(m_deadCursors)) {
QWindowSystemInterface::TouchPoint tp = cursorToTouchPoint(tc, win);
tp.state = Qt::TouchPointReleased;
tp.state = QEventPoint::State::Released;
tpl.append(tp);
}
QWindowSystemInterface::handleTouchEvent(win, m_device, tpl);
@ -425,12 +425,12 @@ void QTuioHandler::process2DObjAlive(const QOscMessage &message)
if (!oldActiveTokens.contains(sessionId)) {
// newly active
QTuioToken token(sessionId);
token.setState(Qt::TouchPointPressed);
token.setState(QEventPoint::State::Pressed);
newActiveTokens.insert(sessionId, token);
} else {
// we already know about it, remove it so it isn't marked as released
QTuioToken token = oldActiveTokens.value(sessionId);
token.setState(Qt::TouchPointStationary); // position change in SET will update if needed
token.setState(QEventPoint::State::Stationary); // position change in SET will update if needed
newActiveTokens.insert(sessionId, token);
oldActiveTokens.remove(sessionId);
}
@ -511,7 +511,6 @@ QWindowSystemInterface::TouchPoint QTuioHandler::tokenToTouchPoint(const QTuioTo
QWindowSystemInterface::TouchPoint tp;
tp.id = tc.id();
tp.uniqueId = tc.classId(); // TODO TUIO 2.0: populate a QVariant, and register the mapping from int to arbitrary UID data
tp.flags = QTouchEvent::TouchPoint::Token;
tp.pressure = 1.0f;
tp.normalPosition = QPointF(tc.x(), tc.y());
@ -552,7 +551,7 @@ void QTuioHandler::process2DObjFseq(const QOscMessage &message)
for (const QTuioToken & t : qAsConst(m_deadTokens)) {
QWindowSystemInterface::TouchPoint tp = tokenToTouchPoint(t, win);
tp.state = Qt::TouchPointReleased;
tp.state = QEventPoint::State::Released;
tp.velocity = QVector2D();
tpl.append(tp);
}

View File

@ -66,7 +66,7 @@ public:
, m_angle(0)
, m_angularVelocity(0)
, m_angularAcceleration(0)
, m_state(Qt::TouchPointPressed)
, m_state(QEventPoint::State::Pressed)
{
}
@ -77,9 +77,9 @@ public:
void setX(float x)
{
if (state() == Qt::TouchPointStationary &&
if (state() == QEventPoint::State::Stationary &&
!qFuzzyCompare(m_x + 2.0, x + 2.0)) { // +2 because 1 is a valid value, and qFuzzyCompare can't cope with 0.0
setState(Qt::TouchPointMoved);
setState(QEventPoint::State::Updated);
}
m_x = x;
}
@ -87,9 +87,9 @@ public:
void setY(float y)
{
if (state() == Qt::TouchPointStationary &&
if (state() == QEventPoint::State::Stationary &&
!qFuzzyCompare(m_y + 2.0, y + 2.0)) { // +2 because 1 is a valid value, and qFuzzyCompare can't cope with 0.0
setState(Qt::TouchPointMoved);
setState(QEventPoint::State::Updated);
}
m_y = y;
}
@ -109,9 +109,9 @@ public:
{
if (angle > M_PI)
angle = angle - M_PI * 2.0; // zero is pointing upwards, and is the default; but we want to have negative angles when rotating left
if (state() == Qt::TouchPointStationary &&
if (state() == QEventPoint::State::Stationary &&
!qFuzzyCompare(m_angle + 2.0, angle + 2.0)) { // +2 because 1 is a valid value, and qFuzzyCompare can't cope with 0.0
setState(Qt::TouchPointMoved);
setState(QEventPoint::State::Updated);
}
m_angle = angle;
}
@ -122,8 +122,8 @@ public:
float angularAcceleration() const { return m_angularAcceleration; }
void setAngularAcceleration(float angularAcceleration) { m_angularAcceleration = angularAcceleration; }
void setState(const Qt::TouchPointState &state) { m_state = state; }
Qt::TouchPointState state() const { return m_state; }
void setState(const QEventPoint::State &state) { m_state = state; }
QEventPoint::State state() const { return m_state; }
private:
int m_id; // sessionID, temporary object ID
@ -136,7 +136,7 @@ private:
float m_angle;
float m_angularVelocity;
float m_angularAcceleration;
Qt::TouchPointState m_state;
QEventPoint::State m_state;
};
Q_DECLARE_TYPEINFO(QTuioToken, Q_MOVABLE_TYPE); // Q_PRIMITIVE_TYPE: not possible: m_id, m_classId == -1

View File

@ -228,19 +228,19 @@ namespace QtAndroidInput
static void touchAdd(JNIEnv */*env*/, jobject /*thiz*/, jint /*winId*/, jint id, jint action, jboolean /*primary*/, jint x, jint y,
jfloat major, jfloat minor, jfloat rotation, jfloat pressure)
{
Qt::TouchPointState state = Qt::TouchPointStationary;
QEventPoint::State state = QEventPoint::State::Stationary;
switch (action) {
case 0:
state = Qt::TouchPointPressed;
state = QEventPoint::State::Pressed;
break;
case 1:
state = Qt::TouchPointMoved;
state = QEventPoint::State::Updated;
break;
case 2:
state = Qt::TouchPointStationary;
state = QEventPoint::State::Stationary;
break;
case 3:
state = Qt::TouchPointReleased;
state = QEventPoint::State::Released;
break;
}
@ -258,7 +258,7 @@ namespace QtAndroidInput
double(major * 2));
m_touchPoints.push_back(touchPoint);
if (state == Qt::TouchPointPressed) {
if (state == QEventPoint::State::Pressed) {
QAndroidInputContext *inputContext = QAndroidInputContext::androidInputContext();
if (inputContext && qGuiApp)
QMetaObject::invokeMethod(inputContext, "touchDown", Q_ARG(int, x), Q_ARG(int, y));

View File

@ -112,22 +112,22 @@ QCocoaTouch *QCocoaTouch::findQCocoaTouch(NSTouch *nstouch)
return nullptr;
}
Qt::TouchPointState QCocoaTouch::toTouchPointState(NSTouchPhase nsState)
QEventPoint::State QCocoaTouch::toTouchPointState(NSTouchPhase nsState)
{
Qt::TouchPointState qtState = Qt::TouchPointReleased;
QEventPoint::State qtState = QEventPoint::State::Released;
switch (nsState) {
case NSTouchPhaseBegan:
qtState = Qt::TouchPointPressed;
qtState = QEventPoint::State::Pressed;
break;
case NSTouchPhaseMoved:
qtState = Qt::TouchPointMoved;
qtState = QEventPoint::State::Updated;
break;
case NSTouchPhaseStationary:
qtState = Qt::TouchPointStationary;
qtState = QEventPoint::State::Stationary;
break;
case NSTouchPhaseEnded:
case NSTouchPhaseCancelled:
qtState = Qt::TouchPointReleased;
qtState = QEventPoint::State::Released;
break;
default:
break;
@ -191,7 +191,7 @@ QCocoaTouch::getCurrentTouchPointList(NSEvent *event, bool acceptSingleTouch)
const auto currentTouchesSnapshot = _currentTouches;
for (QCocoaTouch *qcocoaTouch : currentTouchesSnapshot) {
if (!_updateInternalStateOnly) {
qcocoaTouch->_touchPoint.state = Qt::TouchPointReleased;
qcocoaTouch->_touchPoint.state = QEventPoint::State::Released;
touchPoints.insert(qcocoaTouch->_touchPoint.id, qcocoaTouch->_touchPoint);
}
delete qcocoaTouch;
@ -207,7 +207,7 @@ QCocoaTouch::getCurrentTouchPointList(NSEvent *event, bool acceptSingleTouch)
if (_updateInternalStateOnly && !wasUpdateInternalStateOnly && !_currentTouches.isEmpty()) {
QCocoaTouch *qcocoaTouch = _currentTouches.cbegin().value();
qcocoaTouch->_touchPoint.state = Qt::TouchPointReleased;
qcocoaTouch->_touchPoint.state = QEventPoint::State::Released;
touchPoints.insert(qcocoaTouch->_touchPoint.id, qcocoaTouch->_touchPoint);
// Since this last touch also will end up being the first
// touch (if the user adds a second finger without lifting

View File

@ -88,7 +88,7 @@ class QCocoaTouch
void updateTouchData(NSTouch *nstouch, NSTouchPhase phase);
static QCocoaTouch *findQCocoaTouch(NSTouch *nstouch);
static Qt::TouchPointState toTouchPointState(NSTouchPhase nsState);
static QEventPoint::State toTouchPointState(NSTouchPhase nsState);
};
QT_END_NAMESPACE

View File

@ -367,7 +367,7 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
return [super pointInside:point withEvent:event];
}
- (void)handleTouches:(NSSet *)touches withEvent:(UIEvent *)event withState:(Qt::TouchPointState)state withTimestamp:(ulong)timeStamp
- (void)handleTouches:(NSSet *)touches withEvent:(UIEvent *)event withState:(QEventPoint::State)state withTimestamp:(ulong)timeStamp
{
QIOSIntegration *iosIntegration = QIOSIntegration::instance();
bool supportsPressure = QIOSIntegration::instance()->touchDevice()->capabilities() & QPointingDevice::Capability::Pressure;
@ -417,7 +417,7 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
}
}
if (!uiTouch) {
touchPoint.state = Qt::TouchPointStationary;
touchPoint.state = QEventPoint::State::Stationary;
} else {
touchPoint.state = state;
@ -444,7 +444,7 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
} else {
// We don't claim that our touch device supports QPointingDevice::Capability::Pressure,
// but fill in a meaningful value in case clients use it anyway.
touchPoint.pressure = (state == Qt::TouchPointReleased) ? 0.0 : 1.0;
touchPoint.pressure = (state == QEventPoint::State::Released) ? 0.0 : 1.0;
}
}
}
@ -499,17 +499,17 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
topLevel->requestActivateWindow();
}
[self handleTouches:touches withEvent:event withState:Qt::TouchPointPressed withTimestamp:ulong(event.timestamp * 1000)];
[self handleTouches:touches withEvent:event withState:QEventPoint::State::Pressed withTimestamp:ulong(event.timestamp * 1000)];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
[self handleTouches:touches withEvent:event withState:Qt::TouchPointMoved withTimestamp:ulong(event.timestamp * 1000)];
[self handleTouches:touches withEvent:event withState:QEventPoint::State::Updated withTimestamp:ulong(event.timestamp * 1000)];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
[self handleTouches:touches withEvent:event withState:Qt::TouchPointReleased withTimestamp:ulong(event.timestamp * 1000)];
[self handleTouches:touches withEvent:event withState:QEventPoint::State::Released withTimestamp:ulong(event.timestamp * 1000)];
// Remove ended touch points from the active set:
#ifndef Q_OS_TVOS

View File

@ -160,7 +160,7 @@ QQnxScreenEventHandler::QQnxScreenEventHandler(QQnxIntegration *integration)
m_touchPoints[i].pressure = 1.0;
// nothing touching
m_touchPoints[i].state = Qt::TouchPointReleased;
m_touchPoints[i].state = QEventPoint::State::Released;
}
}
@ -544,15 +544,15 @@ void QQnxScreenEventHandler::handleTouchEvent(screen_event_t event, int qnxType)
QEvent::Type type = QEvent::None;
switch (qnxType) {
case SCREEN_EVENT_MTOUCH_TOUCH:
m_touchPoints[touchId].state = Qt::TouchPointPressed;
m_touchPoints[touchId].state = QEventPoint::State::Pressed;
type = QEvent::TouchBegin;
break;
case SCREEN_EVENT_MTOUCH_MOVE:
m_touchPoints[touchId].state = Qt::TouchPointMoved;
m_touchPoints[touchId].state = QEventPoint::State::Updated;
type = QEvent::TouchUpdate;
break;
case SCREEN_EVENT_MTOUCH_RELEASE:
m_touchPoints[touchId].state = Qt::TouchPointReleased;
m_touchPoints[touchId].state = QEventPoint::State::Released;
type = QEvent::TouchEnd;
break;
}
@ -563,9 +563,9 @@ void QQnxScreenEventHandler::handleTouchEvent(screen_event_t event, int qnxType)
if (i == touchId) {
// current touch point is always active
pointList.append(m_touchPoints[i]);
} else if (m_touchPoints[i].state != Qt::TouchPointReleased) {
} else if (m_touchPoints[i].state != QEventPoint::State::Released) {
// finger is down but did not move
m_touchPoints[i].state = Qt::TouchPointStationary;
m_touchPoints[i].state = QEventPoint::State::Stationary;
pointList.append(m_touchPoints[i]);
}
}

View File

@ -738,22 +738,22 @@ int QWasmEventTranslator::handleTouch(int eventType, const EmscriptenTouchEvent
case EMSCRIPTEN_EVENT_TOUCHSTART:
if (tp != pressedTouchIds.constEnd()) {
touchPoint.state = (stationaryTouchPoint
? Qt::TouchPointStationary
: Qt::TouchPointMoved);
? QEventPoint::State::Stationary
: QEventPoint::State::Updated);
} else {
touchPoint.state = Qt::TouchPointPressed;
touchPoint.state = QEventPoint::State::Pressed;
}
pressedTouchIds.insert(touchPoint.id, touchPoint.normalPosition);
break;
case EMSCRIPTEN_EVENT_TOUCHEND:
touchPoint.state = Qt::TouchPointReleased;
touchPoint.state = QEventPoint::State::Released;
pressedTouchIds.remove(touchPoint.id);
break;
case EMSCRIPTEN_EVENT_TOUCHMOVE:
touchPoint.state = (stationaryTouchPoint
? Qt::TouchPointStationary
: Qt::TouchPointMoved);
? QEventPoint::State::Stationary
: QEventPoint::State::Updated);
pressedTouchIds.insert(touchPoint.id, touchPoint.normalPosition);
break;

View File

@ -601,7 +601,7 @@ bool QWindowsMouseHandler::translateTouchEvent(QWindow *window, HWND,
QTouchPointList touchPoints;
touchPoints.reserve(winTouchPointCount);
Qt::TouchPointStates allStates;
QEventPoint::States allStates;
GetTouchInputInfo(reinterpret_cast<HTOUCHINPUT>(msg.lParam),
UINT(msg.wParam), winTouchInputs.data(), sizeof(TOUCHINPUT));
@ -628,15 +628,15 @@ bool QWindowsMouseHandler::translateTouchEvent(QWindow *window, HWND,
touchPoint.normalPosition = normalPosition;
if (winTouchInput.dwFlags & TOUCHEVENTF_DOWN) {
touchPoint.state = Qt::TouchPointPressed;
touchPoint.state = QEventPoint::State::Pressed;
m_lastTouchPositions.insert(id, touchPoint.normalPosition);
} else if (winTouchInput.dwFlags & TOUCHEVENTF_UP) {
touchPoint.state = Qt::TouchPointReleased;
touchPoint.state = QEventPoint::State::Released;
m_lastTouchPositions.remove(id);
} else {
touchPoint.state = (stationaryTouchPoint
? Qt::TouchPointStationary
: Qt::TouchPointMoved);
? QEventPoint::State::Stationary
: QEventPoint::State::Updated);
m_lastTouchPositions.insert(id, touchPoint.normalPosition);
}
@ -648,7 +648,7 @@ bool QWindowsMouseHandler::translateTouchEvent(QWindow *window, HWND,
CloseTouchInputHandle(reinterpret_cast<HTOUCHINPUT>(msg.lParam));
// all touch points released, forget the ids we've seen, they may not be reused
if (allStates == Qt::TouchPointReleased)
if (allStates == QEventPoint::State::Released)
m_touchInputIDToTouchPointID.clear();
QWindowSystemInterface::handleTouchEvent(window,

View File

@ -491,7 +491,7 @@ bool QWindowsPointerHandler::translateTouchEvent(QWindow *window, HWND hwnd,
<< " message=" << Qt::hex << msg.message
<< " count=" << Qt::dec << count;
Qt::TouchPointStates allStates;
QEventPoint::States allStates;
for (quint32 i = 0; i < count; ++i) {
if (QWindowsContext::verbose > 1)
@ -526,13 +526,13 @@ bool QWindowsPointerHandler::translateTouchEvent(QWindow *window, HWND hwnd,
touchPoint.normalPosition = normalPosition;
if (touchInfo[i].pointerInfo.pointerFlags & POINTER_FLAG_DOWN) {
touchPoint.state = Qt::TouchPointPressed;
touchPoint.state = QEventPoint::State::Pressed;
m_lastTouchPositions.insert(touchPoint.id, touchPoint.normalPosition);
} else if (touchInfo[i].pointerInfo.pointerFlags & POINTER_FLAG_UP) {
touchPoint.state = Qt::TouchPointReleased;
touchPoint.state = QEventPoint::State::Released;
m_lastTouchPositions.remove(touchPoint.id);
} else {
touchPoint.state = stationaryTouchPoint ? Qt::TouchPointStationary : Qt::TouchPointMoved;
touchPoint.state = stationaryTouchPoint ? QEventPoint::State::Stationary : QEventPoint::State::Updated;
m_lastTouchPositions.insert(touchPoint.id, touchPoint.normalPosition);
}
allStates |= touchPoint.state;
@ -544,7 +544,7 @@ bool QWindowsPointerHandler::translateTouchEvent(QWindow *window, HWND hwnd,
}
// all touch points released, forget the ids we've seen.
if (allStates == Qt::TouchPointReleased)
if (allStates == QEventPoint::State::Released)
m_touchInputIDToTouchPointID.clear();
QWindowSystemInterface::handleTouchEvent(window, m_touchDevice, touchPoints,

View File

@ -819,7 +819,7 @@ void QXcbConnection::xi2ProcessTouch(void *xiDevEvent, QXcbWindow *platformWindo
if (xiDeviceEvent->event_type == XCB_INPUT_TOUCH_BEGIN) {
QWindowSystemInterface::TouchPoint tp;
tp.id = xiDeviceEvent->detail % INT_MAX;
tp.state = Qt::TouchPointPressed;
tp.state = QEventPoint::State::Pressed;
tp.pressure = -1.0;
dev->touchPoints[tp.id] = tp;
}
@ -926,9 +926,9 @@ void QXcbConnection::xi2ProcessTouch(void *xiDevEvent, QXcbWindow *platformWindo
dev->size.height() * screen->geometry().height() / screen->physicalSize().height();
x = dev->firstPressedPosition.x() + dx;
y = dev->firstPressedPosition.y() + dy;
touchPoint.state = Qt::TouchPointMoved;
touchPoint.state = QEventPoint::State::Updated;
} else if (touchPoint.area.center() != QPoint(x, y)) {
touchPoint.state = Qt::TouchPointMoved;
touchPoint.state = QEventPoint::State::Updated;
if (dev->qtTouchDevice->type() == QInputDevice::DeviceType::TouchPad)
dev->pointPressedPosition[touchPoint.id] = QPointF(x, y);
}
@ -948,7 +948,7 @@ void QXcbConnection::xi2ProcessTouch(void *xiDevEvent, QXcbWindow *platformWindo
}
break;
case XCB_INPUT_TOUCH_END:
touchPoint.state = Qt::TouchPointReleased;
touchPoint.state = QEventPoint::State::Released;
if (dev->qtTouchDevice->type() == QInputDevice::DeviceType::TouchPad && dev->pointPressedPosition.value(touchPoint.id) == QPointF(x, y)) {
qreal dx = (nx - dev->firstPressedNormalPosition.x()) *
dev->size.width() * screen->geometry().width() / screen->physicalSize().width();
@ -967,13 +967,13 @@ void QXcbConnection::xi2ProcessTouch(void *xiDevEvent, QXcbWindow *platformWindo
" area " << touchPoint.area << " pressure " << touchPoint.pressure;
Qt::KeyboardModifiers modifiers = keyboard()->translateModifiers(xiDeviceEvent->mods.effective);
QWindowSystemInterface::handleTouchEvent(platformWindow->window(), xiDeviceEvent->time, dev->qtTouchDevice, dev->touchPoints.values(), modifiers);
if (touchPoint.state == Qt::TouchPointReleased)
if (touchPoint.state == QEventPoint::State::Released)
// If a touchpoint was released, we can forget it, because the ID won't be reused.
dev->touchPoints.remove(touchPoint.id);
else
// Make sure that we don't send TouchPointPressed/Moved in more than one QTouchEvent
// with this touch point if the next XI2 event is about a different touch point.
touchPoint.state = Qt::TouchPointStationary;
touchPoint.state = QEventPoint::State::Stationary;
}
bool QXcbConnection::startSystemMoveResizeForTouch(xcb_window_t window, int edges)
@ -984,8 +984,8 @@ bool QXcbConnection::startSystemMoveResizeForTouch(xcb_window_t window, int edge
if (deviceData.qtTouchDevice->type() == QInputDevice::DeviceType::TouchScreen) {
auto pointIt = deviceData.touchPoints.constBegin();
for (; pointIt != deviceData.touchPoints.constEnd(); ++pointIt) {
Qt::TouchPointState state = pointIt.value().state;
if (state == Qt::TouchPointMoved || state == Qt::TouchPointPressed || state == Qt::TouchPointStationary) {
QEventPoint::State state = pointIt.value().state;
if (state == QEventPoint::State::Updated || state == QEventPoint::State::Pressed || state == QEventPoint::State::Stationary) {
m_startSystemMoveResizeInfo.window = window;
m_startSystemMoveResizeInfo.deviceid = devIt.key();
m_startSystemMoveResizeInfo.pointid = pointIt.key();

View File

@ -211,20 +211,20 @@ namespace QTest
stateKey &= static_cast<unsigned int>(Qt::KeyboardModifierMask);
QMouseEvent me(QEvent::User, QPoint(), Qt::LeftButton, button, stateKey);
QMouseEvent me(QEvent::User, QPointF(), Qt::LeftButton, QTestPrivate::qtestMouseButtons, stateKey, QPointingDevice::primaryPointingDevice());
switch (action)
{
case MousePress:
me = QMouseEvent(QEvent::MouseButtonPress, pos, widget->mapToGlobal(pos), button, button, stateKey);
me = QMouseEvent(QEvent::MouseButtonPress, pos, widget->mapToGlobal(pos), button, button, stateKey, QPointingDevice::primaryPointingDevice());
me.setTimestamp(++lastMouseTimestamp);
break;
case MouseRelease:
me = QMouseEvent(QEvent::MouseButtonRelease, pos, widget->mapToGlobal(pos), button, Qt::MouseButton(), stateKey);
me = QMouseEvent(QEvent::MouseButtonRelease, pos, widget->mapToGlobal(pos), button, Qt::MouseButton(), stateKey, QPointingDevice::primaryPointingDevice());
me.setTimestamp(++lastMouseTimestamp);
lastMouseTimestamp += mouseDoubleClickInterval; // avoid double clicks being generated
break;
case MouseDClick:
me = QMouseEvent(QEvent::MouseButtonDblClick, pos, widget->mapToGlobal(pos), button, button, stateKey);
me = QMouseEvent(QEvent::MouseButtonDblClick, pos, widget->mapToGlobal(pos), button, button, stateKey, QPointingDevice::primaryPointingDevice());
me.setTimestamp(++lastMouseTimestamp);
break;
case MouseMove:

View File

@ -61,7 +61,7 @@
QT_BEGIN_NAMESPACE
Q_GUI_EXPORT void qt_handleTouchEvent(QWindow *w, const QPointingDevice *device,
const QList<QTouchEvent::TouchPoint> &points,
const QList<QEventPoint> &points,
Qt::KeyboardModifiers mods = Qt::NoModifier);
@ -81,52 +81,52 @@ namespace QTest
}
QTouchEventSequence& press(int touchId, const QPoint &pt, QWindow *window = nullptr)
{
QTouchEvent::TouchPoint &p = point(touchId);
p.setScreenPos(mapToScreen(window, pt));
p.setState(Qt::TouchPointPressed);
QEventPoint &p = point(touchId);
p.m_globalPos = mapToScreen(window, pt);
p.m_state = QEventPoint::State::Pressed;
return *this;
}
QTouchEventSequence& move(int touchId, const QPoint &pt, QWindow *window = nullptr)
{
QTouchEvent::TouchPoint &p = point(touchId);
p.setScreenPos(mapToScreen(window, pt));
p.setState(Qt::TouchPointMoved);
QEventPoint &p = point(touchId);
p.m_globalPos = mapToScreen(window, pt);
p.m_state = QEventPoint::State::Updated;
return *this;
}
QTouchEventSequence& release(int touchId, const QPoint &pt, QWindow *window = nullptr)
{
QTouchEvent::TouchPoint &p = point(touchId);
p.setScreenPos(mapToScreen(window, pt));
p.setState(Qt::TouchPointReleased);
QEventPoint &p = point(touchId);
p.m_globalPos = mapToScreen(window, pt);
p.m_state = QEventPoint::State::Released;
return *this;
}
QTouchEventSequence& stationary(int touchId)
{
QTouchEvent::TouchPoint &p = pointOrPreviousPoint(touchId);
p.setState(Qt::TouchPointStationary);
QEventPoint &p = pointOrPreviousPoint(touchId);
p.m_state = QEventPoint::State::Stationary;
return *this;
}
#ifdef QT_WIDGETS_LIB
QTouchEventSequence& press(int touchId, const QPoint &pt, QWidget *widget = nullptr)
{
QTouchEvent::TouchPoint &p = point(touchId);
p.setScreenPos(mapToScreen(widget, pt));
p.setState(Qt::TouchPointPressed);
QEventPoint &p = point(touchId);
p.m_globalPos = mapToScreen(widget, pt);
p.m_state = QEventPoint::State::Pressed;
return *this;
}
QTouchEventSequence& move(int touchId, const QPoint &pt, QWidget *widget = nullptr)
{
QTouchEvent::TouchPoint &p = point(touchId);
p.setScreenPos(mapToScreen(widget, pt));
p.setState(Qt::TouchPointMoved);
QEventPoint &p = point(touchId);
p.m_globalPos = mapToScreen(widget, pt);
p.m_state = QEventPoint::State::Updated;
return *this;
}
QTouchEventSequence& release(int touchId, const QPoint &pt, QWidget *widget = nullptr)
{
QTouchEvent::TouchPoint &p = point(touchId);
p.setScreenPos(mapToScreen(widget, pt));
p.setState(Qt::TouchPointReleased);
QEventPoint &p = point(touchId);
p.m_globalPos = mapToScreen(widget, pt);
p.m_state = QEventPoint::State::Released;
return *this;
}
#endif
@ -168,24 +168,6 @@ private:
{
}
QTouchEvent::TouchPoint &point(int touchId)
{
if (!points.contains(touchId))
points[touchId] = QTouchEvent::TouchPoint(touchId);
return points[touchId];
}
QTouchEvent::TouchPoint &pointOrPreviousPoint(int touchId)
{
if (!points.contains(touchId)) {
if (previousPoints.contains(touchId))
points[touchId] = previousPoints.value(touchId);
else
points[touchId] = QTouchEvent::TouchPoint(touchId);
}
return points[touchId];
}
#ifdef QT_WIDGETS_LIB
QPoint mapToScreen(QWidget *widget, const QPoint &pt)
{
@ -201,8 +183,8 @@ private:
return targetWindow ? targetWindow->mapToGlobal(pt) : pt;
}
QMap<int, QTouchEvent::TouchPoint> previousPoints;
QMap<int, QTouchEvent::TouchPoint> points;
QMap<int, QEventPoint> previousPoints;
QMap<int, QEventPoint> points;
#ifdef QT_WIDGETS_LIB
QWidget *targetWidget;
#endif
@ -213,6 +195,29 @@ private:
friend QTouchEventSequence touchEvent(QWidget *widget, QPointingDevice *device, bool autoCommit);
#endif
friend QTouchEventSequence touchEvent(QWindow *window, QPointingDevice *device, bool autoCommit);
protected:
// These don't make sense for public testing API,
// because we are getting rid of most public setters in QEventPoint.
// Each of these constructs a QEventPoint with null parent; in normal usage,
// the QTouchEvent constructor will set the points' parents to itself, later on.
QEventPoint &point(int touchId)
{
if (!points.contains(touchId))
points[touchId] = QEventPoint(touchId);
return points[touchId];
}
QEventPoint &pointOrPreviousPoint(int touchId)
{
if (!points.contains(touchId)) {
if (previousPoints.contains(touchId))
points[touchId] = previousPoints.value(touchId);
else
points[touchId] = QEventPoint(touchId);
}
return points[touchId];
}
};
#if defined(QT_WIDGETS_LIB) || defined(Q_CLANG_QDOC)

View File

@ -1301,7 +1301,9 @@ void QGraphicsProxyWidget::wheelEvent(QGraphicsSceneWheelEvent *event)
// pixelDelta, inverted, scrollPhase and source from the original QWheelEvent
// were not preserved in the QGraphicsSceneWheelEvent unfortunately
QWheelEvent wheelEvent(pos, event->screenPos(), QPoint(), angleDelta,
event->buttons(), event->modifiers(), Qt::NoScrollPhase, false);
event->buttons(), event->modifiers(), Qt::NoScrollPhase,
false, Qt::MouseEventNotSynthesized,
QPointingDevice::primaryPointingDevice());
QPointer<QWidget> focusWidget = d->widget->focusWidget();
extern bool qt_sendSpontaneousEvent(QObject *, QEvent *);
qt_sendSpontaneousEvent(receiver, &wheelEvent);

View File

@ -243,6 +243,7 @@
#include <QtGui/qtransform.h>
#include <QtGui/qinputmethod.h>
#include <private/qapplication_p.h>
#include <private/qevent_p.h>
#include <private/qobject_p.h>
#if QT_CONFIG(graphicseffect)
#include <private/qgraphicseffect_p.h>
@ -5828,18 +5829,15 @@ void QGraphicsScenePrivate::updateTouchPointsForItem(QGraphicsItem *item, QTouch
const QTransform mapFromScene =
item->d_ptr->genericMapFromSceneTransform(static_cast<const QWidget *>(touchEvent->target()));
for (auto &touchPoint : touchEvent->_touchPoints) {
touchPoint.setPos(mapFromScene.map(touchPoint.scenePosition()));
touchPoint.setStartPos(mapFromScene.map(touchPoint.scenePressPosition()));
touchPoint.setLastPos(mapFromScene.map(touchPoint.lastScenePos()));
}
for (QEventPoint &pt : QMutableTouchEvent::from(touchEvent)->touchPoints())
QMutableEventPoint::from(pt).setPosition(mapFromScene.map(pt.scenePosition()));
}
int QGraphicsScenePrivate::findClosestTouchPointId(const QPointF &scenePos)
{
int closestTouchPointId = -1;
qreal closestDistance = qreal(0.);
for (const QTouchEvent::TouchPoint &touchPoint : qAsConst(sceneCurrentTouchPoints)) {
for (const QEventPoint &touchPoint : qAsConst(sceneCurrentTouchPoints)) {
qreal distance = QLineF(scenePos, touchPoint.scenePosition()).length();
if (closestTouchPointId == -1|| distance < closestDistance) {
closestTouchPointId = touchPoint.id();
@ -5851,14 +5849,14 @@ int QGraphicsScenePrivate::findClosestTouchPointId(const QPointF &scenePos)
void QGraphicsScenePrivate::touchEventHandler(QTouchEvent *sceneTouchEvent)
{
typedef QPair<Qt::TouchPointStates, QList<QTouchEvent::TouchPoint> > StatesAndTouchPoints;
typedef QPair<QEventPoint::States, QList<QEventPoint> > StatesAndTouchPoints;
QHash<QGraphicsItem *, StatesAndTouchPoints> itemsNeedingEvents;
const auto touchPoints = sceneTouchEvent->touchPoints();
for (const auto &touchPoint : touchPoints) {
// update state
QGraphicsItem *item = nullptr;
if (touchPoint.state() == Qt::TouchPointPressed) {
if (touchPoint.state() == QEventPoint::State::Pressed) {
if (sceneTouchEvent->pointingDevice()->type() == QInputDevice::DeviceType::TouchPad) {
// on touch-pad devices, send all touch points to the same item
item = itemForTouchPointId.isEmpty()
@ -5886,7 +5884,7 @@ void QGraphicsScenePrivate::touchEventHandler(QTouchEvent *sceneTouchEvent)
itemForTouchPointId.insert(touchPoint.id(), item);
sceneCurrentTouchPoints.insert(touchPoint.id(), touchPoint);
} else if (touchPoint.state() == Qt::TouchPointReleased) {
} else if (touchPoint.state() == QEventPoint::State::Released) {
item = itemForTouchPointId.take(touchPoint.id());
if (!item)
continue;
@ -5901,7 +5899,7 @@ void QGraphicsScenePrivate::touchEventHandler(QTouchEvent *sceneTouchEvent)
}
StatesAndTouchPoints &statesAndTouchPoints = itemsNeedingEvents[item];
statesAndTouchPoints.first |= touchPoint.state();
statesAndTouchPoints.first = QEventPoint::States(statesAndTouchPoints.first | touchPoint.state());
statesAndTouchPoints.second.append(touchPoint);
}
@ -5921,15 +5919,15 @@ void QGraphicsScenePrivate::touchEventHandler(QTouchEvent *sceneTouchEvent)
// determine event type from the state mask
QEvent::Type eventType;
switch (it.value().first) {
case Qt::TouchPointPressed:
case QEventPoint::State::Pressed:
// all touch points have pressed state
eventType = QEvent::TouchBegin;
break;
case Qt::TouchPointReleased:
case QEventPoint::State::Released:
// all touch points have released state
eventType = QEvent::TouchEnd;
break;
case Qt::TouchPointStationary:
case QEventPoint::State::Stationary:
// don't send the event if nothing changed
continue;
default:
@ -5938,9 +5936,7 @@ void QGraphicsScenePrivate::touchEventHandler(QTouchEvent *sceneTouchEvent)
break;
}
QTouchEvent touchEvent(eventType, sceneTouchEvent->pointingDevice(), sceneTouchEvent->modifiers(), it.value().first, it.value().second);
// TODO more constructor args and fewer setters?
touchEvent.setWindow(sceneTouchEvent->window());
QMutableTouchEvent touchEvent(eventType, sceneTouchEvent->pointingDevice(), sceneTouchEvent->modifiers(), it.value().second);
touchEvent.setTarget(sceneTouchEvent->target());
touchEvent.setModifiers(sceneTouchEvent->modifiers());
touchEvent.setTimestamp(sceneTouchEvent->timestamp());
@ -5981,7 +5977,7 @@ bool QGraphicsScenePrivate::sendTouchBeginEvent(QGraphicsItem *origin, QTouchEve
if (focusOnTouch) {
if (cachedItemsUnderMouse.isEmpty() || cachedItemsUnderMouse.constFirst() != origin) {
const QTouchEvent::TouchPoint &firstTouchPoint = touchEvent->touchPoints().first();
const QEventPoint &firstTouchPoint = touchEvent->touchPoints().first();
cachedItemsUnderMouse = itemsAtPosition(firstTouchPoint.globalPosition().toPoint(),
firstTouchPoint.scenePosition(),
static_cast<QWidget *>(touchEvent->target()));

View File

@ -309,7 +309,7 @@ public:
QStyleOptionGraphicsItem styleOptionTmp;
QMap<int, QTouchEvent::TouchPoint> sceneCurrentTouchPoints;
QMap<int, QEventPoint> sceneCurrentTouchPoints;
QMap<int, QGraphicsItem *> itemForTouchPointId;
static void updateTouchPointsForItem(QGraphicsItem *item, QTouchEvent *touchEvent);
int findClosestTouchPointId(const QPointF &scenePos);

View File

@ -653,6 +653,7 @@ void QGraphicsSceneMouseEvent::setSource(Qt::MouseEventSource source)
/*!
\since 5.4
\deprecated in 6.0
Returns the mouse event flags.

View File

@ -121,8 +121,12 @@ public:
Qt::MouseEventSource source() const;
void setSource(Qt::MouseEventSource source);
#if QT_DEPRECATED_SINCE(6, 0)
QT_DEPRECATED_VERSION_X_6_0("Internal, don't use")
Qt::MouseEventFlags flags() const;
QT_DEPRECATED_VERSION_X_6_0("Internal, don't use")
void setFlags(Qt::MouseEventFlags);
#endif // QT_DEPRECATED_SINCE(6, 0)
private:
Q_DECLARE_PRIVATE(QGraphicsSceneMouseEvent)

View File

@ -310,21 +310,12 @@ inline int q_round_bound(qreal d) //### (int)(qreal) INT_MAX != INT_MAX for sing
void QGraphicsViewPrivate::translateTouchEvent(QGraphicsViewPrivate *d, QTouchEvent *touchEvent)
{
QList<QTouchEvent::TouchPoint> touchPoints = touchEvent->touchPoints();
for (int i = 0; i < touchPoints.count(); ++i) {
QTouchEvent::TouchPoint &touchPoint = touchPoints[i];
const QSizeF ellipseDiameters = touchPoint.ellipseDiameters();
for (QEventPoint &pt : QMutableTouchEvent::from(touchEvent)->touchPoints()) {
// the scene will set the item local pos, startPos, lastPos, and rect before delivering to
// an item, but for now those functions are returning the view's local coordinates
touchPoint.setScenePos(d->mapToScene(touchPoint.position()));
touchPoint.setStartScenePos(d->mapToScene(touchPoint.pressPosition()));
touchPoint.setLastScenePos(d->mapToScene(touchPoint.lastPos()));
touchPoint.setEllipseDiameters(ellipseDiameters);
QMutableEventPoint::from(pt).setScenePosition(d->mapToScene(pt.position()));
// screenPos, startScreenPos, and lastScreenPos are already set
}
touchEvent->setTouchPoints(touchPoints);
}
/*!
@ -2929,7 +2920,7 @@ bool QGraphicsView::viewportEvent(QEvent *event)
if (d->scene && d->sceneInteractionAllowed) {
// Convert and deliver the touch event to the scene.
QTouchEvent *touchEvent = static_cast<QTouchEvent *>(event);
touchEvent->setTarget(viewport());
QMutableTouchEvent::from(touchEvent)->setTarget(viewport());
QGraphicsViewPrivate::translateTouchEvent(d, touchEvent);
QCoreApplication::sendEvent(d->scene, touchEvent);
} else {

View File

@ -91,6 +91,7 @@
#include <qthread.h>
#include <private/qthread_p.h>
#include <QtGui/private/qevent_p.h>
#include <private/qfont_p.h>
#if QT_CONFIG(action)
#include <private/qaction_p.h>
@ -99,7 +100,6 @@
#include <stdlib.h>
#include "qapplication_p.h"
#include "private/qevent_p.h"
#include "qwidget_p.h"
#include "qgesture.h"
@ -2946,7 +2946,7 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
mouse->button(), mouse->buttons(), mouse->modifiers(), mouse->source());
me.spont = mouse->spontaneous();
me.setTimestamp(mouse->timestamp());
QGuiApplicationPrivate::setMouseEventFlags(&me, mouse->flags());
QMutableSinglePointEvent::from(me).setDoubleClick(QMutableSinglePointEvent::from(mouse)->isDoubleClick());
// throw away any mouse-tracking-only mouse events
if (!w->hasMouseTracking()
&& mouse->type() == QEvent::MouseMove && mouse->buttons() == 0) {
@ -3067,7 +3067,7 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
}
QWheelEvent we(relpos, wheel->globalPosition(), wheel->pixelDelta(), wheel->angleDelta(), wheel->buttons(),
wheel->modifiers(), phase, wheel->inverted(), wheel->source());
wheel->modifiers(), phase, wheel->inverted(), wheel->source(), wheel->pointingDevice());
we.setTimestamp(wheel->timestamp());
bool eventAccepted;
@ -3080,7 +3080,7 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
if (w->isWindow() || w->testAttribute(Qt::WA_NoMousePropagation))
break;
we.p += w->pos();
QMutableSinglePointEvent::from(we).mutablePoint().setPosition(we.position() + w->pos());
w = w->parentWidget();
} while (w);
wheel->setAccepted(eventAccepted);
@ -3250,7 +3250,7 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
// Note: TouchUpdate and TouchEnd events are never propagated
{
QWidget *widget = static_cast<QWidget *>(receiver);
QTouchEvent *touchEvent = static_cast<QTouchEvent *>(e);
QMutableTouchEvent *touchEvent = QMutableTouchEvent::from(static_cast<QTouchEvent *>(e));
bool eventAccepted = touchEvent->isAccepted();
bool acceptTouchEvents = widget->testAttribute(Qt::WA_AcceptTouchEvents);
@ -3293,12 +3293,8 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
QPoint offset = widget->pos();
widget = widget->parentWidget();
touchEvent->setTarget(widget);
for (int i = 0; i < touchEvent->_touchPoints.size(); ++i) {
QTouchEvent::TouchPoint &pt = touchEvent->_touchPoints[i];
pt.d->pos = pt.position() + offset;
pt.d->startPos = pt.pressPosition() + offset;
pt.d->lastPos = pt.lastPos() + offset;
}
for (QEventPoint &pt : touchEvent->touchPoints())
QMutableEventPoint::from(pt).setPosition(pt.position() + offset);
}
#ifndef QT_NO_GESTURES
@ -3944,18 +3940,15 @@ bool QApplicationPrivate::shouldSetFocus(QWidget *w, Qt::FocusPolicy policy)
bool QApplicationPrivate::updateTouchPointsForWidget(QWidget *widget, QTouchEvent *touchEvent)
{
bool containsPress = false;
for (int i = 0; i < touchEvent->touchPoints().count(); ++i) {
QTouchEvent::TouchPoint &touchPoint = touchEvent->_touchPoints[i];
for (QEventPoint &pt : QMutableTouchEvent::from(touchEvent)->touchPoints()) {
// preserve the sub-pixel resolution
const QPointF screenPos = touchPoint.globalPosition();
const QPointF screenPos = pt.globalPosition();
const QPointF delta = screenPos - screenPos.toPoint();
touchPoint.d->pos = widget->mapFromGlobal(screenPos.toPoint()) + delta;
touchPoint.d->startPos = widget->mapFromGlobal(touchPoint.globalPressPosition().toPoint()) + delta;
touchPoint.d->lastPos = widget->mapFromGlobal(touchPoint.lastScreenPos().toPoint()) + delta;
QMutableEventPoint::from(pt).setPosition(widget->mapFromGlobal(screenPos.toPoint()) + delta);
if (touchPoint.state() == Qt::TouchPointPressed)
if (pt.state() == QEventPoint::State::Pressed)
containsPress = true;
}
return containsPress;
@ -3979,7 +3972,7 @@ void QApplicationPrivate::cleanupMultitouch_sys()
{
}
QWidget *QApplicationPrivate::findClosestTouchPointTarget(const QPointingDevice *device, const QTouchEvent::TouchPoint &touchPoint)
QWidget *QApplicationPrivate::findClosestTouchPointTarget(const QPointingDevice *device, const QEventPoint &touchPoint)
{
const QPointF screenPos = touchPoint.globalPosition();
int closestTouchPointId = -1;
@ -3989,7 +3982,7 @@ QWidget *QApplicationPrivate::findClosestTouchPointTarget(const QPointingDevice
ite = activeTouchPoints.constEnd();
while (it != ite) {
if (it.key().device == device && it.key().touchPointId != touchPoint.id()) {
const QTouchEvent::TouchPoint &touchPoint = it->touchPoint;
const QEventPoint &touchPoint = it->touchPoint;
qreal dx = screenPos.x() - touchPoint.globalPosition().x();
qreal dy = screenPos.y() - touchPoint.globalPosition().y();
qreal distance = dx * dx + dy * dy;
@ -4010,7 +4003,7 @@ void QApplicationPrivate::activateImplicitTouchGrab(QWidget *widget, QTouchEvent
return;
for (int i = 0, tc = touchEvent->touchPoints().count(); i < tc; ++i) {
const QTouchEvent::TouchPoint &touchPoint = touchEvent->touchPoints().at(i);
const QEventPoint &touchPoint = touchEvent->touchPoints().at(i);
activeTouchPoints[QGuiApplicationPrivate::ActiveTouchPointsKey(
touchEvent->pointingDevice(), touchPoint.id())].target = widget;
}
@ -4018,30 +4011,31 @@ void QApplicationPrivate::activateImplicitTouchGrab(QWidget *widget, QTouchEvent
bool QApplicationPrivate::translateRawTouchEvent(QWidget *window,
const QPointingDevice *device,
const QList<QTouchEvent::TouchPoint> &touchPoints,
const QList<QEventPoint> &touchPoints,
ulong timestamp)
{
QApplicationPrivate *d = self;
typedef QPair<Qt::TouchPointStates, QList<QTouchEvent::TouchPoint> > StatesAndTouchPoints;
// TODO get rid of this QPair
typedef QPair<QEventPoint::State, QList<QEventPoint> > StatesAndTouchPoints;
QHash<QWidget *, StatesAndTouchPoints> widgetsNeedingEvents;
for (int i = 0; i < touchPoints.count(); ++i) {
QTouchEvent::TouchPoint touchPoint = touchPoints.at(i);
// explicitly detach from the original touch point that we got, so even
// if the touchpoint structs are reused, we will make a copy that we'll
// deliver to the user (which might want to store the struct for later use).
touchPoint.d = touchPoint.d->detach();
QEventPoint touchPoint = touchPoints.at(i);
// update state
QPointer<QObject> target;
ActiveTouchPointsKey touchInfoKey(device, touchPoint.id());
ActiveTouchPointsValue &touchInfo = d->activeTouchPoints[touchInfoKey];
if (touchPoint.state() == Qt::TouchPointPressed) {
if (device->type() == QInputDevice::DeviceType::TouchPad) {
if (touchPoint.state() == QEventPoint::State::Pressed) {
if (device->type() == QInputDevice::DeviceType::TouchPad && !d->activeTouchPoints.isEmpty()) {
// on touch-pads, send all touch points to the same widget
target = d->activeTouchPoints.isEmpty()
? QPointer<QObject>()
: d->activeTouchPoints.constBegin().value().target;
// pick the first non-null target if possible
for (const auto &a : d->activeTouchPoints.values()) {
if (a.target) {
target = a.target;
break;
}
}
}
if (!target) {
@ -4084,7 +4078,7 @@ bool QApplicationPrivate::translateRawTouchEvent(QWidget *window,
#endif
StatesAndTouchPoints &maskAndPoints = widgetsNeedingEvents[targetWidget];
maskAndPoints.first |= touchPoint.state();
maskAndPoints.first = QEventPoint::State(maskAndPoints.first | touchPoint.state());
maskAndPoints.second.append(touchPoint);
}
@ -4101,13 +4095,13 @@ bool QApplicationPrivate::translateRawTouchEvent(QWidget *window,
QEvent::Type eventType;
switch (it.value().first) {
case Qt::TouchPointPressed:
case QEventPoint::State::Pressed:
eventType = QEvent::TouchBegin;
break;
case Qt::TouchPointReleased:
case QEventPoint::State::Released:
eventType = QEvent::TouchEnd;
break;
case Qt::TouchPointStationary:
case QEventPoint::State::Stationary:
// don't send the event if nothing changed
continue;
default:
@ -4115,14 +4109,10 @@ bool QApplicationPrivate::translateRawTouchEvent(QWidget *window,
break;
}
QTouchEvent touchEvent(eventType,
device,
QGuiApplication::keyboardModifiers(),
it.value().first,
it.value().second);
QMutableTouchEvent touchEvent(eventType, device, QGuiApplication::keyboardModifiers(),
it.value().second);
bool containsPress = updateTouchPointsForWidget(widget, &touchEvent);
touchEvent.setTimestamp(timestamp);
touchEvent.setWindow(window->windowHandle());
touchEvent.setTarget(widget);
if (containsPress)
@ -4160,7 +4150,7 @@ bool QApplicationPrivate::translateRawTouchEvent(QWidget *window,
void QApplicationPrivate::translateTouchCancel(const QPointingDevice *device, ulong timestamp)
{
QTouchEvent touchEvent(QEvent::TouchCancel, device, QGuiApplication::keyboardModifiers());
QMutableTouchEvent touchEvent(QEvent::TouchCancel, device, QGuiApplication::keyboardModifiers());
touchEvent.setTimestamp(timestamp);
QHash<ActiveTouchPointsKey, ActiveTouchPointsValue>::const_iterator it
= self->activeTouchPoints.constBegin(), ite = self->activeTouchPoints.constEnd();
@ -4174,7 +4164,6 @@ void QApplicationPrivate::translateTouchCancel(const QPointingDevice *device, ul
for (QSet<QWidget *>::const_iterator widIt = widgetsNeedingCancel.constBegin(),
widItEnd = widgetsNeedingCancel.constEnd(); widIt != widItEnd; ++widIt) {
QWidget *widget = *widIt;
touchEvent.setWindow(widget->windowHandle());
touchEvent.setTarget(widget);
QApplication::sendSpontaneousEvent(widget, &touchEvent);
}

View File

@ -247,13 +247,13 @@ public:
void initializeMultitouch_sys();
void cleanupMultitouch();
void cleanupMultitouch_sys();
QWidget *findClosestTouchPointTarget(const QPointingDevice *device, const QTouchEvent::TouchPoint &touchPoint);
void appendTouchPoint(const QTouchEvent::TouchPoint &touchPoint);
QWidget *findClosestTouchPointTarget(const QPointingDevice *device, const QEventPoint &touchPoint);
void appendTouchPoint(const QEventPoint &touchPoint);
void removeTouchPoint(int touchPointId);
void activateImplicitTouchGrab(QWidget *widget, QTouchEvent *touchBeginEvent);
static bool translateRawTouchEvent(QWidget *widget,
const QPointingDevice *device,
const QList<QTouchEvent::TouchPoint> &touchPoints,
const QList<QEventPoint> &touchPoints,
ulong timestamp);
static void translateTouchCancel(const QPointingDevice *device, ulong timestamp);

View File

@ -71,7 +71,7 @@ QGesture *QPanGestureRecognizer::create(QObject *target)
return new QPanGesture;
}
static QPointF panOffset(const QList<QTouchEvent::TouchPoint> &touchPoints, int maxCount)
static QPointF panOffset(const QList<QEventPoint> &touchPoints, int maxCount)
{
QPointF result;
const int count = qMin(touchPoints.size(), maxCount);
@ -92,7 +92,7 @@ QGestureRecognizer::Result QPanGestureRecognizer::recognize(QGesture *state,
case QEvent::TouchBegin: {
const QTouchEvent *ev = static_cast<const QTouchEvent *>(event);
result = QGestureRecognizer::MayBeGesture;
QTouchEvent::TouchPoint p = ev->touchPoints().at(0);
QEventPoint p = ev->touchPoints().at(0);
d->lastOffset = d->offset = QPointF();
d->pointCount = m_pointCount;
break;
@ -185,8 +185,8 @@ QGestureRecognizer::Result QPinchGestureRecognizer::recognize(QGesture *state,
const QTouchEvent *ev = static_cast<const QTouchEvent *>(event);
d->changeFlags = { };
if (ev->touchPoints().size() == 2) {
QTouchEvent::TouchPoint p1 = ev->touchPoints().at(0);
QTouchEvent::TouchPoint p2 = ev->touchPoints().at(1);
QEventPoint p1 = ev->touchPoints().at(0);
QEventPoint p2 = ev->touchPoints().at(1);
d->hotSpot = p1.globalPosition();
d->isHotSpotSet = true;
@ -209,7 +209,7 @@ QGestureRecognizer::Result QPinchGestureRecognizer::recognize(QGesture *state,
} else {
d->lastScaleFactor = d->scaleFactor;
QLineF line(p1.globalPosition(), p2.globalPosition());
QLineF lastLine(p1.lastScreenPos(), p2.lastScreenPos());
QLineF lastLine(p1.globalLastPosition(), p2.globalLastPosition());
qreal newScaleFactor = line.length() / lastLine.length();
if (newScaleFactor > kSingleStepScaleMax || newScaleFactor < kSingleStepScaleMin)
return QGestureRecognizer::Ignore;
@ -315,9 +315,9 @@ QGestureRecognizer::Result QSwipeGestureRecognizer::recognize(QGesture *state,
result = QGestureRecognizer::CancelGesture;
else if (ev->touchPoints().size() == 3) {
d->state = QSwipeGesturePrivate::ThreePointsReached;
QTouchEvent::TouchPoint p1 = ev->touchPoints().at(0);
QTouchEvent::TouchPoint p2 = ev->touchPoints().at(1);
QTouchEvent::TouchPoint p3 = ev->touchPoints().at(2);
QEventPoint p1 = ev->touchPoints().at(0);
QEventPoint p2 = ev->touchPoints().at(1);
QEventPoint p3 = ev->touchPoints().at(2);
if (d->lastPositions[0].isNull()) {
d->lastPositions[0] = p1.globalPressPosition().toPoint();
@ -381,7 +381,7 @@ QGestureRecognizer::Result QSwipeGestureRecognizer::recognize(QGesture *state,
result = QGestureRecognizer::Ignore;
break;
case QSwipeGesturePrivate::ThreePointsReached:
result = (ev->touchPointStates() & Qt::TouchPointPressed)
result = (ev->touchPointStates() & QEventPoint::State::Pressed)
? QGestureRecognizer::CancelGesture : QGestureRecognizer::Ignore;
break;
}
@ -447,7 +447,7 @@ QGestureRecognizer::Result QTapGestureRecognizer::recognize(QGesture *state,
case QEvent::TouchUpdate:
case QEvent::TouchEnd: {
if (q->state() != Qt::NoGesture && ev->touchPoints().size() == 1) {
QTouchEvent::TouchPoint p = ev->touchPoints().at(0);
QEventPoint p = ev->touchPoints().at(0);
QPoint delta = p.position().toPoint() - p.pressPosition().toPoint();
enum { TapRadius = 40 };
if (delta.manhattanLength() <= TapRadius) {
@ -551,7 +551,7 @@ QTapAndHoldGestureRecognizer::recognize(QGesture *state, QObject *object,
case QEvent::TouchUpdate: {
const QTouchEvent *ev = static_cast<const QTouchEvent *>(event);
if (d->timerId && ev->touchPoints().size() == 1) {
QTouchEvent::TouchPoint p = ev->touchPoints().at(0);
QEventPoint p = ev->touchPoints().at(0);
QPoint delta = p.position().toPoint() - p.pressPosition().toPoint();
if (delta.manhattanLength() <= TapRadius)
return QGestureRecognizer::MayBeGesture;

View File

@ -1,6 +1,6 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtWidgets module of the Qt Toolkit.
@ -563,8 +563,7 @@ void QWidgetWindow::handleMouseEvent(QMouseEvent *event)
}
}
#endif
if ((event->type() != QEvent::MouseButtonPress)
|| !(event->flags().testFlag(Qt::MouseEventCreatedDoubleClick))) {
if ((event->type() != QEvent::MouseButtonPress) || !(QMutableSinglePointEvent::from(event)->isDoubleClick())) {
// if the widget that was pressed is gone, then deliver move events without buttons
const auto buttons = event->type() == QEvent::MouseMove && qt_popup_down_closed
? Qt::NoButton : event->buttons();
@ -666,8 +665,7 @@ void QWidgetWindow::handleMouseEvent(QMouseEvent *event)
if (!receiver)
return;
if ((event->type() != QEvent::MouseButtonPress)
|| !(event->flags().testFlag(Qt::MouseEventCreatedDoubleClick))) {
if ((event->type() != QEvent::MouseButtonPress) || !QMutableSinglePointEvent::from(event)->isDoubleClick()) {
// The preceding statement excludes MouseButtonPress events which caused
// creation of a MouseButtonDblClick event. QTBUG-25831
@ -866,7 +864,8 @@ void QWidgetWindow::handleWheelEvent(QWheelEvent *event)
QPoint mapped = widget->mapFrom(rootWidget, pos);
QWheelEvent translated(QPointF(mapped), event->globalPosition(), event->pixelDelta(), event->angleDelta(),
event->buttons(), event->modifiers(), event->phase(), event->inverted(), event->source());
event->buttons(), event->modifiers(), event->phase(), event->inverted(),
event->source(), event->pointingDevice());
translated.setTimestamp(event->timestamp());
QGuiApplication::forwardEvent(widget, &translated, event);
}

View File

@ -120,12 +120,6 @@ void tst_QMouseEvent::mouseEventBasic()
QCOMPARE(me.position(), local);
QCOMPARE(me.scenePosition(), scene);
QCOMPARE(me.globalPosition(), screen);
QPointF changedLocal(33, 66);
me.setLocalPos(changedLocal);
QCOMPARE(me.position(), changedLocal);
QCOMPARE(me.scenePosition(), scene);
QCOMPARE(me.globalPosition(), screen);
}
void tst_QMouseEvent::checkMousePressEvent_data()

File diff suppressed because it is too large Load Diff

View File

@ -960,15 +960,15 @@ public:
QList<QTouchEvent::TouchPoint> points = event->touchPoints();
for (int i = 0; i < points.count(); ++i) {
switch (points.at(i).state()) {
case Qt::TouchPointPressed:
case QEventPoint::State::Pressed:
++touchPressedCount;
if (spinLoopWhenPressed)
QCoreApplication::processEvents();
break;
case Qt::TouchPointReleased:
case QEventPoint::State::Released:
++touchReleasedCount;
break;
case Qt::TouchPointMoved:
case QEventPoint::State::Updated:
++touchMovedCount;
break;
default:
@ -1055,15 +1055,15 @@ void tst_QWindow::testInputEvents()
QList<QWindowSystemInterface::TouchPoint> points;
QWindowSystemInterface::TouchPoint tp1, tp2;
tp1.id = 1;
tp1.state = Qt::TouchPointPressed;
tp1.state = QEventPoint::State::Pressed;
tp1.area = QRect(10, 10, 4, 4);
tp2.id = 2;
tp2.state = Qt::TouchPointPressed;
tp2.state = QEventPoint::State::Pressed;
tp2.area = QRect(20, 20, 4, 4);
points << tp1 << tp2;
QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points);
points[0].state = Qt::TouchPointReleased;
points[1].state = Qt::TouchPointReleased;
points[0].state = QEventPoint::State::Released;
points[1].state = QEventPoint::State::Released;
QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points);
QCoreApplication::processEvents();
QTRY_COMPARE(window.touchPressedCount, 2);
@ -1102,24 +1102,24 @@ void tst_QWindow::touchToMouseTranslation()
const QRectF pressArea(101, 102, 4, 4);
const QRectF moveArea(105, 108, 4, 4);
tp1.id = 1;
tp1.state = Qt::TouchPointPressed;
tp1.state = QEventPoint::State::Pressed;
tp1.area = QHighDpi::toNativePixels(pressArea, &window);
tp2.id = 2;
tp2.state = Qt::TouchPointPressed;
tp2.state = QEventPoint::State::Pressed;
points << tp1 << tp2;
QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points);
// Now an update but with changed list order. The mouse event should still
// be generated from the point with id 1.
tp1.id = 2;
tp1.state = Qt::TouchPointStationary;
tp1.state = QEventPoint::State::Stationary;
tp2.id = 1;
tp2.state = Qt::TouchPointMoved;
tp2.state = QEventPoint::State::Updated;
tp2.area = QHighDpi::toNativePixels(moveArea, &window);
points.clear();
points << tp1 << tp2;
QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points);
points[0].state = Qt::TouchPointReleased;
points[1].state = Qt::TouchPointReleased;
points[0].state = QEventPoint::State::Released;
points[1].state = QEventPoint::State::Released;
QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points);
QCoreApplication::processEvents();
@ -1133,11 +1133,11 @@ void tst_QWindow::touchToMouseTranslation()
window.ignoreTouch = false;
points[0].state = Qt::TouchPointPressed;
points[1].state = Qt::TouchPointPressed;
points[0].state = QEventPoint::State::Pressed;
points[1].state = QEventPoint::State::Pressed;
QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points);
points[0].state = Qt::TouchPointReleased;
points[1].state = Qt::TouchPointReleased;
points[0].state = QEventPoint::State::Released;
points[1].state = QEventPoint::State::Released;
QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points);
QCoreApplication::processEvents();
@ -1148,11 +1148,11 @@ void tst_QWindow::touchToMouseTranslation()
QCoreApplication::setAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents, false);
window.ignoreTouch = true;
points[0].state = Qt::TouchPointPressed;
points[1].state = Qt::TouchPointPressed;
points[0].state = QEventPoint::State::Pressed;
points[1].state = QEventPoint::State::Pressed;
QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points);
points[0].state = Qt::TouchPointReleased;
points[1].state = Qt::TouchPointReleased;
points[0].state = QEventPoint::State::Released;
points[1].state = QEventPoint::State::Released;
QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points);
QCoreApplication::processEvents();
@ -1270,7 +1270,7 @@ void tst_QWindow::touchCancel()
tp1.id = 1;
// Start a touch.
tp1.state = Qt::TouchPointPressed;
tp1.state = QEventPoint::State::Pressed;
tp1.area = QRect(10, 10, 4, 4);
points << tp1;
QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points);
@ -1285,7 +1285,7 @@ void tst_QWindow::touchCancel()
// Send a move -> will not be delivered due to the cancellation.
QTRY_COMPARE(window.touchMovedCount, 0);
points[0].state = Qt::TouchPointMoved;
points[0].state = QEventPoint::State::Updated;
tp1.area.adjust(2, 2, 2, 2);
QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points);
QCoreApplication::processEvents();
@ -1293,25 +1293,25 @@ void tst_QWindow::touchCancel()
// Likewise. The only allowed transition is TouchCancel -> TouchBegin.
QTRY_COMPARE(window.touchReleasedCount, 0);
points[0].state = Qt::TouchPointReleased;
points[0].state = QEventPoint::State::Released;
QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points);
QCoreApplication::processEvents();
QTRY_COMPARE(window.touchReleasedCount, 0);
// Start a new sequence -> from this point on everything should go through normally.
points[0].state = Qt::TouchPointPressed;
points[0].state = QEventPoint::State::Pressed;
QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points);
QCoreApplication::processEvents();
QTRY_COMPARE(window.touchEventType, QEvent::TouchBegin);
QTRY_COMPARE(window.touchPressedCount, 2);
points[0].state = Qt::TouchPointMoved;
points[0].state = QEventPoint::State::Updated;
tp1.area.adjust(2, 2, 2, 2);
QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points);
QCoreApplication::processEvents();
QTRY_COMPARE(window.touchMovedCount, 1);
points[0].state = Qt::TouchPointReleased;
points[0].state = QEventPoint::State::Released;
QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points);
QCoreApplication::processEvents();
QTRY_COMPARE(window.touchReleasedCount, 1);
@ -1330,7 +1330,7 @@ void tst_QWindow::touchCancelWithTouchToMouse()
QWindowSystemInterface::TouchPoint tp1;
tp1.id = 1;
tp1.state = Qt::TouchPointPressed;
tp1.state = QEventPoint::State::Pressed;
const QRect area(100, 100, 4, 4);
tp1.area = QHighDpi::toNativePixels(area, &window);
points << tp1;
@ -1379,7 +1379,7 @@ void tst_QWindow::touchInterruptedByPopup()
tp1.id = 1;
// Start a touch.
tp1.state = Qt::TouchPointPressed;
tp1.state = QEventPoint::State::Pressed;
tp1.area = QRect(10, 10, 4, 4);
points << tp1;
QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points);
@ -1399,7 +1399,7 @@ void tst_QWindow::touchInterruptedByPopup()
// Send a move -> will not be delivered to the original window
// (TODO verify where it is forwarded, after we've defined that)
QTRY_COMPARE(window.touchMovedCount, 0);
points[0].state = Qt::TouchPointMoved;
points[0].state = QEventPoint::State::Updated;
tp1.area.adjust(2, 2, 2, 2);
QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points);
QCoreApplication::processEvents();
@ -1407,7 +1407,7 @@ void tst_QWindow::touchInterruptedByPopup()
// Send a touch end -> will not be delivered to the original window
QTRY_COMPARE(window.touchReleasedCount, 0);
points[0].state = Qt::TouchPointReleased;
points[0].state = QEventPoint::State::Released;
QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points);
QCoreApplication::processEvents();
QTRY_COMPARE(window.touchReleasedCount, 0);
@ -1676,14 +1676,14 @@ void tst_QWindow::inputReentrancy()
QList<QWindowSystemInterface::TouchPoint> points;
QWindowSystemInterface::TouchPoint tp1;
tp1.id = 1;
tp1.state = Qt::TouchPointPressed;
tp1.state = QEventPoint::State::Pressed;
tp1.area = QRectF(10, 10, 4, 4);
points << tp1;
QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points);
points[0].state = Qt::TouchPointMoved;
points[0].state = QEventPoint::State::Updated;
points[0].area = QRectF(20, 20, 8, 8);
QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points);
points[0].state = Qt::TouchPointReleased;
points[0].state = QEventPoint::State::Released;
QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points);
QCoreApplication::processEvents();
QCOMPARE(window.touchPressedCount, 1);

View File

@ -33,6 +33,7 @@
#include <private/qgraphicsitem_p.h>
#include <private/qgraphicsview_p.h>
#include <private/qgraphicsscene_p.h>
#include <private/qinputdevice_p.h>
#include <QRandomGenerator>
#include <QStyleOptionGraphicsItem>
#include <QAbstractTextDocumentLayout>
@ -490,7 +491,7 @@ private slots:
private:
GraphicsItems paintedItems;
QPointingDevice *m_touchDevice = nullptr;
QPointingDevice *m_touchDevice = QTest::createTouchDevice();
};
void tst_QGraphicsItem::initMain()
@ -10980,7 +10981,7 @@ void tst_QGraphicsItem::focusHandling()
class TouchEventTestee : public QGraphicsRectItem
{
public:
using TouchPoints = QList<QTouchEvent::TouchPoint>;
using TouchPoints = QList<QEventPoint>;
TouchEventTestee(const QSizeF &size = QSizeF(100, 100)) :
QGraphicsRectItem(QRectF(QPointF(), size))
@ -11019,25 +11020,21 @@ private:
TouchPoints m_touchUpdatePoints;
};
static QList<QTouchEvent::TouchPoint>
static QList<QEventPoint>
createTouchPoints(const QGraphicsView &view,
const QPointF &scenePos,
const QSizeF &ellipseDiameters,
Qt::TouchPointState state = Qt::TouchPointPressed)
QEventPoint::State state = QEventPoint::State::Pressed)
{
QTouchEvent::TouchPoint tp(0);
tp.setState(state);
tp.setScenePos(scenePos);
tp.setStartScenePos(scenePos);
tp.setLastScenePos(scenePos);
const QPointF screenPos = view.viewport()->mapToGlobal(view.mapFromScene(scenePos));
tp.setScreenPos(screenPos);
tp.setStartScreenPos(screenPos);
tp.setLastScreenPos(screenPos);
QMutableEventPoint tp(0, state, scenePos, screenPos);
tp.setState(state);
tp.setScenePosition(scenePos);
tp.setGlobalPosition(screenPos);
tp.setGlobalPressPosition(screenPos);
tp.setGlobalLastPosition(screenPos);
tp.setEllipseDiameters(ellipseDiameters);
const QSizeF screenSize = view.screen()->geometry().size();
tp.setNormalizedPos(QPointF(screenPos.x() / screenSize.width(), screenPos.y() / screenSize.height()));
return QList<QTouchEvent::TouchPoint>() << tp;
return QList<QEventPoint>() << tp;
}
static bool comparePointF(const QPointF &p1, const QPointF &p2)
@ -11104,15 +11101,14 @@ void tst_QGraphicsItem::touchEventPropagation()
view.setSceneRect(touchEventReceiver->boundingRect());
view.show();
QVERIFY(QTest::qWaitForWindowExposed(&view));
QInputDevicePrivate::get(m_touchDevice)->setAvailableVirtualGeometry(view.screen()->geometry());
QCOMPARE(touchEventReceiver->touchBeginEventCount(), 0);
const QPointF scenePos = view.sceneRect().center();
sendMousePress(&scene, scenePos);
if (m_touchDevice == nullptr)
m_touchDevice = QTest::createTouchDevice();
QTouchEvent touchBegin(QEvent::TouchBegin, m_touchDevice, Qt::NoModifier, Qt::TouchPointPressed,
createTouchPoints(view, scenePos, QSizeF(10, 10)));
QMutableTouchEvent touchBegin(QEvent::TouchBegin, m_touchDevice, Qt::NoModifier,
createTouchPoints(view, scenePos, QSizeF(10, 10)));
touchBegin.setTarget(view.viewport());
qApp->sendEvent(&scene, &touchBegin);
@ -11165,39 +11161,36 @@ void tst_QGraphicsItem::touchEventTransformation()
view.setTransform(viewTransform);
view.show();
QVERIFY(QTest::qWaitForWindowExposed(&view));
QInputDevicePrivate::get(m_touchDevice)->setAvailableVirtualGeometry(view.screen()->geometry());
QCOMPARE(touchEventReceiver->touchBeginEventCount(), 0);
if (m_touchDevice == nullptr)
m_touchDevice = QTest::createTouchDevice();
QTouchEvent touchBegin(QEvent::TouchBegin, m_touchDevice, Qt::NoModifier, Qt::TouchPointPressed,
createTouchPoints(view, touchScenePos, ellipseDiameters));
QMutableTouchEvent touchBegin(QEvent::TouchBegin, m_touchDevice, Qt::NoModifier,
createTouchPoints(view, touchScenePos, ellipseDiameters));
touchBegin.setTarget(view.viewport());
QCoreApplication::sendEvent(&scene, &touchBegin);
QCOMPARE(touchEventReceiver->touchBeginEventCount(), 1);
const QTouchEvent::TouchPoint touchBeginPoint = touchEventReceiver->touchBeginPoints().constFirst();
const QEventPoint touchBeginPoint = touchEventReceiver->touchBeginPoints().constFirst();
COMPARE_POINTF(touchBeginPoint.scenePos(), touchScenePos);
COMPARE_POINTF(touchBeginPoint.startScenePos(), touchScenePos);
COMPARE_POINTF(touchBeginPoint.lastScenePos(), touchScenePos);
COMPARE_POINTF(touchBeginPoint.pos(), expectedItemPos);
COMPARE_POINTF(touchBeginPoint.scenePosition(), touchScenePos);
COMPARE_POINTF(touchBeginPoint.scenePressPosition(), touchScenePos);
COMPARE_POINTF(touchBeginPoint.sceneLastPosition(), touchScenePos);
COMPARE_POINTF(touchBeginPoint.position(), expectedItemPos);
COMPARE_SIZEF(touchBeginPoint.ellipseDiameters(), ellipseDiameters); // Must remain untransformed
QTouchEvent touchUpdate(QEvent::TouchUpdate, m_touchDevice, Qt::NoModifier, Qt::TouchPointMoved,
createTouchPoints(view, touchScenePos, ellipseDiameters, Qt::TouchPointMoved));
QMutableTouchEvent touchUpdate(QEvent::TouchUpdate, m_touchDevice, Qt::NoModifier,
createTouchPoints(view, touchScenePos, ellipseDiameters, QEventPoint::State::Updated));
touchUpdate.setTarget(view.viewport());
QCoreApplication::sendEvent(&scene, &touchUpdate);
QCOMPARE(touchEventReceiver->touchUpdateEventCount(), 1);
const QTouchEvent::TouchPoint touchUpdatePoint = touchEventReceiver->touchUpdatePoints().constFirst();
const QEventPoint touchUpdatePoint = touchEventReceiver->touchUpdatePoints().constFirst();
COMPARE_POINTF(touchUpdatePoint.scenePos(), touchScenePos);
COMPARE_POINTF(touchBeginPoint.startScenePos(), touchScenePos);
COMPARE_POINTF(touchUpdatePoint.lastScenePos(), touchScenePos);
COMPARE_POINTF(touchUpdatePoint.pos(), expectedItemPos);
COMPARE_POINTF(touchUpdatePoint.scenePosition(), touchScenePos);
COMPARE_POINTF(touchBeginPoint.scenePressPosition(), touchScenePos);
COMPARE_POINTF(touchUpdatePoint.position(), expectedItemPos);
COMPARE_SIZEF(touchUpdatePoint.ellipseDiameters(), ellipseDiameters); // Must remain untransformed
}

View File

@ -4840,15 +4840,12 @@ void tst_QGraphicsScene::focusOnTouch()
scene.setFocusOnTouch(false);
QPointingDevice device;
device.setType(QInputDevice::DeviceType::TouchPad);
QList<QTouchEvent::TouchPoint> touchPoints;
QTouchEvent::TouchPoint point;
point.setScenePos(QPointF(10, 10));
point.setState(Qt::TouchPointPressed);
touchPoints.append(point);
QTouchEvent event(QEvent::TouchBegin, &device, Qt::NoModifier, Qt::TouchPointStates(),
touchPoints);
QPointingDevice device("fake touchpad", 4321, QInputDevice::DeviceType::TouchPad,
QPointingDevice::PointerType::Finger, QInputDevice::Capability::Position, 1, 3);
auto touchPoints = QList<QEventPoint>() <<
QEventPoint(0, QEventPoint::State::Pressed, {10, 10}, {});
QTouchEvent event(QEvent::TouchBegin, &device, Qt::NoModifier, touchPoints);
QApplication::sendEvent(&scene, &event);

View File

@ -57,6 +57,7 @@
#include <qpa/qwindowsysteminterface.h>
#include <qpa/qwindowsysteminterface_p.h>
#include <private/qevent_p.h>
#include <private/qhighdpiscaling_p.h>
#include <algorithm>
@ -1900,15 +1901,6 @@ void tst_QApplication::touchEventPropagation()
int argc = 1;
QApplication app(argc, &argv0);
QList<QTouchEvent::TouchPoint> pressedTouchPoints;
QTouchEvent::TouchPoint press(0);
press.setState(Qt::TouchPointPressed);
pressedTouchPoints << press;
QList<QTouchEvent::TouchPoint> releasedTouchPoints;
QTouchEvent::TouchPoint release(0);
release.setState(Qt::TouchPointReleased);
releasedTouchPoints << release;
QPointingDevice *device = QTest::createTouchDevice();
@ -1927,8 +1919,10 @@ void tst_QApplication::touchEventPropagation()
// we must ensure there is a screen position in the TouchPoint that maps to a local 0, 0.
const QPoint deviceGlobalPos =
QHighDpi::toNativePixels(window.mapToGlobal(QPoint(0, 0)), window.windowHandle()->screen());
pressedTouchPoints[0].setScreenPos(deviceGlobalPos);
releasedTouchPoints[0].setScreenPos(deviceGlobalPos);
auto pressedTouchPoints = QList<QEventPoint>() <<
QEventPoint(0, QEventPoint::State::Pressed, QPointF(), deviceGlobalPos);
auto releasedTouchPoints = QList<QEventPoint>() <<
QEventPoint(0, QEventPoint::State::Released, QPointF(), deviceGlobalPos);
QWindowSystemInterface::handleTouchEvent(handle,
0,
@ -1985,8 +1979,10 @@ void tst_QApplication::touchEventPropagation()
QVERIFY(QTest::qWaitForWindowExposed(&window));
const QPoint deviceGlobalPos =
QHighDpi::toNativePixels(window.mapToGlobal(QPoint(50, 150)), window.windowHandle()->screen());
pressedTouchPoints[0].setScreenPos(deviceGlobalPos);
releasedTouchPoints[0].setScreenPos(deviceGlobalPos);
auto pressedTouchPoints = QList<QEventPoint>() <<
QEventPoint(0, QEventPoint::State::Pressed, QPointF(), deviceGlobalPos);
auto releasedTouchPoints = QList<QEventPoint>() <<
QEventPoint(0, QEventPoint::State::Released, QPointF(), deviceGlobalPos);
QWindowSystemInterface::handleTouchEvent(handle,
0,

View File

@ -29,6 +29,7 @@
#include <QtGui>
#include <QtWidgets>
#include <QtTest>
#include <QtGui/private/qevent_p.h>
#include <qpa/qwindowsysteminterface.h>
// #include <QDebug>
@ -145,34 +146,32 @@ void tst_QScroller::kineticScroll(tst_QScrollerWidget *sw, QPointF from, QPoint
QScrollerProperties sp1 = QScroller::scroller(sw)->scrollerProperties();
QTouchEvent::TouchPoint rawTouchPoint;
rawTouchPoint.setId(0);
// send the touch begin event
QTouchEvent::TouchPoint touchPoint(0);
touchPoint.setState(Qt::TouchPointPressed);
touchPoint.setPos(touchStart);
touchPoint.setScenePos(touchStart);
touchPoint.setScreenPos(touchStart);
QMutableEventPoint touchPoint(0);
touchPoint.setState(QEventPoint::State::Pressed);
touchPoint.setPosition(touchStart);
touchPoint.setScenePosition(touchStart);
touchPoint.setGlobalPosition(touchStart);
QTouchEvent touchEvent1(QEvent::TouchBegin,
m_touchScreen,
Qt::NoModifier,
Qt::TouchPointPressed,
(QList<QTouchEvent::TouchPoint>() << touchPoint));
QApplication::sendEvent(sw, &touchEvent1);
QCOMPARE(s1->state(), QScroller::Pressed);
// send the touch update far enough to trigger a scroll
QTest::qWait(200); // we need to wait a little or else the speed would be infinite. now we have around 500 pixel per second.
touchPoint.setPos(touchUpdate);
touchPoint.setScenePos(touchUpdate);
touchPoint.setScreenPos(touchUpdate);
touchPoint.setPosition(touchUpdate);
touchPoint.setScenePosition(touchUpdate);
touchPoint.setGlobalPosition(touchUpdate);
touchPoint.setState(QEventPoint::State::Updated);
QTouchEvent touchEvent2(QEvent::TouchUpdate,
m_touchScreen,
Qt::NoModifier,
Qt::TouchPointMoved,
(QList<QTouchEvent::TouchPoint>() << touchPoint));
(QList<QEventPoint>() << touchPoint));
QApplication::sendEvent(sw, &touchEvent2);
QCOMPARE(s1->state(), QScroller::Dragging);
@ -189,14 +188,14 @@ void tst_QScroller::kineticScroll(tst_QScrollerWidget *sw, QPointF from, QPoint
QVERIFY(qAbs(sw->currentPos.y() - calculatedPos.y()) < 1.0);
// send the touch end
touchPoint.setPos(touchEnd);
touchPoint.setScenePos(touchEnd);
touchPoint.setScreenPos(touchEnd);
touchPoint.setPosition(touchEnd);
touchPoint.setScenePosition(touchEnd);
touchPoint.setGlobalPosition(touchEnd);
touchPoint.setState(QEventPoint::State::Released);
QTouchEvent touchEvent5(QEvent::TouchEnd,
m_touchScreen,
Qt::NoModifier,
Qt::TouchPointReleased,
(QList<QTouchEvent::TouchPoint>() << touchPoint));
(QList<QEventPoint>() << touchPoint));
QApplication::sendEvent(sw, &touchEvent5);
}
@ -215,45 +214,41 @@ void tst_QScroller::kineticScrollNoTest(tst_QScrollerWidget *sw, QPointF from, Q
QScrollerProperties sp1 = s1->scrollerProperties();
int fps = 60;
QTouchEvent::TouchPoint rawTouchPoint;
rawTouchPoint.setId(0);
// send the touch begin event
QTouchEvent::TouchPoint touchPoint(0);
touchPoint.setState(Qt::TouchPointPressed);
touchPoint.setPos(touchStart);
touchPoint.setScenePos(touchStart);
touchPoint.setScreenPos(touchStart);
QMutableEventPoint touchPoint(0);
touchPoint.setState(QEventPoint::State::Pressed);
touchPoint.setPosition(touchStart);
touchPoint.setScenePosition(touchStart);
touchPoint.setGlobalPosition(touchStart);
QTouchEvent touchEvent1(QEvent::TouchBegin,
m_touchScreen,
Qt::NoModifier,
Qt::TouchPointPressed,
(QList<QTouchEvent::TouchPoint>() << touchPoint));
(QList<QEventPoint>() << touchPoint));
QApplication::sendEvent(sw, &touchEvent1);
// send the touch update far enough to trigger a scroll
QTest::qWait(200); // we need to wait a little or else the speed would be infinite. now we have around 500 pixel per second.
touchPoint.setPos(touchUpdate);
touchPoint.setScenePos(touchUpdate);
touchPoint.setScreenPos(touchUpdate);
touchPoint.setState(QEventPoint::State::Updated);
touchPoint.setPosition(touchUpdate);
touchPoint.setScenePosition(touchUpdate);
touchPoint.setGlobalPosition(touchUpdate);
QTouchEvent touchEvent2(QEvent::TouchUpdate,
m_touchScreen,
Qt::NoModifier,
Qt::TouchPointMoved,
(QList<QTouchEvent::TouchPoint>() << touchPoint));
(QList<QEventPoint>() << touchPoint));
QApplication::sendEvent(sw, &touchEvent2);
QTest::qWait(1000 / fps * 2); // wait until the first scroll move
// send the touch end
touchPoint.setPos(touchEnd);
touchPoint.setScenePos(touchEnd);
touchPoint.setScreenPos(touchEnd);
touchPoint.setState(QEventPoint::State::Released);
touchPoint.setPosition(touchEnd);
touchPoint.setScenePosition(touchEnd);
touchPoint.setGlobalPosition(touchEnd);
QTouchEvent touchEvent5(QEvent::TouchEnd,
m_touchScreen,
Qt::NoModifier,
Qt::TouchPointReleased,
(QList<QTouchEvent::TouchPoint>() << touchPoint));
(QList<QEventPoint>() << touchPoint));
QApplication::sendEvent(sw, &touchEvent5);
}

View File

@ -68,7 +68,7 @@ protected:
case QEvent::TouchEnd:
{
QTouchEvent *te = static_cast<QTouchEvent *>(e);
for (const QTouchEvent::TouchPoint &tp : te->touchPoints()) {
for (const QEventPoint &tp : te->touchPoints()) {
QGraphicsEllipseItem *diameterItem = nullptr;
QSizeF ellipse = tp.ellipseDiameters();
if (ellipse.isNull()) {
@ -121,8 +121,6 @@ int main(int argc, char **argv)
str << " Pressure";
if (capabilities & QPointingDevice::Velocity)
str << " Velocity";
if (capabilities & QPointingDevice::RawPositions)
str << " RawPositions";
if (capabilities & QPointingDevice::Capability::NormalizedPosition)
str << " NormalizedPosition";
if (capabilities & QInputDevice::DeviceType::MouseEmulation)