macOS touch and gestures: pay attention to deviceID

Previously we pretended that there is only one touch device; but in fact,
different trackpads have different deviceIDs, and this may be useful
in some scenarios to tell them apart, as on other platforms.
So far we don't expect to get touch events from actual touchscreens
though, because macOS only turns single-touch events into mouse events
and does not interpret gestures on touchscreens.  So there isn't API
which can distinguish touchscreens from touchpads as far as we know.
QCocoaTouch::getTouchDevice() takes the type as a parameter, just in
case this changes some day.

Change-Id: I56228471363235c5d0cc2a55a35a3c3288f3b1a1
Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
This commit is contained in:
Shawn Rutledge 2017-09-12 17:07:54 +02:00
parent 83729ad7a1
commit aa4ff7b2e9
3 changed files with 35 additions and 24 deletions

View File

@ -39,10 +39,14 @@
#include "qmultitouch_mac_p.h"
#include "qcocoahelpers.h"
#include <private/qtouchdevice_p.h>
QT_BEGIN_NAMESPACE
Q_LOGGING_CATEGORY(lcInputDevices, "qt.qpa.input.devices")
QHash<qint64, QCocoaTouch*> QCocoaTouch::_currentTouches;
QHash<quint64, QTouchDevice*> QCocoaTouch::_touchDevices;
QPointF QCocoaTouch::_screenReferencePos;
QPointF QCocoaTouch::_trackpadReferencePos;
int QCocoaTouch::_idAssignmentCount = 0;
@ -209,4 +213,19 @@ QCocoaTouch::getCurrentTouchPointList(NSEvent *event, bool acceptSingleTouch)
return touchPoints.values();
}
QTouchDevice *QCocoaTouch::getTouchDevice(QTouchDevice::DeviceType type, quint64 id)
{
QTouchDevice *ret = _touchDevices.value(id);
if (!ret) {
ret = new QTouchDevice;
ret->setType(type);
ret->setCapabilities(QTouchDevice::Position | QTouchDevice::NormalizedPosition | QTouchDevice::MouseEmulation);
QWindowSystemInterface::registerTouchDevice(ret);
_touchDevices.insert(id, ret);
qCDebug(lcInputDevices) << "touch device" << id << "of type" << type
<< "registered as Qt device" << QTouchDevicePrivate::get(ret)->id;
}
return ret;
}
QT_END_NAMESPACE

View File

@ -66,8 +66,10 @@ class QCocoaTouch
public:
static QList<QWindowSystemInterface::TouchPoint> getCurrentTouchPointList(NSEvent *event, bool acceptSingleTouch);
static void setMouseInDraggingState(bool inDraggingState);
static QTouchDevice *getTouchDevice(QTouchDevice::DeviceType type, quint64 id);
private:
static QHash<quint64, QTouchDevice*> _touchDevices;
static QHash<qint64, QCocoaTouch*> _currentTouches;
static QPointF _screenReferencePos;
static QPointF _trackpadReferencePos;

View File

