*** ./qtbase/src/plugins/platforms/cocoa/qnsview.mm --- ./qtbase/src/plugins/platforms/cocoa/qnsview.mm *************** static NSString *_q_NSWindowDidChangeOcc *** 77,82 **** --- 77,85 ---- static bool _q_dontOverrideCtrlLMB = false; + // ### Mach port for the event tap to fix up the buttonNumber for Tablet right button mouse Events. (QTBUG-57487) + static CFMachPortRef _q_TableEventTapMachPort = 0; + @interface NSEvent (Qt_Compile_Leopard_DeviceDelta) - (CGFloat)deviceDeltaX; - (CGFloat)deviceDeltaY; *************** static bool _q_dontOverrideCtrlLMB = fal *** 132,137 **** --- 135,170 ---- @implementation QT_MANGLE_NAMESPACE(QNSView) + // Event tap to fix up the right mouse buttonNumber to [theEvent buttonNumber] references below will work correctly + // for "right" button tablet events returned by some tablets. (QTBUG-57487) + static CGEventRef qnsTabletEventTap(CGEventTapProxy /*proxy*/, CGEventType type, CGEventRef inEvent, void *refCon) + { + Q_UNUSED(refCon); + switch (type) + { + case kCGEventRightMouseDown: + case kCGEventRightMouseUp: + case kCGEventRightMouseDragged: + { + int64_t subType = CGEventGetIntegerValueField(inEvent, kCGMouseEventSubtype); + if (subType == kCGEventMouseSubtypeTabletPoint) + { + int64_t buttonNumber = CGEventGetIntegerValueField(inEvent, kCGMouseEventButtonNumber); + if (buttonNumber != kCGMouseButtonRight) + { + CGEventSetIntegerValueField(inEvent, kCGMouseEventButtonNumber, kCGMouseButtonRight); + } + } + break; + } + + default: + break; + } + + return inEvent; + } + + (void)initialize { NSString **notificationNameVar = (NSString **)dlsym(RTLD_NEXT, "NSWindowDidChangeOcclusionStateNotification"); *************** static bool _q_dontOverrideCtrlLMB = fal *** 139,144 **** --- 172,197 ---- _q_NSWindowDidChangeOcclusionStateNotification = *notificationNameVar; _q_dontOverrideCtrlLMB = qt_mac_resolveOption(false, "QT_MAC_DONT_OVERRIDE_CTRL_LMB"); + + // Use event tap to fix up the incorrect [NSEvent buttonNumber] returned for "right" button tablet events + // returned by some tablets. (QTBUG-57487) + static bool useTabletEventTap = qt_mac_resolveOption(true, "QT_MAC_USE_TABLET_EVENTTAP"); + if (!_q_TableEventTapMachPort && useTabletEventTap) + { + pid_t pid = getpid(); + ProcessSerialNumber psn; + GetProcessForPID(pid, &psn); + + CGEventMask eventMask = CGEventMaskBit(kCGEventRightMouseDown) + | CGEventMaskBit(kCGEventRightMouseUp) + | CGEventMaskBit(kCGEventRightMouseDragged); + + _q_TableEventTapMachPort = CGEventTapCreateForPSN(&psn, kCGHeadInsertEventTap, kCGEventTapOptionDefault, eventMask, + qnsTabletEventTap, NULL); + + CFRunLoopSourceRef eventSrc = CFMachPortCreateRunLoopSource(NULL, _q_TableEventTapMachPort, 0); + CFRunLoopAddSource((CFRunLoopRef) GetCFRunLoopFromEventLoop(GetMainEventLoop()), eventSrc, kCFRunLoopCommonModes); + } } - (id) init *************** Q_GLOBAL_STATIC(QCocoaTabletDeviceDataHa *** 1200,1206 **** NSPoint tilt = [theEvent tilt]; int xTilt = qRound(tilt.x * 60.0); int yTilt = qRound(tilt.y * -60.0); ! Qt::MouseButtons buttons = static_cast(static_cast([theEvent buttonMask])); qreal tangentialPressure = 0; qreal rotation = 0; int z = 0; --- 1253,1267 ---- NSPoint tilt = [theEvent tilt]; int xTilt = qRound(tilt.x * 60.0); int yTilt = qRound(tilt.y * -60.0); ! // If we are using the event tab then m_buttons will have the valid button state even for right clicks. (QTBUG-57487) ! // Please note that the older code is incorrect because it maps the physical tablet buttons: NSPenTipMask, NSPenLowerSideMask, ! // NSPenUpperSideMask. We are leaving this old code path here so we can test both code paths a runtime for acceptance ! // testing. Once that changes have been verified by QA we will remove the old code. ! Qt::MouseButtons buttons; ! if (_q_TableEventTapMachPort) ! buttons = m_buttons; ! else ! buttons = static_cast(static_cast([theEvent buttonMask])); qreal tangentialPressure = 0; qreal rotation = 0; int z = 0;