summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/cocoa
diff options
context:
space:
mode:
authorShawn Rutledge <shawn.rutledge@qt.io>2020-06-24 12:33:43 +0200
committerTor Arne Vestbø <tor.arne.vestbo@qt.io>2021-08-01 15:32:41 +0200
commit69c833dae91d004b48f815e0156d6caeb4cdb491 (patch)
tree5e0504e2807e4f7383b20d8a7ccdb58c8c961052 /src/plugins/platforms/cocoa
parent07d8885cccdb759532715598e18ecbe1c1282d25 (diff)
Register mouse devices on cocoa
It would have been nice to ensure that a device is registered already in mouseEnteredImpl(); but in that context, NSEvent.deviceID is always 0, and we can't find out anything else about the device. QWindowSystemInterface::handleEnterEvent() doesn't currently take a QPointingDevice either. In handleMouseEvent() and scrollWheel(), deviceID seems unique for each trackpad or Magic Mouse, but 0 for any plain USB mouse. There, the first mouse that the user interacts with becomes primaryPointingDevice(): its deviceID is assigned to systemID (except if deviceID == 0, we use 1 instead, to avoid the auto-incrementing device ID assignment in the QInputDevicePrivate ctor.) When scrolling occurs, we update the capabilities to have PixelScroll if theEvent.hasPreciseScrollingDeltas. So over time, QInputDevice::devices() should build up to a complete list, with capabilities() also distinguishing plain mice from those that have the PixelScroll capability. And in the common case that the user has only one Apple pointing device, it becomes primaryPointingDevice(). Pick-to: 6.2 Task-number: QTBUG-46412 Task-number: QTBUG-63363 Task-number: QTBUG-72167 Change-Id: Id9771b4dfd765e49023bd57d42a2aa4d0635a3b2 Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io> Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
Diffstat (limited to 'src/plugins/platforms/cocoa')
-rw-r--r--src/plugins/platforms/cocoa/qcocoahelpers.h1
-rw-r--r--src/plugins/platforms/cocoa/qcocoahelpers.mm1
-rw-r--r--src/plugins/platforms/cocoa/qmultitouch_mac.mm2
-rw-r--r--src/plugins/platforms/cocoa/qnsview.mm1
-rw-r--r--src/plugins/platforms/cocoa/qnsview_mouse.mm50
5 files changed, 51 insertions, 4 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.h b/src/plugins/platforms/cocoa/qcocoahelpers.h
index e25eff740f..25069bb56d 100644
--- a/src/plugins/platforms/cocoa/qcocoahelpers.h
+++ b/src/plugins/platforms/cocoa/qcocoahelpers.h
@@ -74,6 +74,7 @@ Q_DECLARE_LOGGING_CATEGORY(lcQpaMouse)
Q_DECLARE_LOGGING_CATEGORY(lcQpaScreen)
Q_DECLARE_LOGGING_CATEGORY(lcQpaApplication)
Q_DECLARE_LOGGING_CATEGORY(lcQpaClipboard)
+Q_DECLARE_LOGGING_CATEGORY(lcInputDevices)
class QPixmap;
class QString;
diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.mm b/src/plugins/platforms/cocoa/qcocoahelpers.mm
index a3535b25f3..299c655d14 100644
--- a/src/plugins/platforms/cocoa/qcocoahelpers.mm
+++ b/src/plugins/platforms/cocoa/qcocoahelpers.mm
@@ -61,6 +61,7 @@ Q_LOGGING_CATEGORY(lcQpaMouse, "qt.qpa.input.mouse", QtCriticalMsg);
Q_LOGGING_CATEGORY(lcQpaScreen, "qt.qpa.screen", QtCriticalMsg);
Q_LOGGING_CATEGORY(lcQpaApplication, "qt.qpa.application");
Q_LOGGING_CATEGORY(lcQpaClipboard, "qt.qpa.clipboard")
+Q_LOGGING_CATEGORY(lcInputDevices, "qt.qpa.input.devices")
//
// Conversion Functions
diff --git a/src/plugins/platforms/cocoa/qmultitouch_mac.mm b/src/plugins/platforms/cocoa/qmultitouch_mac.mm
index 28d641b598..5521b7525c 100644
--- a/src/plugins/platforms/cocoa/qmultitouch_mac.mm
+++ b/src/plugins/platforms/cocoa/qmultitouch_mac.mm
@@ -46,8 +46,6 @@
QT_BEGIN_NAMESPACE
-Q_LOGGING_CATEGORY(lcInputDevices, "qt.qpa.input.devices")
-
QHash<qint64, QCocoaTouch*> QCocoaTouch::_currentTouches;
QHash<quint64, QPointingDevice*> QCocoaTouch::_touchDevices;
QPointF QCocoaTouch::_screenReferencePos;
diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm
index 8e4efc6fb6..bcc6c5ee61 100644
--- a/src/plugins/platforms/cocoa/qnsview.mm
+++ b/src/plugins/platforms/cocoa/qnsview.mm
@@ -62,6 +62,7 @@
#include <private/qguiapplication_p.h>
#include <private/qcoregraphics_p.h>
#include <private/qwindow_p.h>
+#include <private/qpointingdevice_p.h>
#include "qcocoabackingstore.h"
#ifndef QT_NO_OPENGL
#include "qcocoaglcontext.h"
diff --git a/src/plugins/platforms/cocoa/qnsview_mouse.mm b/src/plugins/platforms/cocoa/qnsview_mouse.mm
index 54a1f06df6..f5896de99e 100644
--- a/src/plugins/platforms/cocoa/qnsview_mouse.mm
+++ b/src/plugins/platforms/cocoa/qnsview_mouse.mm
@@ -187,6 +187,36 @@
}
@end
+static const QPointingDevice *pointingDeviceFor(qint64 deviceID)
+{
+ // macOS will in many cases not report a deviceID (0 value).
+ // We can't pass this on directly, as the QInputDevicePrivate
+ // constructor will treat this as a request to assign a new Id.
+ // Instead we use the default Id of the primary pointing device.
+ static const int kDefaultPrimaryPointingDeviceId = 1;
+ if (!deviceID)
+ deviceID = kDefaultPrimaryPointingDeviceId;
+
+ if (const auto *device = QPointingDevicePrivate::pointingDeviceById(deviceID))
+ return device; // All good, already have the device registered
+
+ const auto *primaryDevice = QPointingDevice::primaryPointingDevice();
+ if (primaryDevice->systemId() == kDefaultPrimaryPointingDeviceId) {
+ // Adopt existing primary device instead of creating a new one
+ QPointingDevicePrivate::get(const_cast<QPointingDevice *>(primaryDevice))->systemId = deviceID;
+ qCDebug(lcInputDevices) << "primaryPointingDevice is now" << primaryDevice;
+ return primaryDevice;
+ } else {
+ // Register a new device. Name and capabilities may need updating later.
+ const auto *device = new QPointingDevice(QLatin1String("mouse"), deviceID,
+ QInputDevice::DeviceType::Mouse, QPointingDevice::PointerType::Generic,
+ QInputDevice::Capability::Scroll | QInputDevice::Capability::Position,
+ 1, 3, QString(), QPointingDeviceUniqueId(), QCocoaIntegration::instance());
+ QWindowSystemInterface::registerInputDevice(device);
+ return device;
+ }
+}
+
@implementation QNSView (Mouse)
- (void)initMouse
@@ -294,6 +324,9 @@
button = Qt::RightButton;
const auto eventType = cocoaEvent2QtMouseEvent(theEvent);
+ const QPointingDevice *device = pointingDeviceFor(theEvent.deviceID);
+ Q_ASSERT(device);
+
if (eventType == QEvent::MouseMove)
qCDebug(lcQpaMouse) << eventType << "at" << qtWindowPoint << "with" << m_buttons;
else
@@ -696,8 +729,21 @@
<< " pixelDelta=" << pixelDelta << " angleDelta=" << angleDelta
<< (isInverted ? " inverted=true" : "");
- QWindowSystemInterface::handleWheelEvent(m_platformWindow->window(), qt_timestamp, qt_windowPoint,
- qt_screenPoint, pixelDelta, angleDelta, m_currentWheelModifiers, phase, source, isInverted);
+ const QPointingDevice *device = pointingDeviceFor(theEvent.deviceID);
+ Q_ASSERT(device);
+
+ if (theEvent.hasPreciseScrollingDeltas) {
+ auto *devicePriv = QPointingDevicePrivate::get(const_cast<QPointingDevice *>(device));
+ if (!devicePriv->capabilities.testFlag(QInputDevice::Capability::PixelScroll)) {
+ devicePriv->name = QLatin1String("trackpad or magic mouse");
+ devicePriv->capabilities |= QInputDevice::Capability::PixelScroll;
+ qCDebug(lcInputDevices) << "mouse scrolling: updated capabilities" << device;
+ }
+ }
+
+ QWindowSystemInterface::handleWheelEvent(m_platformWindow->window(), qt_timestamp,
+ device, qt_windowPoint, qt_screenPoint, pixelDelta, angleDelta,
+ m_currentWheelModifiers, phase, source, isInverted);
}
#endif // QT_CONFIG(wheelevent)