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>bb10
parent
07d8885ccc
commit
69c833dae9
|
|
@ -84,6 +84,7 @@ public:
|
|||
Velocity = 0x0008,
|
||||
NormalizedPosition = 0x0020,
|
||||
MouseEmulation = 0x0040,
|
||||
PixelScroll = 0x0080,
|
||||
Scroll = 0x0100,
|
||||
Hover = 0x0200,
|
||||
Rotation = 0x0400,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue