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 "qcursor.h"
#include "private/qguiapplication_p.h"
#include "private/qtouchdevice_p.h"
#include "qpa/qplatformintegration.h"
#include "qpa/qplatformdrag.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.
*/
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)
: QInputEvent(QEvent::NativeGesture), mGestureType(type),
mTouchDeviceId(QTouchDevicePrivate::get(const_cast<QTouchDevice *>(dev))->id),
mLocalPos(localPos), mWindowPos(windowPos), mScreenPos(screenPos), mRealValue(realValue),
mSequenceId(sequenceId), mIntValue(intValue)
{ }
const QTouchDevice *QNativeGestureEvent::device() const
{
return QTouchDevicePrivate::deviceById(mTouchDeviceId);
}
/*!
\fn QNativeGestureEvent::gestureType() const
\since 5.2

View File

@ -301,7 +301,7 @@ protected:
class Q_GUI_EXPORT QNativeGestureEvent : public QInputEvent
{
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);
Qt::NativeGestureType gestureType() const { return mGestureType; }
qreal value() const { return mRealValue; }
@ -314,8 +314,12 @@ public:
const QPointF &windowPos() const { return mWindowPos; }
const QPointF &screenPos() const { return mScreenPos; }
const QTouchDevice *device() const;
protected:
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 mWindowPos;
QPointF mScreenPos;

View File

@ -2420,7 +2420,7 @@ void QGuiApplicationPrivate::processGestureEvent(QWindowSystemInterfacePrivate::
if (e->window.isNull())
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);
QGuiApplication::sendSpontaneousEvent(e->window, &ev);
}

View File

@ -235,6 +235,15 @@ bool QTouchDevicePrivate::isRegistered(const QTouchDevice *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
*/

View File

@ -78,6 +78,7 @@ public:
static void registerDevice(const QTouchDevice *dev);
static void unregisterDevice(const QTouchDevice *dev);
static bool isRegistered(const QTouchDevice *dev);
static const QTouchDevice *deviceById(quint8 id);
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
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)
{
QWindowSystemInterfacePrivate::GestureEvent *e =
new QWindowSystemInterfacePrivate::GestureEvent(window, timestamp, type, local, global);
new QWindowSystemInterfacePrivate::GestureEvent(window, timestamp, type, device, local, global);
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)
{
QWindowSystemInterfacePrivate::GestureEvent *e =
new QWindowSystemInterfacePrivate::GestureEvent(window, timestamp, type, local, global);
new QWindowSystemInterfacePrivate::GestureEvent(window, timestamp, type, device, local, global);
e->realValue = value;
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)
{
QWindowSystemInterfacePrivate::GestureEvent *e =
new QWindowSystemInterfacePrivate::GestureEvent(window, timestamp, type, local, global);
new QWindowSystemInterfacePrivate::GestureEvent(window, timestamp, type, device, local, global);
e->sequenceId = sequenceId;
e->intValue = value;
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);

View File

@ -225,11 +225,11 @@ public:
static void handleTabletLeaveProximityEvent(int device, int pointerType, qint64 uid);
#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);
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);
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);
#endif // QT_NO_GESTURES

View File

@ -421,9 +421,9 @@ public:
#ifndef QT_NO_GESTURES
class GestureEvent : public InputEvent {
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),
realValue(0), sequenceId(0), intValue(0) { }
realValue(0), sequenceId(0), intValue(0), device(dev) { }
Qt::NativeGestureType type;
QPointF pos;
QPointF globalPos;
@ -432,6 +432,7 @@ public:
// Windows
ulong sequenceId;
quint64 intValue;
QTouchDevice *device;
};
#endif

View File

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