Cocoa: Send correct mouse buttons for tablets

Tablet vendors allow user configurable pen buttons
where the user may assign a logical mouse button to
a given physical button.

In the case of Wacom tablets this mapping is not reflected
in the buttonMask API, which returns the state of
the physical buttons.

Use NSEvent buttonNummber instead, which returns the
logical button number, after applying user mappings.
Unifiy button state stacking with the mouse handlers.

Handle a special case where buttonNumber returns 0
for tablet right mouse presses. We get these events
via rightMouse* event handlers and can hardcode the
button number.

Change-Id: I06b9b1aa98c49b84f7e3871e694c22c7ad0169d6
Task-number: QTBUG-57487
Task-number: QTBUG-54160
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
This commit is contained in:
Morten Johan Sørvig 2016-12-07 12:52:52 +01:00 committed by Shawn Rutledge
parent 148188fef3
commit 8bc36c773f
2 changed files with 22 additions and 20 deletions

View File

@ -116,9 +116,9 @@ Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper));
- (void)resetMouseButtons; - (void)resetMouseButtons;
- (void)handleMouseEvent:(NSEvent *)theEvent; - (void)handleMouseEvent:(NSEvent *)theEvent;
- (bool)handleMouseDownEvent:(NSEvent *)theEvent; - (bool)handleMouseDownEvent:(NSEvent *)theEvent withButton:(int)buttonNumber;
- (bool)handleMouseDraggedEvent:(NSEvent *)theEvent; - (bool)handleMouseDraggedEvent:(NSEvent *)theEvent withButton:(int)buttonNumber;
- (bool)handleMouseUpEvent:(NSEvent *)theEvent; - (bool)handleMouseUpEvent:(NSEvent *)theEvent withButton:(int)buttonNumber;
- (void)mouseDown:(NSEvent *)theEvent; - (void)mouseDown:(NSEvent *)theEvent;
- (void)mouseDragged:(NSEvent *)theEvent; - (void)mouseDragged:(NSEvent *)theEvent;
- (void)mouseUp:(NSEvent *)theEvent; - (void)mouseUp:(NSEvent *)theEvent;

View File

