Add QPointingDevice argument to every QWSI input event handler function

We want every QInputEvent to carry a valid device pointer. It may be
some time until all QPA plugins are sending it, but it's necessary to
provide the functions for them to start doing that.

We now try to maintain the same order of arguments to all the functions.
handleTouchEvent(window, timestamp, device, the rest) was already there
(except "device" has changed type now), and is used in a lot of platform
plugins; so it seems easiest to let that set the precedent, and modify
the rest to match. We do that by adding new functions; we can deprecate
the older functions after it becomes clear that the new ones work well.

However the handleGestureEvent functions have only ever been used in
the cocoa plugin, so it's easy to change their argument order right now.

Modify tst_qwindow::tabletEvents() to test new tablet event API.

Task-number: QTBUG-46412
Change-Id: I1828b61183cf51f3a08774936156c6a91cfc9a12
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
This commit is contained in:
Shawn Rutledge 2020-06-10 15:32:26 +02:00
parent 68de38ded1
commit 28ef8d283d
7 changed files with 244 additions and 117 deletions

View File

@ -2606,7 +2606,8 @@ QGuiApplicationPrivate::TabletPointData &QGuiApplicationPrivate::tabletDevicePoi
void QGuiApplicationPrivate::processTabletEvent(QWindowSystemInterfacePrivate::TabletEvent *e)
{
#if QT_CONFIG(tabletevent)
TabletPointData &pointData = tabletDevicePoint(e->uid);
const auto device = static_cast<const QPointingDevice *>(e->device);
TabletPointData &pointData = tabletDevicePoint(device->uniqueId().numericId());
QEvent::Type type = QEvent::TabletMove;
if (e->buttons != pointData.state)
@ -2642,6 +2643,8 @@ void QGuiApplicationPrivate::processTabletEvent(QWindowSystemInterfacePrivate::T
QPointF delta = e->global - e->global.toPoint();
local = window->mapFromGlobal(e->global.toPoint()) + delta;
}
// TODO stop deducing the button state change here: rather require it from the platform plugin, as with mouse events
Qt::MouseButtons stateChange = e->buttons ^ pointData.state;
Qt::MouseButton button = Qt::NoButton;
for (int check = Qt::LeftButton; check <= int(Qt::MaxMouseButton); check = check << 1) {
@ -2650,10 +2653,11 @@ void QGuiApplicationPrivate::processTabletEvent(QWindowSystemInterfacePrivate::T
break;
}
}
QTabletEvent tabletEvent(type, local, e->global,
e->device, e->pointerType, e->pressure, e->xTilt, e->yTilt,
QTabletEvent tabletEvent(type, device, local, e->global,
e->pressure, e->xTilt, e->yTilt,
e->tangentialPressure, e->rotation, e->z,
e->modifiers, e->uid, button, e->buttons);
e->modifiers, button, e->buttons);
tabletEvent.setAccepted(false);
tabletEvent.setTimestamp(e->timestamp);
QGuiApplication::sendSpontaneousEvent(window, &tabletEvent);
@ -2683,10 +2687,10 @@ void QGuiApplicationPrivate::processTabletEvent(QWindowSystemInterfacePrivate::T
void QGuiApplicationPrivate::processTabletEnterProximityEvent(QWindowSystemInterfacePrivate::TabletEnterProximityEvent *e)
{
#if QT_CONFIG(tabletevent)
QTabletEvent ev(QEvent::TabletEnterProximity, QPointF(), QPointF(),
e->device, e->pointerType, 0, 0, 0,
0, 0, 0,
Qt::NoModifier, e->uid, Qt::NoButton, tabletDevicePoint(e->uid).state);
const QPointingDevice *dev = static_cast<const QPointingDevice *>(e->device);
QTabletEvent ev(QEvent::TabletEnterProximity, dev, QPointF(), QPointF(),
0, 0, 0, 0, 0, 0, e->modifiers, Qt::NoButton,
tabletDevicePoint(dev->uniqueId().numericId()).state);
ev.setTimestamp(e->timestamp);
QGuiApplication::sendSpontaneousEvent(qGuiApp, &ev);
#else
@ -2697,10 +2701,10 @@ void QGuiApplicationPrivate::processTabletEnterProximityEvent(QWindowSystemInter
void QGuiApplicationPrivate::processTabletLeaveProximityEvent(QWindowSystemInterfacePrivate::TabletLeaveProximityEvent *e)
{
#if QT_CONFIG(tabletevent)
QTabletEvent ev(QEvent::TabletLeaveProximity, QPointF(), QPointF(),
e->device, e->pointerType, 0, 0, 0,
0, 0, 0,
Qt::NoModifier, e->uid, Qt::NoButton, tabletDevicePoint(e->uid).state);
const QPointingDevice *dev = static_cast<const QPointingDevice *>(e->device);
QTabletEvent ev(QEvent::TabletLeaveProximity, dev, QPointF(), QPointF(),
0, 0, 0, 0, 0, 0, e->modifiers, Qt::NoButton,
tabletDevicePoint(dev->uniqueId().numericId()).state);
ev.setTimestamp(e->timestamp);
QGuiApplication::sendSpontaneousEvent(qGuiApp, &ev);
#else
@ -2767,7 +2771,7 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To
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, e->device, e->modifiers);
QTouchEvent touchEvent(QEvent::TouchCancel, static_cast<const QPointingDevice *>(e->device), e->modifiers);
touchEvent.setTimestamp(e->timestamp);
QHash<ActiveTouchPointsKey, ActiveTouchPointsValue>::const_iterator it
= self->activeTouchPoints.constBegin(), ite = self->activeTouchPoints.constEnd();
@ -2828,7 +2832,7 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To
// update state
QPointer<QWindow> w;
QTouchEvent::TouchPoint previousTouchPoint;
ActiveTouchPointsKey touchInfoKey(e->device, touchPoint.id());
ActiveTouchPointsKey touchInfoKey(static_cast<const QPointingDevice *>(e->device), touchPoint.id());
ActiveTouchPointsValue &touchInfo = d->activeTouchPoints[touchInfoKey];
switch (touchPoint.state()) {
case Qt::TouchPointPressed:
@ -2959,7 +2963,7 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To
// but don't leave dangling state: e.g.
// QQuickWindowPrivate::itemForTouchPointId needs to be cleared.
QTouchEvent touchEvent(QEvent::TouchCancel,
e->device,
static_cast<const QPointingDevice *>(e->device),
e->modifiers);
touchEvent.setTimestamp(e->timestamp);
touchEvent.setWindow(w);
@ -2969,7 +2973,7 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To
}
QTouchEvent touchEvent(eventType,
e->device,
static_cast<const QPointingDevice *>(e->device),
e->modifiers,
it.value().first, // state flags
it.value().second); // list of touchpoints
@ -3050,7 +3054,7 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To
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(e->device, touchPoint.id()));
d->activeTouchPoints.remove(ActiveTouchPointsKey(static_cast<const QPointingDevice *>(e->device), touchPoint.id()));
}
}

View File

@ -237,6 +237,7 @@ public:
static bool highDpiScalingUpdated;
static QPointer<QWindow> currentDragWindow;
// TODO remove this: QPointingDevice can store what we need directly
struct TabletPointData {
TabletPointData(qint64 devId = 0) : deviceId(devId), state(Qt::NoButton), target(nullptr) {}
qint64 deviceId;

View File

@ -382,6 +382,15 @@ QT_DEFINE_QPA_EVENT_HANDLER(bool, handleMouseEvent, QWindow *window, ulong times
const QPointF &local, const QPointF &global, Qt::MouseButtons state,
Qt::MouseButton button, QEvent::Type type, Qt::KeyboardModifiers mods,
Qt::MouseEventSource source)
{
return handleMouseEvent<Delivery>(window, timestamp, QPointingDevice::primaryPointingDevice(),
local, global, state, button, type, mods, source);
}
QT_DEFINE_QPA_EVENT_HANDLER(bool, handleMouseEvent, QWindow *window, ulong timestamp, const QPointingDevice *device,
const QPointF &local, const QPointF &global, Qt::MouseButtons state,
Qt::MouseButton button, QEvent::Type type, Qt::KeyboardModifiers mods,
Qt::MouseEventSource source)
{
Q_ASSERT_X(type != QEvent::MouseButtonDblClick && type != QEvent::NonClientAreaMouseButtonDblClick,
"QWindowSystemInterface::handleMouseEvent",
@ -391,7 +400,7 @@ QT_DEFINE_QPA_EVENT_HANDLER(bool, handleMouseEvent, QWindow *window, ulong times
QWindowSystemInterfacePrivate::MouseEvent *e =
new QWindowSystemInterfacePrivate::MouseEvent(window, timestamp, localPos, globalPos,
state, mods, button, type, source);
state, mods, button, type, source, false, device);
return QWindowSystemInterfacePrivate::handleWindowSystemEvent<Delivery>(e);
}
@ -412,13 +421,24 @@ bool QWindowSystemInterface::handleFrameStrutMouseEvent(QWindow *window, ulong t
Qt::MouseButton button, QEvent::Type type,
Qt::KeyboardModifiers mods,
Qt::MouseEventSource source)
{
return handleFrameStrutMouseEvent(window, timestamp, QPointingDevice::primaryPointingDevice(),
local, global, state, button, type, mods, source);
}
bool QWindowSystemInterface::handleFrameStrutMouseEvent(QWindow *window, ulong timestamp, const QPointingDevice *device,
const QPointF &local, const QPointF &global,
Qt::MouseButtons state,
Qt::MouseButton button, QEvent::Type type,
Qt::KeyboardModifiers mods,
Qt::MouseEventSource source)
{
auto localPos = QHighDpi::fromNativeLocalPosition(local, window);
auto globalPos = QHighDpi::fromNativePixels(global, window);
QWindowSystemInterfacePrivate::MouseEvent *e =
new QWindowSystemInterfacePrivate::MouseEvent(window, timestamp, localPos, globalPos,
state, mods, button, type, source, true);
state, mods, button, type, source, true, device);
return QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
@ -517,13 +537,6 @@ bool QWindowSystemInterface::handleExtendedKeyEvent(QWindow *window, ulong times
return QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
QWindowSystemInterfacePrivate::WheelEvent::WheelEvent(QWindow *window, ulong time, const QPointF &local, const QPointF &global, QPoint pixelD,
QPoint angleD, int qt4D, Qt::Orientation qt4O, Qt::KeyboardModifiers mods, Qt::ScrollPhase phase, Qt::MouseEventSource src, bool inverted)
: InputEvent(window, time, Wheel, mods), pixelDelta(pixelD), angleDelta(angleD), qt4Delta(qt4D),
qt4Orientation(qt4O), localPos(local), globalPos(global), phase(phase), source(src), inverted(inverted)
{
}
bool QWindowSystemInterface::handleWheelEvent(QWindow *window, const QPointF &local, const QPointF &global, QPoint pixelDelta, QPoint angleDelta, Qt::KeyboardModifiers mods, Qt::ScrollPhase phase, Qt::MouseEventSource source)
{
unsigned long time = QWindowSystemInterfacePrivate::eventTime.elapsed();
@ -532,6 +545,15 @@ bool QWindowSystemInterface::handleWheelEvent(QWindow *window, const QPointF &lo
bool QWindowSystemInterface::handleWheelEvent(QWindow *window, ulong timestamp, const QPointF &local, const QPointF &global, QPoint pixelDelta, QPoint angleDelta, Qt::KeyboardModifiers mods, Qt::ScrollPhase phase,
Qt::MouseEventSource source, bool invertedScrolling)
{
return handleWheelEvent(window, timestamp, QPointingDevice::primaryPointingDevice(), local, global,
pixelDelta, angleDelta, mods, phase, source, invertedScrolling);
}
bool QWindowSystemInterface::handleWheelEvent(QWindow *window, ulong timestamp, const QPointingDevice *device,
const QPointF &local, const QPointF &global, QPoint pixelDelta, QPoint angleDelta,
Qt::KeyboardModifiers mods, Qt::ScrollPhase phase,
Qt::MouseEventSource source, bool invertedScrolling)
{
// Qt 4 sends two separate wheel events for horizontal and vertical
// deltas. For Qt 5 we want to send the deltas in one event, but at the
@ -550,14 +572,15 @@ bool QWindowSystemInterface::handleWheelEvent(QWindow *window, ulong timestamp,
// Simple case: vertical deltas only:
if (angleDelta.y() != 0 && angleDelta.x() == 0) {
e = new QWindowSystemInterfacePrivate::WheelEvent(window, timestamp, QHighDpi::fromNativeLocalPosition(local, window), QHighDpi::fromNativePixels(global, window), pixelDelta, angleDelta, angleDelta.y(), Qt::Vertical,
mods, phase, source, invertedScrolling);
mods, phase, source, invertedScrolling, device);
return QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
// Simple case: horizontal deltas only:
if (angleDelta.y() == 0 && angleDelta.x() != 0) {
e = new QWindowSystemInterfacePrivate::WheelEvent(window, timestamp, QHighDpi::fromNativeLocalPosition(local, window), QHighDpi::fromNativePixels(global, window), pixelDelta, angleDelta, angleDelta.x(), Qt::Horizontal, mods, phase, source, invertedScrolling);
e = new QWindowSystemInterfacePrivate::WheelEvent(window, timestamp, QHighDpi::fromNativeLocalPosition(local, window), QHighDpi::fromNativePixels(global, window), pixelDelta, angleDelta, angleDelta.x(), Qt::Horizontal,
mods, phase, source, invertedScrolling, device);
return QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
@ -566,12 +589,14 @@ bool QWindowSystemInterface::handleWheelEvent(QWindow *window, ulong timestamp,
// Both horizontal and vertical deltas: Send two wheel events.
// The first event contains the Qt 5 pixel and angle delta as points,
// and in addition the Qt 4 compatibility vertical angle delta.
e = new QWindowSystemInterfacePrivate::WheelEvent(window, timestamp, QHighDpi::fromNativeLocalPosition(local, window), QHighDpi::fromNativePixels(global, window), pixelDelta, angleDelta, angleDelta.y(), Qt::Vertical, mods, phase, source, invertedScrolling);
e = new QWindowSystemInterfacePrivate::WheelEvent(window, timestamp, QHighDpi::fromNativeLocalPosition(local, window), QHighDpi::fromNativePixels(global, window), pixelDelta, angleDelta, angleDelta.y(), Qt::Vertical,
mods, phase, source, invertedScrolling, device);
acceptVert = QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
// The second event contains null pixel and angle points and the
// Qt 4 compatibility horizontal angle delta.
e = new QWindowSystemInterfacePrivate::WheelEvent(window, timestamp, QHighDpi::fromNativeLocalPosition(local, window), QHighDpi::fromNativePixels(global, window), QPoint(), QPoint(), angleDelta.x(), Qt::Horizontal, mods, phase, source, invertedScrolling);
e = new QWindowSystemInterfacePrivate::WheelEvent(window, timestamp, QHighDpi::fromNativeLocalPosition(local, window), QHighDpi::fromNativePixels(global, window), QPoint(), QPoint(), angleDelta.x(), Qt::Horizontal,
mods, phase, source, invertedScrolling, device);
acceptHorz = QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
return acceptVert || acceptHorz;
}
@ -863,20 +888,32 @@ void QWindowSystemInterfacePrivate::TabletEvent::setPlatformSynthesizesMouse(boo
platformSynthesizesMouse = v;
}
bool QWindowSystemInterface::handleTabletEvent(QWindow *window, ulong timestamp, 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,
bool QWindowSystemInterface::handleTabletEvent(QWindow *window, ulong timestamp, const QPointingDevice *device,
const QPointF &local, const QPointF &global,
Qt::MouseButtons buttons, qreal pressure, int xTilt, int yTilt,
qreal tangentialPressure, qreal rotation, int z,
Qt::KeyboardModifiers modifiers)
{
QWindowSystemInterfacePrivate::TabletEvent *e =
new QWindowSystemInterfacePrivate::TabletEvent(window, timestamp,
QHighDpi::fromNativeLocalPosition(local, window),
QHighDpi::fromNativePixels(global, window),
device, pointerType, buttons, pressure,
xTilt, yTilt, tangentialPressure, rotation, z, uid, modifiers);
device, buttons, pressure,
xTilt, yTilt, tangentialPressure, rotation, z, modifiers);
return QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
bool QWindowSystemInterface::handleTabletEvent(QWindow *window, ulong timestamp, 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,
Qt::KeyboardModifiers modifiers)
{
const QPointingDevice *dev = QPointingDevice::tabletDevice(QInputDevice::DeviceType(device),QPointingDevice::PointerType(pointerType),
QPointingDeviceUniqueId::fromNumericId(uid));
return handleTabletEvent(window, timestamp, dev, local, global, buttons, pressure,
xTilt, yTilt, tangentialPressure, rotation, z, modifiers);
}
bool QWindowSystemInterface::handleTabletEvent(QWindow *window, 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,
@ -887,43 +924,76 @@ bool QWindowSystemInterface::handleTabletEvent(QWindow *window, const QPointF &l
xTilt, yTilt, tangentialPressure, rotation, z, uid, modifiers);
}
bool QWindowSystemInterface::handleTabletEnterProximityEvent(ulong timestamp, int device, int pointerType, qint64 uid)
bool QWindowSystemInterface::handleTabletEnterLeaveProximityEvent(QWindow *window, ulong timestamp, const QPointingDevice *device,
bool inProximity, const QPointF &local, const QPointF &global,
Qt::MouseButtons buttons, int xTilt, int yTilt,
qreal tangentialPressure, qreal rotation, int z,
Qt::KeyboardModifiers modifiers)
{
Q_UNUSED(window);
Q_UNUSED(local);
Q_UNUSED(global);
Q_UNUSED(buttons);
Q_UNUSED(xTilt);
Q_UNUSED(yTilt);
Q_UNUSED(tangentialPressure);
Q_UNUSED(rotation);
Q_UNUSED(z);
Q_UNUSED(modifiers);
if (inProximity) {
QWindowSystemInterfacePrivate::TabletEnterProximityEvent *e =
new QWindowSystemInterfacePrivate::TabletEnterProximityEvent(timestamp, device);
return QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
} else {
QWindowSystemInterfacePrivate::TabletLeaveProximityEvent *e =
new QWindowSystemInterfacePrivate::TabletLeaveProximityEvent(timestamp, device);
return QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
}
bool QWindowSystemInterface::handleTabletEnterProximityEvent(ulong timestamp, int deviceType, int pointerType, qint64 uid)
{
const QPointingDevice *device = QPointingDevice::tabletDevice(QInputDevice::DeviceType(deviceType),
QPointingDevice::PointerType(pointerType),
QPointingDeviceUniqueId::fromNumericId(uid));
QWindowSystemInterfacePrivate::TabletEnterProximityEvent *e =
new QWindowSystemInterfacePrivate::TabletEnterProximityEvent(timestamp, device, pointerType, uid);
new QWindowSystemInterfacePrivate::TabletEnterProximityEvent(timestamp, device);
return QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
void QWindowSystemInterface::handleTabletEnterProximityEvent(int device, int pointerType, qint64 uid)
void QWindowSystemInterface::handleTabletEnterProximityEvent(int deviceType, int pointerType, qint64 uid)
{
ulong time = QWindowSystemInterfacePrivate::eventTime.elapsed();
handleTabletEnterProximityEvent(time, device, pointerType, uid);
handleTabletEnterProximityEvent(time, deviceType, pointerType, uid);
}
bool QWindowSystemInterface::handleTabletLeaveProximityEvent(ulong timestamp, int device, int pointerType, qint64 uid)
bool QWindowSystemInterface::handleTabletLeaveProximityEvent(ulong timestamp, int deviceType, int pointerType, qint64 uid)
{
const QPointingDevice *device = QPointingDevice::tabletDevice(QInputDevice::DeviceType(deviceType),
QPointingDevice::PointerType(pointerType),
QPointingDeviceUniqueId::fromNumericId(uid));
QWindowSystemInterfacePrivate::TabletLeaveProximityEvent *e =
new QWindowSystemInterfacePrivate::TabletLeaveProximityEvent(timestamp, device, pointerType, uid);
new QWindowSystemInterfacePrivate::TabletLeaveProximityEvent(timestamp, device);
return QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
void QWindowSystemInterface::handleTabletLeaveProximityEvent(int device, int pointerType, qint64 uid)
void QWindowSystemInterface::handleTabletLeaveProximityEvent(int deviceType, int pointerType, qint64 uid)
{
ulong time = QWindowSystemInterfacePrivate::eventTime.elapsed();
handleTabletLeaveProximityEvent(time, device, pointerType, uid);
handleTabletLeaveProximityEvent(time, deviceType, pointerType, uid);
}
#ifndef QT_NO_GESTURES
bool QWindowSystemInterface::handleGestureEvent(QWindow *window, const QPointingDevice *device, ulong timestamp, Qt::NativeGestureType type,
QPointF &local, QPointF &global)
bool QWindowSystemInterface::handleGestureEvent(QWindow *window, ulong timestamp, const QPointingDevice *device,
Qt::NativeGestureType type, const QPointF &local, const QPointF &global)
{
QWindowSystemInterfacePrivate::GestureEvent *e =
new QWindowSystemInterfacePrivate::GestureEvent(window, timestamp, type, device, local, global);
return QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
bool QWindowSystemInterface::handleGestureEventWithRealValue(QWindow *window, const QPointingDevice *device, ulong timestamp, Qt::NativeGestureType type,
qreal value, QPointF &local, QPointF &global)
bool QWindowSystemInterface::handleGestureEventWithRealValue(QWindow *window, ulong timestamp, const QPointingDevice *device,
Qt::NativeGestureType type, qreal value, const QPointF &local, const QPointF &global)
{
QWindowSystemInterfacePrivate::GestureEvent *e =
new QWindowSystemInterfacePrivate::GestureEvent(window, timestamp, type, device, local, global);
@ -931,8 +1001,9 @@ bool QWindowSystemInterface::handleGestureEventWithRealValue(QWindow *window, co
return QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
bool QWindowSystemInterface::handleGestureEventWithSequenceIdAndValue(QWindow *window, const QPointingDevice *device, ulong timestamp, Qt::NativeGestureType type,
ulong sequenceId, quint64 value, QPointF &local, QPointF &global)
bool QWindowSystemInterface::handleGestureEventWithSequenceIdAndValue(QWindow *window, ulong timestamp, const QPointingDevice *device,
Qt::NativeGestureType type, ulong sequenceId, quint64 value,
const QPointF &local, const QPointF &global)
{
QWindowSystemInterfacePrivate::GestureEvent *e =
new QWindowSystemInterfacePrivate::GestureEvent(window, timestamp, type, device, local, global);

View File

@ -87,6 +87,12 @@ public:
Qt::MouseButton button, QEvent::Type type,
Qt::KeyboardModifiers mods = Qt::NoModifier,
Qt::MouseEventSource source = Qt::MouseEventNotSynthesized);
template<typename Delivery = QWindowSystemInterface::DefaultDelivery>
static bool handleMouseEvent(QWindow *window, ulong timestamp, const QPointingDevice *device,
const QPointF &local, const QPointF &global, Qt::MouseButtons state,
Qt::MouseButton button, QEvent::Type type,
Qt::KeyboardModifiers mods = Qt::NoModifier,
Qt::MouseEventSource source = Qt::MouseEventNotSynthesized);
static bool handleFrameStrutMouseEvent(QWindow *window, const QPointF &local,
const QPointF &global, Qt::MouseButtons state,
@ -100,6 +106,11 @@ public:
Qt::KeyboardModifiers mods = Qt::NoModifier,
Qt::MouseEventSource source =
Qt::MouseEventNotSynthesized);
static bool handleFrameStrutMouseEvent(QWindow *window, ulong timestamp, const QPointingDevice *device,
const QPointF &local, const QPointF &global, Qt::MouseButtons state,
Qt::MouseButton button, QEvent::Type type,
Qt::KeyboardModifiers mods = Qt::NoModifier,
Qt::MouseEventSource source = Qt::MouseEventNotSynthesized);
static bool handleShortcutEvent(QWindow *window, ulong timestamp, int k, Qt::KeyboardModifiers mods, quint32 nativeScanCode,
quint32 nativeVirtualKey, quint32 nativeModifiers, const QString & text = QString(), bool autorep = false, ushort count = 1);
@ -119,6 +130,12 @@ public:
quint32 nativeModifiers,
const QString& text = QString(), bool autorep = false,
ushort count = 1, bool tryShortcutOverride = true);
static bool handleExtendedKeyEvent(QWindow *window, ulong timestamp, const QInputDevice *device,
QEvent::Type type, int key, Qt::KeyboardModifiers modifiers,
quint32 nativeScanCode, quint32 nativeVirtualKey,
quint32 nativeModifiers,
const QString& text = QString(), bool autorep = false,
ushort count = 1, bool tryShortcutOverride = true);
static bool handleWheelEvent(QWindow *window, const QPointF &local, const QPointF &global,
QPoint pixelDelta, QPoint angleDelta,
Qt::KeyboardModifiers mods = Qt::NoModifier,
@ -130,6 +147,13 @@ public:
Qt::ScrollPhase phase = Qt::NoScrollPhase,
Qt::MouseEventSource source = Qt::MouseEventNotSynthesized,
bool inverted = false);
static bool handleWheelEvent(QWindow *window, ulong timestamp, const QPointingDevice *device,
const QPointF &local, const QPointF &global,
QPoint pixelDelta, QPoint angleDelta,
Qt::KeyboardModifiers mods = Qt::NoModifier,
Qt::ScrollPhase phase = Qt::NoScrollPhase,
Qt::MouseEventSource source = Qt::MouseEventNotSynthesized,
bool inverted = false);
struct TouchPoint {
TouchPoint() : id(0), uniqueId(-1), pressure(0), rotation(0), state(Qt::TouchPointStationary) { }
@ -225,6 +249,10 @@ public:
static void handleFileOpenEvent(const QString& fileName);
static void handleFileOpenEvent(const QUrl &url);
static bool handleTabletEvent(QWindow *window, ulong timestamp, const QPointingDevice *device,
const QPointF &local, const QPointF &global,
Qt::MouseButtons buttons, qreal pressure, int xTilt, int yTilt,
qreal tangentialPressure, qreal rotation, int z, Qt::KeyboardModifiers modifiers = Qt::NoModifier);
static bool handleTabletEvent(QWindow *window, ulong timestamp, 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,
@ -233,18 +261,23 @@ public:
int device, int pointerType, Qt::MouseButtons buttons, qreal pressure, int xTilt, int yTilt,
qreal tangentialPressure, qreal rotation, int z, qint64 uid,
Qt::KeyboardModifiers modifiers = Qt::NoModifier);
static bool handleTabletEnterProximityEvent(ulong timestamp, int device, int pointerType, qint64 uid);
static void handleTabletEnterProximityEvent(int device, int pointerType, qint64 uid);
static bool handleTabletLeaveProximityEvent(ulong timestamp, int device, int pointerType, qint64 uid);
static void handleTabletLeaveProximityEvent(int device, int pointerType, qint64 uid);
static bool handleTabletEnterLeaveProximityEvent(QWindow *window, ulong timestamp, const QPointingDevice *device,
bool inProximity, const QPointF &local = QPointF(), const QPointF &global = QPointF(),
Qt::MouseButtons buttons = {}, int xTilt = 0, int yTilt = 0,
qreal tangentialPressure = 0, qreal rotation = 0, int z = 0,
Qt::KeyboardModifiers modifiers = Qt::NoModifier);
static bool handleTabletEnterProximityEvent(ulong timestamp, int deviceType, int pointerType, qint64 uid);
static void handleTabletEnterProximityEvent(int deviceType, int pointerType, qint64 uid);
static bool handleTabletLeaveProximityEvent(ulong timestamp, int deviceType, int pointerType, qint64 uid);
static void handleTabletLeaveProximityEvent(int deviceType, int pointerType, qint64 uid);
#ifndef QT_NO_GESTURES
static bool handleGestureEvent(QWindow *window, const QPointingDevice *device, ulong timestamp, Qt::NativeGestureType type,
QPointF &local, QPointF &global);
static bool handleGestureEventWithRealValue(QWindow *window, const QPointingDevice *device, ulong timestamp, Qt::NativeGestureType type,
qreal value, QPointF &local, QPointF &global);
static bool handleGestureEventWithSequenceIdAndValue(QWindow *window, const QPointingDevice *device, ulong timestamp,Qt::NativeGestureType type,
ulong sequenceId, quint64 value, QPointF &local, QPointF &global);
static bool handleGestureEvent(QWindow *window, ulong timestamp, const QPointingDevice *device, Qt::NativeGestureType type,
const QPointF &local, const QPointF &global);
static bool handleGestureEventWithRealValue(QWindow *window, ulong timestamp, const QPointingDevice *device, Qt::NativeGestureType type,
qreal value, const QPointF &local, const QPointF &global);
static bool handleGestureEventWithSequenceIdAndValue(QWindow *window, ulong timestamp, const QPointingDevice *device, Qt::NativeGestureType type,
ulong sequenceId, quint64 value, const QPointF &local, const QPointF &global);
#endif // QT_NO_GESTURES
static void handlePlatformPanelEvent(QWindow *window);

View File

@ -228,9 +228,10 @@ public:
class InputEvent: public UserEvent {
public:
InputEvent(QWindow * w, ulong time, EventType t, Qt::KeyboardModifiers mods)
: UserEvent(w, time, t), modifiers(mods) {}
InputEvent(QWindow *w, ulong time, EventType t, Qt::KeyboardModifiers mods, const QInputDevice *dev)
: UserEvent(w, time, t), modifiers(mods), device(dev) {}
Qt::KeyboardModifiers modifiers;
const QInputDevice *device;
};
class MouseEvent : public InputEvent {
@ -238,9 +239,10 @@ 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)
: InputEvent(w, time, Mouse, mods), localPos(local), globalPos(global), buttons(state),
source(src), nonClientArea(frame), button(b), buttonType(type) { }
Qt::MouseEventSource src = Qt::MouseEventNotSynthesized, bool frame = false,
const QPointingDevice *device = QPointingDevice::primaryPointingDevice())
: InputEvent(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
bool enhancedMouseEvent() const
@ -261,7 +263,10 @@ public:
class WheelEvent : public InputEvent {
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);
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),
qt4Orientation(qt4O), localPos(local), globalPos(global), phase(phase), source(src), inverted(inverted) { }
QPoint pixelDelta;
QPoint angleDelta;
int qt4Delta;
@ -275,14 +280,15 @@ public:
class KeyEvent : public InputEvent {
public:
KeyEvent(QWindow *w, ulong time, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text = QString(), bool autorep = false, ushort count = 1)
:InputEvent(w, time, Key, mods), key(k), unicode(text), repeat(autorep),
KeyEvent(QWindow *w, ulong time, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text = QString(),
bool autorep = false, ushort count = 1, const QInputDevice *device = QInputDevice::primaryKeyboard())
: InputEvent(w, time, Key, mods, device), key(k), unicode(text), repeat(autorep),
repeatCount(count), keyType(t),
nativeScanCode(0), nativeVirtualKey(0), nativeModifiers(0) { }
KeyEvent(QWindow *w, ulong time, QEvent::Type t, int k, Qt::KeyboardModifiers mods,
quint32 nativeSC, quint32 nativeVK, quint32 nativeMods,
const QString & text = QString(), bool autorep = false, ushort count = 1)
:InputEvent(w, time, Key, mods), key(k), unicode(text), repeat(autorep),
const QString & text = QString(), bool autorep = false, ushort count = 1, const QInputDevice *device = QInputDevice::primaryKeyboard())
: InputEvent(w, time, Key, mods, device), key(k), unicode(text), repeat(autorep),
repeatCount(count), keyType(t),
nativeScanCode(nativeSC), nativeVirtualKey(nativeVK), nativeModifiers(nativeMods) { }
int key;
@ -297,10 +303,10 @@ public:
class TouchEvent : public InputEvent {
public:
TouchEvent(QWindow *w, ulong time, QEvent::Type t, const QPointingDevice *dev,
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(dev), points(p), touchType(t) { }
const QPointingDevice *device;
: InputEvent(w, time, Touch, mods, device), points(p), touchType(t) {
}
QList<QTouchEvent::TouchPoint> points;
QEvent::Type touchType;
};
@ -374,45 +380,34 @@ public:
static void setPlatformSynthesizesMouse(bool v);
TabletEvent(QWindow *w, ulong time, const QPointF &local, const QPointF &global,
int device, int pointerType, Qt::MouseButtons b, qreal pressure, int xTilt, int yTilt, qreal tpressure,
qreal rotation, int z, qint64 uid, Qt::KeyboardModifiers mods)
: InputEvent(w, time, Tablet, mods),
buttons(b), local(local), global(global), device(device), pointerType(pointerType),
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),
buttons(b), local(local), global(global),
pressure(pressure), xTilt(xTilt), yTilt(yTilt), tangentialPressure(tpressure),
rotation(rotation), z(z), uid(uid) { }
rotation(rotation), z(z) { }
Qt::MouseButtons buttons;
QPointF local;
QPointF global;
int device;
int pointerType;
qreal pressure;
int xTilt;
int yTilt;
qreal tangentialPressure;
qreal rotation;
int z;
qint64 uid;
static bool platformSynthesizesMouse;
};
class TabletEnterProximityEvent : public InputEvent {
public:
TabletEnterProximityEvent(ulong time, int device, int pointerType, qint64 uid)
: InputEvent(nullptr, time, TabletEnterProximity, Qt::NoModifier),
device(device), pointerType(pointerType), uid(uid) { }
int device;
int pointerType;
qint64 uid;
TabletEnterProximityEvent(ulong time, const QPointingDevice *device)
: InputEvent(nullptr, time, TabletEnterProximity, Qt::NoModifier, device) { }
};
class TabletLeaveProximityEvent : public InputEvent {
public:
TabletLeaveProximityEvent(ulong time, int device, int pointerType, qint64 uid)
: InputEvent(nullptr, time, TabletLeaveProximity, Qt::NoModifier),
device(device), pointerType(pointerType), uid(uid) { }
int device;
int pointerType;
qint64 uid;
TabletLeaveProximityEvent(ulong time, const QPointingDevice *device)
: InputEvent(nullptr, time, TabletLeaveProximity, Qt::NoModifier, device) { }
};
class PlatformPanelEvent : public WindowSystemEvent {
@ -441,7 +436,7 @@ public:
class GestureEvent : public InputEvent {
public:
GestureEvent(QWindow *window, ulong time, Qt::NativeGestureType type, const QPointingDevice *dev, QPointF pos, QPointF globalPos)
: InputEvent(window, time, Gesture, Qt::NoModifier), type(type), pos(pos), globalPos(globalPos),
: InputEvent(window, time, Gesture, Qt::NoModifier, dev), type(type), pos(pos), globalPos(globalPos),
realValue(0), sequenceId(0), intValue(0), device(dev) { }
Qt::NativeGestureType type;
QPointF pos;

View File

@ -75,8 +75,9 @@ Q_LOGGING_CATEGORY(lcQpaGestures, "qt.qpa.input.gestures")
QPointF windowPoint;
QPointF screenPoint;
[self convertFromScreen:[self screenMousePoint:event] toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
QWindowSystemInterface::handleGestureEventWithRealValue(m_platformWindow->window(), QCocoaTouch::getTouchDevice(QInputDevice::DeviceType::TouchPad, [event deviceID]), timestamp, Qt::ZoomNativeGesture,
[event magnification], windowPoint, screenPoint);
QWindowSystemInterface::handleGestureEventWithRealValue(m_platformWindow->window(), timestamp,
QCocoaTouch::getTouchDevice(QInputDevice::DeviceType::TouchPad, [event deviceID]),
Qt::ZoomNativeGesture, [event magnification], windowPoint, screenPoint);
}
- (void)smartMagnifyWithEvent:(NSEvent *)event
@ -90,8 +91,9 @@ Q_LOGGING_CATEGORY(lcQpaGestures, "qt.qpa.input.gestures")
QPointF windowPoint;
QPointF screenPoint;
[self convertFromScreen:[self screenMousePoint:event] toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
QWindowSystemInterface::handleGestureEventWithRealValue(m_platformWindow->window(), QCocoaTouch::getTouchDevice(QInputDevice::DeviceType::TouchPad, [event deviceID]), timestamp, Qt::SmartZoomNativeGesture,
zoomIn ? 1.0f : 0.0f, windowPoint, screenPoint);
QWindowSystemInterface::handleGestureEventWithRealValue(m_platformWindow->window(), timestamp,
QCocoaTouch::getTouchDevice(QInputDevice::DeviceType::TouchPad, [event deviceID]),
Qt::SmartZoomNativeGesture, zoomIn ? 1.0f : 0.0f, windowPoint, screenPoint);
zoomIn = !zoomIn;
}
@ -107,8 +109,9 @@ Q_LOGGING_CATEGORY(lcQpaGestures, "qt.qpa.input.gestures")
QPointF windowPoint;
QPointF screenPoint;
[self convertFromScreen:[self screenMousePoint:event] toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
QWindowSystemInterface::handleGestureEventWithRealValue(m_platformWindow->window(), QCocoaTouch::getTouchDevice(QInputDevice::DeviceType::TouchPad, [event deviceID]), timestamp, Qt::RotateNativeGesture,
-[event rotation], windowPoint, screenPoint);
QWindowSystemInterface::handleGestureEventWithRealValue(m_platformWindow->window(), timestamp,
QCocoaTouch::getTouchDevice(QInputDevice::DeviceType::TouchPad, [event deviceID]),
Qt::RotateNativeGesture, -[event rotation], windowPoint, screenPoint);
}
- (void)swipeWithEvent:(NSEvent *)event
@ -132,8 +135,9 @@ Q_LOGGING_CATEGORY(lcQpaGestures, "qt.qpa.input.gestures")
else if ([event deltaY] == -1)
angle = 270.0f;
QWindowSystemInterface::handleGestureEventWithRealValue(m_platformWindow->window(), QCocoaTouch::getTouchDevice(QInputDevice::DeviceType::TouchPad, [event deviceID]), timestamp, Qt::SwipeNativeGesture,
angle, windowPoint, screenPoint);
QWindowSystemInterface::handleGestureEventWithRealValue(m_platformWindow->window(), timestamp,
QCocoaTouch::getTouchDevice(QInputDevice::DeviceType::TouchPad, [event deviceID]),
Qt::SwipeNativeGesture, angle, windowPoint, screenPoint);
}
- (void)beginGestureWithEvent:(NSEvent *)event
@ -146,8 +150,9 @@ Q_LOGGING_CATEGORY(lcQpaGestures, "qt.qpa.input.gestures")
QPointF screenPoint;
[self convertFromScreen:[self screenMousePoint:event] toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
qCDebug(lcQpaGestures) << "beginGestureWithEvent @" << windowPoint << "from device" << Qt::hex << [event deviceID];
QWindowSystemInterface::handleGestureEvent(m_platformWindow->window(), QCocoaTouch::getTouchDevice(QInputDevice::DeviceType::TouchPad, [event deviceID]), timestamp, Qt::BeginNativeGesture,
windowPoint, screenPoint);
QWindowSystemInterface::handleGestureEvent(m_platformWindow->window(), timestamp,
QCocoaTouch::getTouchDevice(QInputDevice::DeviceType::TouchPad, [event deviceID]),
Qt::BeginNativeGesture, windowPoint, screenPoint);
}
- (void)endGestureWithEvent:(NSEvent *)event
@ -160,8 +165,9 @@ Q_LOGGING_CATEGORY(lcQpaGestures, "qt.qpa.input.gestures")
QPointF windowPoint;
QPointF screenPoint;
[self convertFromScreen:[self screenMousePoint:event] toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
QWindowSystemInterface::handleGestureEvent(m_platformWindow->window(), QCocoaTouch::getTouchDevice(QInputDevice::DeviceType::TouchPad, [event deviceID]), timestamp, Qt::EndNativeGesture,
windowPoint, screenPoint);
QWindowSystemInterface::handleGestureEvent(m_platformWindow->window(), timestamp,
QCocoaTouch::getTouchDevice(QInputDevice::DeviceType::TouchPad, [event deviceID]),
Qt::EndNativeGesture, windowPoint, screenPoint);
}
@end

View File

@ -1725,6 +1725,11 @@ public:
void tst_QWindow::tabletEvents()
{
#if QT_CONFIG(tabletevent)
// the fake USB tablet device is "plugged in"
QPointingDevice tabletDevice("macow", 0xbeef, QInputDevice::DeviceType::Unknown, QPointingDevice::PointerType::Generic,
QInputDevice::Capability::Position, 1, 0);
QWindowSystemInterface::registerInputDevice(&tabletDevice);
TabletTestWindow window;
window.setGeometry(QRect(m_availableTopLeft + QPoint(10, 10), m_testWindowSize));
qGuiApp->installEventFilter(&window);
@ -1733,24 +1738,36 @@ void tst_QWindow::tabletEvents()
const QPoint global = window.mapToGlobal(local);
const QPoint deviceLocal = QHighDpi::toNativeLocalPosition(local, &window);
const QPoint deviceGlobal = QHighDpi::toNativePixels(global, window.screen());
QWindowSystemInterface::handleTabletEvent(&window, deviceLocal, deviceGlobal,
1, 2, Qt::LeftButton, 0.5, 1, 2, 0.1, 0, 0, 0);
QCoreApplication::processEvents();
QTRY_VERIFY(window.eventType == QEvent::TabletPress);
QTRY_COMPARE(window.eventGlobal.toPoint(), global);
QTRY_COMPARE(window.eventLocal.toPoint(), local);
QWindowSystemInterface::handleTabletEvent(&window, deviceLocal, deviceGlobal, 1, 2,
{}, 0.5, 1, 2, 0.1, 0, 0, 0);
QCoreApplication::processEvents();
QTRY_COMPARE(window.eventType, QEvent::TabletRelease);
ulong timestamp = 1234;
QWindowSystemInterface::handleTabletEnterProximityEvent(int(QInputDevice::DeviceType::Stylus), int(QPointingDevice::PointerType::Eraser), 3);
// the stylus is just now seen for the first time, as it comes into proximity
// its QObject-parent will be the tablet device
QPointingDevice tabletStylus("macow stylus eraser", 0xe6a5e6, QInputDevice::DeviceType::Stylus, QPointingDevice::PointerType::Eraser,
QInputDevice::Capability::Position | QInputDevice::Capability::Pressure, 1, 3, QString(),
QPointingDeviceUniqueId::fromNumericId(42), &tabletDevice);
QWindowSystemInterface::registerInputDevice(&tabletStylus);
QWindowSystemInterface::handleTabletEnterLeaveProximityEvent(&window, timestamp++, &tabletStylus, true);
QCoreApplication::processEvents();
QTRY_COMPARE(window.eventType, QEvent::TabletEnterProximity);
QCOMPARE(window.eventDevice, QInputDevice::DeviceType::Stylus);
QCOMPARE(window.eventPointerType, QPointingDevice::PointerType::Eraser);
QWindowSystemInterface::handleTabletLeaveProximityEvent(int(QInputDevice::DeviceType::Stylus), int(QPointingDevice::PointerType::Eraser), 3);
// the eraser is pressed into contact with the tablet surface
QWindowSystemInterface::handleTabletEvent(&window, timestamp++, &tabletStylus, deviceLocal, deviceGlobal,
Qt::LeftButton, 0.5, 1, 2, 0.1, 0, 0, {});
QCoreApplication::processEvents();
QTRY_VERIFY(window.eventType == QEvent::TabletPress);
QTRY_COMPARE(window.eventGlobal.toPoint(), global);
QTRY_COMPARE(window.eventLocal.toPoint(), local);
// now it's lifted
QWindowSystemInterface::handleTabletEvent(&window, timestamp++, &tabletStylus, deviceLocal, deviceGlobal,
Qt::NoButton, 0, 3, 4, 0.11, 2, 1, {});
QCoreApplication::processEvents();
QTRY_COMPARE(window.eventType, QEvent::TabletRelease);
// and is taken away (goes out of proxmity)
QWindowSystemInterface::handleTabletEnterLeaveProximityEvent(&window, timestamp, &tabletStylus, false);
QCoreApplication::processEvents();
QTRY_COMPARE(window.eventType, QEvent::TabletLeaveProximity);
QCOMPARE(window.eventDevice, QInputDevice::DeviceType::Stylus);