diff options
author | Shawn Rutledge <shawn.rutledge@qt.io> | 2020-06-24 12:33:43 +0200 |
---|---|---|
committer | Tor Arne Vestbø <tor.arne.vestbo@qt.io> | 2021-08-01 15:32:41 +0200 |
commit | 69c833dae91d004b48f815e0156d6caeb4cdb491 (patch) | |
tree | 5e0504e2807e4f7383b20d8a7ccdb58c8c961052 /src/plugins/platforms/cocoa | |
parent | 07d8885cccdb759532715598e18ecbe1c1282d25 (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.h | 1 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoahelpers.mm | 1 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qmultitouch_mac.mm | 2 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qnsview.mm | 1 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qnsview_mouse.mm | 50 |
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) |