@ -724,12 +724,12 @@ static bool _q_dontOverrideCtrlLMB = false;
QWindowSystemInterface::handleFrameStrutMouseEvent(m_platformWindow->window(), timestamp, qtWindowPoint, qtScreenPoint, m_frameStrutButtons); QWindowSystemInterface::handleFrameStrutMouseEvent(m_platformWindow->window(), timestamp, qtWindowPoint, qtScreenPoint, m_frameStrutButtons);
} }
- (bool)handleMouseDownEvent:(NSEvent *)theEvent - (bool)handleMouseDownEvent:(NSEvent *)theEvent withButton:(int)buttonNumber
{ {
if ([self isTransparentForUserInput]) if ([self isTransparentForUserInput])
return false; return false;
Qt::MouseButton button = cocoaButton2QtButton([theEvent buttonNumber]); Qt::MouseButton button = cocoaButton2QtButton(buttonNumber);
QPointF qtWindowPoint; QPointF qtWindowPoint;
QPointF qtScreenPoint; QPointF qtScreenPoint;
@ -753,12 +753,12 @@ static bool _q_dontOverrideCtrlLMB = false;
return true; return true;
} }
- (bool)handleMouseDraggedEvent:(NSEvent *)theEvent - (bool)handleMouseDraggedEvent:(NSEvent *)theEvent withButton:(int)buttonNumber
{ {
if ([self isTransparentForUserInput]) if ([self isTransparentForUserInput])
return false; return false;
Qt::MouseButton button = cocoaButton2QtButton([theEvent buttonNumber]); Qt::MouseButton button = cocoaButton2QtButton(buttonNumber);
// Forward the event to the next responder if Qt did not accept the // Forward the event to the next responder if Qt did not accept the
// corresponding mouse down for this button // corresponding mouse down for this button
@ -769,12 +769,12 @@ static bool _q_dontOverrideCtrlLMB = false;
return true; return true;
} }
- (bool)handleMouseUpEvent:(NSEvent *)theEvent - (bool)handleMouseUpEvent:(NSEvent *)theEvent withButton:(int)buttonNumber
{ {
if ([self isTransparentForUserInput]) if ([self isTransparentForUserInput])
return false; return false;
Qt::MouseButton button = cocoaButton2QtButton([theEvent buttonNumber]); Qt::MouseButton button = cocoaButton2QtButton(buttonNumber);
// Forward the event to the next responder if Qt did not accept the // Forward the event to the next responder if Qt did not accept the
// corresponding mouse down for this button // corresponding mouse down for this button
@ -864,56 +864,59 @@ static bool _q_dontOverrideCtrlLMB = false;
- (void)mouseDragged:(NSEvent *)theEvent - (void)mouseDragged:(NSEvent *)theEvent
{ {
const bool accepted = [self handleMouseDraggedEvent:theEvent]; const bool accepted = [self handleMouseDraggedEvent:theEvent withButton:[theEvent buttonNumber]];
if (!accepted) if (!accepted)
[super mouseDragged:theEvent]; [super mouseDragged:theEvent];
} }
- (void)mouseUp:(NSEvent *)theEvent - (void)mouseUp:(NSEvent *)theEvent
{ {
const bool accepted = [self handleMouseUpEvent:theEvent]; const bool accepted = [self handleMouseUpEvent:theEvent withButton:[theEvent buttonNumber]];
if (!accepted) if (!accepted)
[super mouseUp:theEvent]; [super mouseUp:theEvent];
} }
- (void)rightMouseDown:(NSEvent *)theEvent - (void)rightMouseDown:(NSEvent *)theEvent
{ {
const bool accepted = [self handleMouseDownEvent:theEvent]; // Wacom tablet might not return the correct button number for NSEvent buttonNumber
// on right clicks. Decide here that the button is the "right" button and forward
// the button number to the mouse (and tablet) handler.
const bool accepted = [self handleMouseDownEvent:theEvent withButton:1];
if (!accepted) if (!accepted)
[super rightMouseDown:theEvent]; [super rightMouseDown:theEvent];
} }
- (void)rightMouseDragged:(NSEvent *)theEvent - (void)rightMouseDragged:(NSEvent *)theEvent
{ {
const bool accepted = [self handleMouseDraggedEvent:theEvent]; const bool accepted = [self handleMouseDraggedEvent:theEvent withButton:1];
if (!accepted) if (!accepted)
[super rightMouseDragged:theEvent]; [super rightMouseDragged:theEvent];
} }
- (void)rightMouseUp:(NSEvent *)theEvent - (void)rightMouseUp:(NSEvent *)theEvent
{ {
const bool accepted = [self handleMouseUpEvent:theEvent]; const bool accepted = [self handleMouseUpEvent:theEvent withButton:1];
if (!accepted) if (!accepted)
[super rightMouseUp:theEvent]; [super rightMouseUp:theEvent];
} }
- (void)otherMouseDown:(NSEvent *)theEvent - (void)otherMouseDown:(NSEvent *)theEvent
{ {
const bool accepted = [self handleMouseDownEvent:theEvent]; const bool accepted = [self handleMouseDownEvent:theEvent withButton:[theEvent buttonNumber]];
if (!accepted) if (!accepted)
[super otherMouseDown:theEvent]; [super otherMouseDown:theEvent];
} }
- (void)otherMouseDragged:(NSEvent *)theEvent - (void)otherMouseDragged:(NSEvent *)theEvent
{ {
const bool accepted = [self handleMouseDraggedEvent:theEvent]; const bool accepted = [self handleMouseDraggedEvent:theEvent withButton:[theEvent buttonNumber]];
if (!accepted) if (!accepted)
[super otherMouseDragged:theEvent]; [super otherMouseDragged:theEvent];
} }
- (void)otherMouseUp:(NSEvent *)theEvent - (void)otherMouseUp:(NSEvent *)theEvent
{ {
const bool accepted = [self handleMouseUpEvent:theEvent]; const bool accepted = [self handleMouseUpEvent:theEvent withButton:[theEvent buttonNumber]];
if (!accepted) if (!accepted)
[super otherMouseUp:theEvent]; [super otherMouseUp:theEvent];
} }
@ -1071,7 +1074,6 @@ Q_GLOBAL_STATIC(QCocoaTabletDeviceDataHash, tabletDeviceDataHash)
NSPoint tilt = [theEvent tilt]; NSPoint tilt = [theEvent tilt];
int xTilt = qRound(tilt.x * 60.0); int xTilt = qRound(tilt.x * 60.0);
int yTilt = qRound(tilt.y * -60.0); int yTilt = qRound(tilt.y * -60.0);
Qt::MouseButtons buttons = static_cast<Qt::MouseButtons>(static_cast<uint>([theEvent buttonMask]));
qreal tangentialPressure = 0; qreal tangentialPressure = 0;
qreal rotation = 0; qreal rotation = 0;
int z = 0; int z = 0;
@ -1090,10 +1092,10 @@ Q_GLOBAL_STATIC(QCocoaTabletDeviceDataHash, tabletDeviceDataHash)
qCDebug(lcQpaTablet, "event on tablet %d with tool %d type %d unique ID %lld pos %6.1f, %6.1f root pos %6.1f, %6.1f buttons 0x%x pressure %4.2lf tilt %d, %d rotation %6.2lf", qCDebug(lcQpaTablet, "event on tablet %d with tool %d type %d unique ID %lld pos %6.1f, %6.1f root pos %6.1f, %6.1f buttons 0x%x pressure %4.2lf tilt %d, %d rotation %6.2lf",
deviceId, deviceData.device, deviceData.pointerType, deviceData.uid, deviceId, deviceData.device, deviceData.pointerType, deviceData.uid,
windowPoint.x(), windowPoint.y(), screenPoint.x(), screenPoint.y(), windowPoint.x(), windowPoint.y(), screenPoint.x(), screenPoint.y(),
static_cast<uint>(buttons), pressure, xTilt, yTilt, rotation); static_cast<uint>(m_buttons), pressure, xTilt, yTilt, rotation);
QWindowSystemInterface::handleTabletEvent(m_platformWindow->window(), timestamp, windowPoint, screenPoint, QWindowSystemInterface::handleTabletEvent(m_platformWindow->window(), timestamp, windowPoint, screenPoint,
deviceData.device, deviceData.pointerType, buttons, pressure, xTilt, yTilt, deviceData.device, deviceData.pointerType, m_buttons, pressure, xTilt, yTilt,
tangentialPressure, rotation, z, deviceData.uid, tangentialPressure, rotation, z, deviceData.uid,
keyboardModifiers); keyboardModifiers);
return true; return true;