From 3ead3dff7e713057b03cd2b969896f196b7ca2f0 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Mon, 22 Jun 2009 14:49:09 +0200 Subject: Multitouch, Cocoa: Added Qt::WA_TouchPadAcceptSingleTouchEvents By default this is set to false, meaning you will only get multitouch events. The reason why this is important is that we use the first touch of a new touch sequence to find out which widget to send the subsequent touches to. And on a touchpad, you normally want this to be the widget under the cursor when more than one finger is pressed on the pad. --- src/corelib/global/qnamespace.h | 1 + src/gui/kernel/qcocoaview_mac.mm | 12 ++++++++---- src/gui/kernel/qmultitouch_mac.mm | 36 ++++++++++++++++++------------------ src/gui/kernel/qmultitouch_mac_p.h | 4 ++-- 4 files changed, 29 insertions(+), 24 deletions(-) diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h index 2e2a09d..0006026 100644 --- a/src/corelib/global/qnamespace.h +++ b/src/corelib/global/qnamespace.h @@ -493,6 +493,7 @@ public: WA_AcceptTouchEvents = 121, WA_WState_AcceptedTouchBeginEvent = 122, + WA_TouchPadAcceptSingleTouchEvents = 123, // Add new attributes before this line WA_AttributeCount diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm index e8e52f9..827094d 100644 --- a/src/gui/kernel/qcocoaview_mac.mm +++ b/src/gui/kernel/qcocoaview_mac.mm @@ -873,22 +873,26 @@ extern "C" { #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 - (void)touchesBeganWithEvent:(NSEvent *)event; { - qt_translateRawTouchEvent(QCocoaTouch::getCurrentTouchPointList(event, true), qwidget); + bool all = qwidget->testAttribute(Qt::WA_TouchPadAcceptSingleTouchEvents); + qt_translateRawTouchEvent(QCocoaTouch::getCurrentTouchPointList(event, all), qwidget); } - (void)touchesMovedWithEvent:(NSEvent *)event; { - qt_translateRawTouchEvent(QCocoaTouch::getCurrentTouchPointList(event, true), qwidget); + bool all = qwidget->testAttribute(Qt::WA_TouchPadAcceptSingleTouchEvents); + qt_translateRawTouchEvent(QCocoaTouch::getCurrentTouchPointList(event, all), qwidget); } - (void)touchesEndedWithEvent:(NSEvent *)event; { - qt_translateRawTouchEvent(QCocoaTouch::getCurrentTouchPointList(event, true), qwidget); + bool all = qwidget->testAttribute(Qt::WA_TouchPadAcceptSingleTouchEvents); + qt_translateRawTouchEvent(QCocoaTouch::getCurrentTouchPointList(event, all), qwidget); } - (void)touchesCancelledWithEvent:(NSEvent *)event; { - qt_translateRawTouchEvent(QCocoaTouch::getCurrentTouchPointList(event, true), qwidget); + bool all = qwidget->testAttribute(Qt::WA_TouchPadAcceptSingleTouchEvents); + qt_translateRawTouchEvent(QCocoaTouch::getCurrentTouchPointList(event, all), qwidget); } - (void)magnifyWithEvent:(NSEvent *)event; diff --git a/src/gui/kernel/qmultitouch_mac.mm b/src/gui/kernel/qmultitouch_mac.mm index 15fa60d..d3d423c 100644 --- a/src/gui/kernel/qmultitouch_mac.mm +++ b/src/gui/kernel/qmultitouch_mac.mm @@ -53,7 +53,7 @@ QPointF QCocoaTouch::_screenReferencePos; QPointF QCocoaTouch::_trackpadReferencePos; int QCocoaTouch::_idAssignmentCount = 0; int QCocoaTouch::_touchCount = 0; -bool QCocoaTouch::_maskMouseHover = true; +bool QCocoaTouch::_updateInternalStateOnly = true; QCocoaTouch::QCocoaTouch(NSTouch *nstouch) { @@ -128,7 +128,8 @@ Qt::TouchPointState QCocoaTouch::toTouchPointState(NSTouchPhase nsState) return qtState; } -QList QCocoaTouch::getCurrentTouchPointList(NSEvent *event, bool maskMouseHover) +QList +QCocoaTouch::getCurrentTouchPointList(NSEvent *event, bool acceptSingleTouch) { QList touchPoints; NSSet *ended = [event touchesMatchingPhase:NSTouchPhaseEnded | NSTouchPhaseCancelled inView:nil]; @@ -138,27 +139,27 @@ QList QCocoaTouch::getCurrentTouchPointList(NSEvent *ev _touchCount = [active count]; // First: remove touches that were ended by the user. If we are - // currently masking the mouse hover touch, a corresponding 'begin' - // has never been posted to the app. So we should not send - // the following remove either. + // currently not accepting single touches, a corresponding 'begin' + // has never been send to the app for these events. + // So should therefore not send the following removes either. for (int i=0; iupdateTouchData(touch, [touch phase]); - if (!_maskMouseHover) + if (!_updateInternalStateOnly) touchPoints.append(qcocoaTouch->_touchPoint); delete qcocoaTouch; } } - bool wasMaskingMouseHover = _maskMouseHover; - _maskMouseHover = maskMouseHover && _touchCount < 2; + bool wasUpdateInternalStateOnly = _updateInternalStateOnly; + _updateInternalStateOnly = !acceptSingleTouch && _touchCount < 2; // Next: update, or create, existing touches. // We always keep track of all touch points, even - // when masking the mouse hover touch: + // when not accepting single touches. for (int i=0; i QCocoaTouch::getCurrentTouchPointList(NSEvent *ev if (!qcocoaTouch) qcocoaTouch = new QCocoaTouch(touch); else - qcocoaTouch->updateTouchData(touch, wasMaskingMouseHover ? NSTouchPhaseBegan : [touch phase]); - if (!_maskMouseHover) + qcocoaTouch->updateTouchData(touch, wasUpdateInternalStateOnly ? NSTouchPhaseBegan : [touch phase]); + if (!_updateInternalStateOnly) touchPoints.append(qcocoaTouch->_touchPoint); } @@ -180,23 +181,22 @@ QList QCocoaTouch::getCurrentTouchPointList(NSEvent *ev touchPoints.clear(); QList list = _currentTouches.values(); foreach (QCocoaTouch *qcocoaTouch, _currentTouches.values()) { - if (!_maskMouseHover) { + if (!_updateInternalStateOnly) { qcocoaTouch->_touchPoint.setState(Qt::TouchPointReleased); touchPoints.append(qcocoaTouch->_touchPoint); } delete qcocoaTouch; } _currentTouches.clear(); - _maskMouseHover = maskMouseHover; + _updateInternalStateOnly = !acceptSingleTouch; return touchPoints; } - // Finally: If we in this call _started_ to mask the mouse - // hover touch, we need to fake a relase for it now (and refake - // a begin for it later, if needed). + // Finally: If this call _started_ to reject single + // touches, we need to fake a relase for the remaining + // touch now (and refake a begin for it later, if needed). - if (_maskMouseHover && !wasMaskingMouseHover && !_currentTouches.isEmpty()) { - // If one touch is still active, fake a release event for it. + if (_updateInternalStateOnly && !wasUpdateInternalStateOnly && !_currentTouches.isEmpty()) { QCocoaTouch *qcocoaTouch = _currentTouches.values().first(); qcocoaTouch->_touchPoint.setState(Qt::TouchPointReleased); touchPoints.append(qcocoaTouch->_touchPoint); diff --git a/src/gui/kernel/qmultitouch_mac_p.h b/src/gui/kernel/qmultitouch_mac_p.h index 9ec256a..0c45df4 100644 --- a/src/gui/kernel/qmultitouch_mac_p.h +++ b/src/gui/kernel/qmultitouch_mac_p.h @@ -70,7 +70,7 @@ QT_BEGIN_NAMESPACE class QCocoaTouch { public: - static QList getCurrentTouchPointList(NSEvent *event, bool maskMouseHover); + static QList getCurrentTouchPointList(NSEvent *event, bool acceptSingleTouch); static void setMouseInDraggingState(bool inDraggingState); private: @@ -79,7 +79,7 @@ class QCocoaTouch static QPointF _trackpadReferencePos; static int _idAssignmentCount; static int _touchCount; - static bool _maskMouseHover; + static bool _updateInternalStateOnly; QTouchEvent::TouchPoint _touchPoint; QPointF _trackpadPos; -- cgit v0.12