make the QTouchDevice available in each QNativeGestureEvent

QtQuick is beginning to have a use for this, to distinguish native
gestures which come from actual trackpad rather than from the "core pointer".
It might as well use a real device ID instead of making one up,
as it has to do for the core pointer.

So far on macOS, the device ID isn't a real one; but that can be fixed,
as the qCDebug lines demonstrate (different trackpads have different IDs).

Change-Id: I5841deb1c4cc0b77a3b1df70904f70b3d2d71853
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
This commit is contained in:
Shawn Rutledge 2017-09-12 16:39:56 +02:00
parent be0a9a7688
commit 83729ad7a1
9 changed files with 47 additions and 25 deletions

View File

@ -40,6 +40,7 @@
#include "qevent.h" #include "qevent.h"
#include "qcursor.h" #include "qcursor.h"
#include "private/qguiapplication_p.h" #include "private/qguiapplication_p.h"
#include "private/qtouchdevice_p.h"
#include "qpa/qplatformintegration.h" #include "qpa/qplatformintegration.h"
#include "qpa/qplatformdrag.h" #include "qpa/qplatformdrag.h"
#include "private/qevent_p.h" #include "private/qevent_p.h"
@ -2765,13 +2766,19 @@ Qt::MouseButtons QTabletEvent::buttons() const
\a realValue is the \macos event parameter, \a sequenceId and \a intValue are the Windows event parameters. \a realValue is the \macos event parameter, \a sequenceId and \a intValue are the Windows event parameters.
*/ */
QNativeGestureEvent::QNativeGestureEvent(Qt::NativeGestureType type, const QPointF &localPos, const QPointF &windowPos, QNativeGestureEvent::QNativeGestureEvent(Qt::NativeGestureType type, const QTouchDevice *dev, const QPointF &localPos, const QPointF &windowPos,
const QPointF &screenPos, qreal realValue, ulong sequenceId, quint64 intValue) const QPointF &screenPos, qreal realValue, ulong sequenceId, quint64 intValue)
: QInputEvent(QEvent::NativeGesture), mGestureType(type), : QInputEvent(QEvent::NativeGesture), mGestureType(type),
mTouchDeviceId(QTouchDevicePrivate::get(const_cast<QTouchDevice *>(dev))->id),
mLocalPos(localPos), mWindowPos(windowPos), mScreenPos(screenPos), mRealValue(realValue), mLocalPos(localPos), mWindowPos(windowPos), mScreenPos(screenPos), mRealValue(realValue),
mSequenceId(sequenceId), mIntValue(intValue) mSequenceId(sequenceId), mIntValue(intValue)
{ } { }
const QTouchDevice *QNativeGestureEvent::device() const
{
return QTouchDevicePrivate::deviceById(mTouchDeviceId);
}
/*! /*!
\fn QNativeGestureEvent::gestureType() const \fn QNativeGestureEvent::gestureType() const
\since 5.2 \since 5.2

View File

@ -301,7 +301,7 @@ protected:
class Q_GUI_EXPORT QNativeGestureEvent : public QInputEvent class Q_GUI_EXPORT QNativeGestureEvent : public QInputEvent
{ {
public: public:
QNativeGestureEvent(Qt::NativeGestureType type, const QPointF &localPos, const QPointF &windowPos, QNativeGestureEvent(Qt::NativeGestureType type, const QTouchDevice *dev, const QPointF &localPos, const QPointF &windowPos,
const QPointF &screenPos, qreal value, ulong sequenceId, quint64 intArgument); const QPointF &screenPos, qreal value, ulong sequenceId, quint64 intArgument);
Qt::NativeGestureType gestureType() const { return mGestureType; } Qt::NativeGestureType gestureType() const { return mGestureType; }
qreal value() const { return mRealValue; } qreal value() const { return mRealValue; }
@ -314,8 +314,12 @@ public:
const QPointF &windowPos() const { return mWindowPos; } const QPointF &windowPos() const { return mWindowPos; }
const QPointF &screenPos() const { return mScreenPos; } const QPointF &screenPos() const { return mScreenPos; }
const QTouchDevice *device() const;
protected: protected:
Qt::NativeGestureType mGestureType; Qt::NativeGestureType mGestureType;
quint8 mTouchDeviceId; // QTouchDevicePrivate::id
quint8 mReserved[3]; // if qreal == double clang will pad the QPointF below to a 8-byte boundary
QPointF mLocalPos; QPointF mLocalPos;
QPointF mWindowPos; QPointF mWindowPos;
QPointF mScreenPos; QPointF mScreenPos;

View File

@ -2420,7 +2420,7 @@ void QGuiApplicationPrivate::processGestureEvent(QWindowSystemInterfacePrivate::
if (e->window.isNull()) if (e->window.isNull())
return; return;
QNativeGestureEvent ev(e->type, e->pos, e->pos, e->globalPos, e->realValue, e->sequenceId, e->intValue); QNativeGestureEvent ev(e->type, e->device, e->pos, e->pos, e->globalPos, e->realValue, e->sequenceId, e->intValue);
ev.setTimestamp(e->timestamp); ev.setTimestamp(e->timestamp);
QGuiApplication::sendSpontaneousEvent(e->window, &ev); QGuiApplication::sendSpontaneousEvent(e->window, &ev);
} }

View File

@ -235,6 +235,15 @@ bool QTouchDevicePrivate::isRegistered(const QTouchDevice *dev)
return deviceList()->contains(dev); return deviceList()->contains(dev);
} }
const QTouchDevice *QTouchDevicePrivate::deviceById(quint8 id)
{
QMutexLocker locker(&devicesMutex);
for (const QTouchDevice *dev : *deviceList())
if (QTouchDevicePrivate::get(const_cast<QTouchDevice *>(dev))->id == id)
return dev;
return nullptr;
}
/*! /*!
\internal \internal
*/ */