@ -70,8 +70,6 @@ Q_LOGGING_CATEGORY(lcQpaGestures, "qt.qpa.input.gestures")
#endif
Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
static QTouchDevice *touchDevice = 0;
@interface QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper) : NSObject
{
QNSView *view;
@ -146,14 +144,6 @@ static QTouchDevice *touchDevice = 0;
m_scrolling = false;
m_updatingDrag = false;
m_currentlyInterpretedKeyEvent = 0;
if (!touchDevice) {
touchDevice = new QTouchDevice;
touchDevice->setType(QTouchDevice::TouchPad);
touchDevice->setCapabilities(QTouchDevice::Position | QTouchDevice::NormalizedPosition | QTouchDevice::MouseEmulation);
QWindowSystemInterface::registerTouchDevice(touchDevice);
}
m_isMenuView = false;
self.focusRingType = NSFocusRingTypeNone;
self.cursor = nil;
@ -1065,8 +1055,8 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
const NSTimeInterval timestamp = [event timestamp];
const QList<QWindowSystemInterface::TouchPoint> points = QCocoaTouch::getCurrentTouchPointList(event, [self shouldSendSingleTouch]);
qCDebug(lcQpaTouch) << "touchesBeganWithEvent" << points;
QWindowSystemInterface::handleTouchEvent(m_platformWindow->window(), timestamp * 1000, touchDevice, points);
qCDebug(lcQpaTouch) << "touchesBeganWithEvent" << points << "from device" << hex << [event deviceID];
QWindowSystemInterface::handleTouchEvent(m_platformWindow->window(), timestamp * 1000, QCocoaTouch::getTouchDevice(QTouchDevice::TouchPad, [event deviceID]), points);
}
- (void)touchesMovedWithEvent:(NSEvent *)event
@ -1076,8 +1066,8 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
const NSTimeInterval timestamp = [event timestamp];
const QList<QWindowSystemInterface::TouchPoint> points = QCocoaTouch::getCurrentTouchPointList(event, [self shouldSendSingleTouch]);
qCDebug(lcQpaTouch) << "touchesMovedWithEvent" << points;
QWindowSystemInterface::handleTouchEvent(m_platformWindow->window(), timestamp * 1000, touchDevice, points);
qCDebug(lcQpaTouch) << "touchesMovedWithEvent" << points << "from device" << hex << [event deviceID];
QWindowSystemInterface::handleTouchEvent(m_platformWindow->window(), timestamp * 1000, QCocoaTouch::getTouchDevice(QTouchDevice::TouchPad, [event deviceID]), points);
}
- (void)touchesEndedWithEvent:(NSEvent *)event
@ -1087,8 +1077,8 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
const NSTimeInterval timestamp = [event timestamp];
const QList<QWindowSystemInterface::TouchPoint> points = QCocoaTouch::getCurrentTouchPointList(event, [self shouldSendSingleTouch]);
qCDebug(lcQpaTouch) << "touchesEndedWithEvent" << points;
QWindowSystemInterface::handleTouchEvent(m_platformWindow->window(), timestamp * 1000, touchDevice, points);
qCDebug(lcQpaTouch) << "touchesEndedWithEvent" << points << "from device" << hex << [event deviceID];
QWindowSystemInterface::handleTouchEvent(m_platformWindow->window(), timestamp * 1000, QCocoaTouch::getTouchDevice(QTouchDevice::TouchPad, [event deviceID]), points);
}
- (void)touchesCancelledWithEvent:(NSEvent *)event
@ -1098,8 +1088,8 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
const NSTimeInterval timestamp = [event timestamp];
const QList<QWindowSystemInterface::TouchPoint> points = QCocoaTouch::getCurrentTouchPointList(event, [self shouldSendSingleTouch]);
qCDebug(lcQpaTouch) << "touchesCancelledWithEvent" << points;
QWindowSystemInterface::handleTouchEvent(m_platformWindow->window(), timestamp * 1000, touchDevice, points);
qCDebug(lcQpaTouch) << "touchesCancelledWithEvent" << points << "from device" << hex << [event deviceID];
QWindowSystemInterface::handleTouchEvent(m_platformWindow->window(), timestamp * 1000, QCocoaTouch::getTouchDevice(QTouchDevice::TouchPad, [event deviceID]), points);
}
#ifndef QT_NO_GESTURES
@ -1134,7 +1124,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(), touchDevice, timestamp, Qt::ZoomNativeGesture,
QWindowSystemInterface::handleGestureEventWithRealValue(m_platformWindow->window(), QCocoaTouch::getTouchDevice(QTouchDevice::TouchPad, [event deviceID]), timestamp, Qt::ZoomNativeGesture,
[event magnification], windowPoint, screenPoint);
}
@ -1149,7 +1139,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(), touchDevice, timestamp, Qt::SmartZoomNativeGesture,
QWindowSystemInterface::handleGestureEventWithRealValue(m_platformWindow->window(), QCocoaTouch::getTouchDevice(QTouchDevice::TouchPad, [event deviceID]), timestamp, Qt::SmartZoomNativeGesture,
zoomIn ? 1.0f : 0.0f, windowPoint, screenPoint);
zoomIn = !zoomIn;
}
@ -1166,7 +1156,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(), touchDevice, timestamp, Qt::RotateNativeGesture,
QWindowSystemInterface::handleGestureEventWithRealValue(m_platformWindow->window(), QCocoaTouch::getTouchDevice(QTouchDevice::TouchPad, [event deviceID]), timestamp, Qt::RotateNativeGesture,
-[event rotation], windowPoint, screenPoint);
}
@ -1191,7 +1181,7 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
else if ([event deltaY] == -1)
angle = 270.0f;
QWindowSystemInterface::handleGestureEventWithRealValue(m_platformWindow->window(), touchDevice, timestamp, Qt::SwipeNativeGesture,
QWindowSystemInterface::handleGestureEventWithRealValue(m_platformWindow->window(), QCocoaTouch::getTouchDevice(QTouchDevice::TouchPad, [event deviceID]), timestamp, Qt::SwipeNativeGesture,
angle, windowPoint, screenPoint);
}
@ -1205,7 +1195,7 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
QPointF screenPoint;
[self convertFromScreen:[self screenMousePoint:event] toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
qCDebug(lcQpaGestures) << "beginGestureWithEvent @" << windowPoint << "from device" << hex << [event deviceID];
QWindowSystemInterface::handleGestureEvent(m_platformWindow->window(), touchDevice, timestamp, Qt::BeginNativeGesture,
QWindowSystemInterface::handleGestureEvent(m_platformWindow->window(), QCocoaTouch::getTouchDevice(QTouchDevice::TouchPad, [event deviceID]), timestamp, Qt::BeginNativeGesture,
windowPoint, screenPoint);
}
@ -1219,7 +1209,7 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
QPointF windowPoint;
QPointF screenPoint;
[self convertFromScreen:[self screenMousePoint:event] toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
QWindowSystemInterface::handleGestureEvent(m_platformWindow->window(), touchDevice, timestamp, Qt::EndNativeGesture,
QWindowSystemInterface::handleGestureEvent(m_platformWindow->window(), QCocoaTouch::getTouchDevice(QTouchDevice::TouchPad, [event deviceID]), timestamp, Qt::EndNativeGesture,
windowPoint, screenPoint);
}
#endif // QT_NO_GESTURES