View File

@ -78,6 +78,7 @@ public:
static void registerDevice(const QTouchDevice *dev); static void registerDevice(const QTouchDevice *dev);
static void unregisterDevice(const QTouchDevice *dev); static void unregisterDevice(const QTouchDevice *dev);
static bool isRegistered(const QTouchDevice *dev); static bool isRegistered(const QTouchDevice *dev);
static const QTouchDevice *deviceById(quint8 id);
static QTouchDevicePrivate *get(QTouchDevice *q) { return q->d; } static QTouchDevicePrivate *get(QTouchDevice *q) { return q->d; }
}; };

View File

@ -850,28 +850,28 @@ void QWindowSystemInterface::handleTabletLeaveProximityEvent(int device, int poi
} }
#ifndef QT_NO_GESTURES #ifndef QT_NO_GESTURES
void QWindowSystemInterface::handleGestureEvent(QWindow *window, ulong timestamp, Qt::NativeGestureType type, void QWindowSystemInterface::handleGestureEvent(QWindow *window, QTouchDevice *device, ulong timestamp, Qt::NativeGestureType type,
QPointF &local, QPointF &global) QPointF &local, QPointF &global)
{ {
QWindowSystemInterfacePrivate::GestureEvent *e = QWindowSystemInterfacePrivate::GestureEvent *e =
new QWindowSystemInterfacePrivate::GestureEvent(window, timestamp, type, local, global); new QWindowSystemInterfacePrivate::GestureEvent(window, timestamp, type, device, local, global);
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
} }
void QWindowSystemInterface::handleGestureEventWithRealValue(QWindow *window, ulong timestamp, Qt::NativeGestureType type, void QWindowSystemInterface::handleGestureEventWithRealValue(QWindow *window, QTouchDevice *device, ulong timestamp, Qt::NativeGestureType type,
qreal value, QPointF &local, QPointF &global) qreal value, QPointF &local, QPointF &global)
{ {
QWindowSystemInterfacePrivate::GestureEvent *e = QWindowSystemInterfacePrivate::GestureEvent *e =
new QWindowSystemInterfacePrivate::GestureEvent(window, timestamp, type, local, global); new QWindowSystemInterfacePrivate::GestureEvent(window, timestamp, type, device, local, global);
e->realValue = value; e->realValue = value;
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
} }
void QWindowSystemInterface::handleGestureEventWithSequenceIdAndValue(QWindow *window, ulong timestamp, Qt::NativeGestureType type, void QWindowSystemInterface::handleGestureEventWithSequenceIdAndValue(QWindow *window, QTouchDevice *device, ulong timestamp, Qt::NativeGestureType type,
ulong sequenceId, quint64 value, QPointF &local, QPointF &global) ulong sequenceId, quint64 value, QPointF &local, QPointF &global)
{ {
QWindowSystemInterfacePrivate::GestureEvent *e = QWindowSystemInterfacePrivate::GestureEvent *e =
new QWindowSystemInterfacePrivate::GestureEvent(window, timestamp, type, local, global); new QWindowSystemInterfacePrivate::GestureEvent(window, timestamp, type, device, local, global);
e->sequenceId = sequenceId; e->sequenceId = sequenceId;
e->intValue = value; e->intValue = value;
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);

View File

@ -225,11 +225,11 @@ public:
static void handleTabletLeaveProximityEvent(int device, int pointerType, qint64 uid); static void handleTabletLeaveProximityEvent(int device, int pointerType, qint64 uid);
#ifndef QT_NO_GESTURES #ifndef QT_NO_GESTURES
static void handleGestureEvent(QWindow *window, ulong timestamp, Qt::NativeGestureType type, static void handleGestureEvent(QWindow *window, QTouchDevice *device, ulong timestamp, Qt::NativeGestureType type,
QPointF &local, QPointF &global); QPointF &local, QPointF &global);
static void handleGestureEventWithRealValue(QWindow *window, ulong timestamp, Qt::NativeGestureType type, static void handleGestureEventWithRealValue(QWindow *window, QTouchDevice *device, ulong timestamp, Qt::NativeGestureType type,
qreal value, QPointF &local, QPointF &global); qreal value, QPointF &local, QPointF &global);
static void handleGestureEventWithSequenceIdAndValue(QWindow *window, ulong timestamp,Qt::NativeGestureType type, static void handleGestureEventWithSequenceIdAndValue(QWindow *window, QTouchDevice *device, ulong timestamp,Qt::NativeGestureType type,
ulong sequenceId, quint64 value, QPointF &local, QPointF &global); ulong sequenceId, quint64 value, QPointF &local, QPointF &global);
#endif // QT_NO_GESTURES #endif // QT_NO_GESTURES

View File

@ -421,9 +421,9 @@ public:
#ifndef QT_NO_GESTURES #ifndef QT_NO_GESTURES
class GestureEvent : public InputEvent { class GestureEvent : public InputEvent {
public: public:
GestureEvent(QWindow *window, ulong time, Qt::NativeGestureType type, QPointF pos, QPointF globalPos) GestureEvent(QWindow *window, ulong time, Qt::NativeGestureType type, QTouchDevice *dev, QPointF pos, QPointF globalPos)
: InputEvent(window, time, Gesture, Qt::NoModifier), type(type), pos(pos), globalPos(globalPos), : InputEvent(window, time, Gesture, Qt::NoModifier), type(type), pos(pos), globalPos(globalPos),
realValue(0), sequenceId(0), intValue(0) { } realValue(0), sequenceId(0), intValue(0), device(dev) { }
Qt::NativeGestureType type; Qt::NativeGestureType type;
QPointF pos; QPointF pos;
QPointF globalPos; QPointF globalPos;
@ -432,6 +432,7 @@ public:
// Windows // Windows
ulong sequenceId; ulong sequenceId;
quint64 intValue; quint64 intValue;
QTouchDevice *device;
}; };
#endif #endif

View File

@ -1129,12 +1129,12 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
if ([self handleGestureAsBeginEnd:event]) if ([self handleGestureAsBeginEnd:event])
return; return;
qCDebug(lcQpaGestures) << "magnifyWithEvent" << [event magnification]; qCDebug(lcQpaGestures) << "magnifyWithEvent" << [event magnification] << "from device" << hex << [event deviceID];
const NSTimeInterval timestamp = [event timestamp]; const NSTimeInterval timestamp = [event timestamp];
QPointF windowPoint; QPointF windowPoint;
QPointF screenPoint; QPointF screenPoint;
[self convertFromScreen:[self screenMousePoint:event] toWindowPoint:&windowPoint andScreenPoint:&screenPoint]; [self convertFromScreen:[self screenMousePoint:event] toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
QWindowSystemInterface::handleGestureEventWithRealValue(m_platformWindow->window(), timestamp, Qt::ZoomNativeGesture, QWindowSystemInterface::handleGestureEventWithRealValue(m_platformWindow->window(), touchDevice, timestamp, Qt::ZoomNativeGesture,
[event magnification], windowPoint, screenPoint); [event magnification], windowPoint, screenPoint);
} }
@ -1144,12 +1144,12 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
return; return;
static bool zoomIn = true; static bool zoomIn = true;
qCDebug(lcQpaGestures) << "smartMagnifyWithEvent" << zoomIn; qCDebug(lcQpaGestures) << "smartMagnifyWithEvent" << zoomIn << "from device" << hex << [event deviceID];
const NSTimeInterval timestamp = [event timestamp]; const NSTimeInterval timestamp = [event timestamp];
QPointF windowPoint; QPointF windowPoint;
QPointF screenPoint; QPointF screenPoint;
[self convertFromScreen:[self screenMousePoint:event] toWindowPoint:&windowPoint andScreenPoint:&screenPoint]; [self convertFromScreen:[self screenMousePoint:event] toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
QWindowSystemInterface::handleGestureEventWithRealValue(m_platformWindow->window(), timestamp, Qt::SmartZoomNativeGesture, QWindowSystemInterface::handleGestureEventWithRealValue(m_platformWindow->window(), touchDevice, timestamp, Qt::SmartZoomNativeGesture,
zoomIn ? 1.0f : 0.0f, windowPoint, screenPoint); zoomIn ? 1.0f : 0.0f, windowPoint, screenPoint);
zoomIn = !zoomIn; zoomIn = !zoomIn;
} }
@ -1166,7 +1166,7 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
QPointF windowPoint; QPointF windowPoint;
QPointF screenPoint; QPointF screenPoint;
[self convertFromScreen:[self screenMousePoint:event] toWindowPoint:&windowPoint andScreenPoint:&screenPoint]; [self convertFromScreen:[self screenMousePoint:event] toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
QWindowSystemInterface::handleGestureEventWithRealValue(m_platformWindow->window(), timestamp, Qt::RotateNativeGesture, QWindowSystemInterface::handleGestureEventWithRealValue(m_platformWindow->window(), touchDevice, timestamp, Qt::RotateNativeGesture,
-[event rotation], windowPoint, screenPoint); -[event rotation], windowPoint, screenPoint);
} }
@ -1175,7 +1175,7 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
if (!m_platformWindow) if (!m_platformWindow)
return; return;
qCDebug(lcQpaGestures) << "swipeWithEvent" << [event deltaX] << [event deltaY]; qCDebug(lcQpaGestures) << "swipeWithEvent" << [event deltaX] << [event deltaY] << "from device" << hex << [event deviceID];
const NSTimeInterval timestamp = [event timestamp]; const NSTimeInterval timestamp = [event timestamp];
QPointF windowPoint; QPointF windowPoint;
QPointF screenPoint; QPointF screenPoint;
@ -1191,7 +1191,7 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
else if ([event deltaY] == -1) else if ([event deltaY] == -1)
angle = 270.0f; angle = 270.0f;
QWindowSystemInterface::handleGestureEventWithRealValue(m_platformWindow->window(), timestamp, Qt::SwipeNativeGesture, QWindowSystemInterface::handleGestureEventWithRealValue(m_platformWindow->window(), touchDevice, timestamp, Qt::SwipeNativeGesture,
angle, windowPoint, screenPoint); angle, windowPoint, screenPoint);
} }
@ -1204,8 +1204,8 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
QPointF windowPoint; QPointF windowPoint;
QPointF screenPoint; QPointF screenPoint;
[self convertFromScreen:[self screenMousePoint:event] toWindowPoint:&windowPoint andScreenPoint:&screenPoint]; [self convertFromScreen:[self screenMousePoint:event] toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
qCDebug(lcQpaGestures) << "beginGestureWithEvent @" << windowPoint; qCDebug(lcQpaGestures) << "beginGestureWithEvent @" << windowPoint << "from device" << hex << [event deviceID];
QWindowSystemInterface::handleGestureEvent(m_platformWindow->window(), timestamp, Qt::BeginNativeGesture, QWindowSystemInterface::handleGestureEvent(m_platformWindow->window(), touchDevice, timestamp, Qt::BeginNativeGesture,
windowPoint, screenPoint); windowPoint, screenPoint);
} }
@ -1214,12 +1214,12 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
if (!m_platformWindow) if (!m_platformWindow)
return; return;
qCDebug(lcQpaGestures) << "endGestureWithEvent"; qCDebug(lcQpaGestures) << "endGestureWithEvent" << "from device" << hex << [event deviceID];
const NSTimeInterval timestamp = [event timestamp]; const NSTimeInterval timestamp = [event timestamp];
QPointF windowPoint; QPointF windowPoint;
QPointF screenPoint; QPointF screenPoint;
[self convertFromScreen:[self screenMousePoint:event] toWindowPoint:&windowPoint andScreenPoint:&screenPoint]; [self convertFromScreen:[self screenMousePoint:event] toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
QWindowSystemInterface::handleGestureEvent(m_platformWindow->window(), timestamp, Qt::EndNativeGesture, QWindowSystemInterface::handleGestureEvent(m_platformWindow->window(), touchDevice, timestamp, Qt::EndNativeGesture,
windowPoint, screenPoint); windowPoint, screenPoint);
} }
#endif // QT_NO_GESTURES #endif // QT_NO_GESTURES