Created
April 3, 2012 16:00
-
-
Save kenchris/2293169 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/Source/WebKit2/UIProcess/qt/QtTapGestureRecognizer.cpp b/Source/WebKit2/UIProcess/qt/QtTapGestureRecognizer.cpp | |
index d637366..17e8394 100644 | |
--- a/Source/WebKit2/UIProcess/qt/QtTapGestureRecognizer.cpp | |
+++ b/Source/WebKit2/UIProcess/qt/QtTapGestureRecognizer.cpp | |
@@ -37,83 +37,73 @@ QtTapGestureRecognizer::QtTapGestureRecognizer(QtWebPageEventHandler* eventHandl | |
{ | |
} | |
+static inline bool withinDistance(const QTouchEvent::TouchPoint& touchPoint, int distance) | |
+{ | |
+ return QLineF(touchPoint.screenPos(), touchPoint.lastScreenPos()).length() < distance; | |
+} | |
+ | |
bool QtTapGestureRecognizer::recognize(const QTouchEvent* event, qint64 eventTimestampMillis) | |
{ | |
+ ASSERT(m_eventHandler); | |
+ | |
if (event->touchPoints().size() != 1) { | |
reset(); | |
return false; | |
} | |
+ const QTouchEvent::TouchPoint& touchPoint = event->touchPoints().first(); | |
+ | |
switch (event->type()) { | |
case QEvent::TouchBegin: | |
ASSERT(m_tapState == NoTap); | |
- ASSERT(!m_tapAndHoldTimer.isActive()); | |
+ m_lastTouchEvent.clear(); // Cancel other single taps. | |
+ | |
+ ASSERT(!m_tapAndHoldTimer.isActive()); | |
m_tapAndHoldTimer.start(tapAndHoldTime, this); | |
+ m_tapState = SingleTapStarted; | |
+ | |
if (m_doubleTapTimer.isActive()) { | |
- // Might be double tap. | |
- ASSERT(m_touchBeginEventForTap); | |
m_doubleTapTimer.stop(); | |
- QPointF lastPosition = m_touchBeginEventForTap->touchPoints().first().screenPos(); | |
- QPointF newPosition = event->touchPoints().first().screenPos(); | |
- if (QLineF(lastPosition, newPosition).length() < maxDoubleTapDistance) | |
- m_tapState = DoubleTapCandidate; | |
- else { | |
- // Received a new tap, that is unrelated to the previous one. | |
- tapTimeout(); | |
+ | |
+ if (!withinDistance(touchPoint, maxDoubleTapDistance)) { | |
+ // Received a new tap, that is unrelated to the previous one. Ignore previous. | |
+ reset(); | |
m_tapState = SingleTapStarted; | |
- } | |
- } else | |
- m_tapState = SingleTapStarted; | |
- m_touchBeginEventForTap = adoptPtr(new QTouchEvent(*event)); | |
+ } else | |
+ m_tapState = DoubleTapCandidate; | |
+ } | |
if (m_tapState == SingleTapStarted) { | |
- const QTouchEvent::TouchPoint& touchPoint = event->touchPoints().first(); | |
m_eventHandler->handlePotentialSingleTapEvent(touchPoint); | |
+ m_doubleTapTimer.start(maxDoubleTapInterval, this); | |
+ m_lastTouchEvent = adoptPtr(new QTouchEvent(*event)); | |
} | |
+ | |
break; | |
+ | |
case QEvent::TouchUpdate: | |
// If the touch point moves further than the threshold, we cancel the tap gesture. | |
- if (m_tapState == SingleTapStarted) { | |
- const QTouchEvent::TouchPoint& touchPoint = event->touchPoints().first(); | |
- QPointF offset(touchPoint.scenePos() - m_touchBeginEventForTap->touchPoints().first().scenePos()); | |
- const qreal distX = qAbs(offset.x()); | |
- const qreal distY = qAbs(offset.y()); | |
- if (distX > initialTriggerDistanceThreshold || distY > initialTriggerDistanceThreshold) | |
- reset(); | |
- } | |
+ if (m_tapState == SingleTapStarted && !withinDistance(touchPoint, maxPanDistance)) | |
+ reset(); | |
break; | |
+ | |
case QEvent::TouchEnd: | |
m_tapAndHoldTimer.stop(); | |
+ | |
+ if (m_tapState == DoubleTapCandidate) { | |
+ m_doubleTapTimer.stop(); | |
+ if (withinDistance(touchPoint, maxDoubleTapDistance)) | |
+ m_eventHandler->handleDoubleTapEvent(touchPoint); | |
+ } | |
+ | |
if (m_tapState != NoTap) | |
m_eventHandler->handlePotentialSingleTapEvent(QTouchEvent::TouchPoint()); | |
- switch (m_tapState) { | |
- case DoubleTapCandidate: | |
- { | |
- ASSERT(!m_doubleTapTimer.isActive()); | |
- m_tapState = NoTap; | |
- | |
- const QTouchEvent::TouchPoint& touchPoint = event->touchPoints().first(); | |
- QPointF startPosition = touchPoint.startScreenPos(); | |
- QPointF endPosition = touchPoint.screenPos(); | |
- if (QLineF(endPosition, startPosition).length() < maxDoubleTapDistance && m_eventHandler) | |
- m_eventHandler->handleDoubleTapEvent(touchPoint); | |
- break; | |
- } | |
- case SingleTapStarted: | |
- ASSERT(!m_doubleTapTimer.isActive()); | |
- m_doubleTapTimer.start(doubleClickInterval, this); | |
- m_tapState = NoTap; | |
- break; | |
- case TapAndHold: | |
- m_tapState = NoTap; | |
- break; | |
- default: | |
- break; | |
- } | |
+ m_tapState = NoTap; | |
break; | |
+ | |
default: | |
break; | |
} | |
@@ -123,39 +113,37 @@ bool QtTapGestureRecognizer::recognize(const QTouchEvent* event, qint64 eventTim | |
void QtTapGestureRecognizer::tapTimeout() | |
{ | |
- m_doubleTapTimer.stop(); | |
- m_eventHandler->handleSingleTapEvent(m_touchBeginEventForTap->touchPoints().at(0)); | |
- m_touchBeginEventForTap.clear(); | |
+ ASSERT(m_lastTouchEvent); | |
+ | |
+ m_eventHandler->handlePotentialSingleTapEvent(QTouchEvent::TouchPoint()); | |
+ m_eventHandler->handleSingleTapEvent(m_lastTouchEvent->touchPoints().first()); | |
+ reset(); | |
} | |
void QtTapGestureRecognizer::tapAndHoldTimeout() | |
{ | |
- ASSERT(m_touchBeginEventForTap); | |
- m_tapAndHoldTimer.stop(); | |
+ ASSERT(m_lastTouchEvent); | |
+ | |
m_eventHandler->handlePotentialSingleTapEvent(QTouchEvent::TouchPoint()); | |
+ reset(); | |
+ | |
#if 0 // No support for synthetic context menus in WK2 yet. | |
QTouchEvent::TouchPoint tapPoint = m_touchBeginEventForTap->touchPoints().at(0); | |
WebGestureEvent gesture(WebEvent::GestureTapAndHold, tapPoint.pos().toPoint(), tapPoint.screenPos().toPoint(), WebEvent::Modifiers(0), 0); | |
if (m_webPageProxy) | |
m_webPageProxy->handleGestureEvent(gesture); | |
#endif | |
- m_touchBeginEventForTap.clear(); | |
- m_tapState = TapAndHold; | |
- | |
- ASSERT(!m_doubleTapTimer.isActive()); | |
- m_doubleTapTimer.stop(); | |
} | |
void QtTapGestureRecognizer::reset() | |
{ | |
- if (m_tapState == NoTap) | |
- return; | |
- | |
- m_eventHandler->handlePotentialSingleTapEvent(QTouchEvent::TouchPoint()); | |
+ if (m_tapState != NoTap) | |
+ m_eventHandler->handlePotentialSingleTapEvent(QTouchEvent::TouchPoint()); | |
m_tapState = NoTap; | |
- m_touchBeginEventForTap.clear(); | |
+ m_lastTouchEvent.clear(); | |
m_tapAndHoldTimer.stop(); | |
+ m_doubleTapTimer.stop(); | |
QtGestureRecognizer::reset(); | |
} | |
diff --git a/Source/WebKit2/UIProcess/qt/QtTapGestureRecognizer.h b/Source/WebKit2/UIProcess/qt/QtTapGestureRecognizer.h | |
index a4ec41e..791dfda 100644 | |
--- a/Source/WebKit2/UIProcess/qt/QtTapGestureRecognizer.h | |
+++ b/Source/WebKit2/UIProcess/qt/QtTapGestureRecognizer.h | |
@@ -38,10 +38,10 @@ class QTouchEvent; | |
QT_END_NAMESPACE | |
// FIXME: These constants should possibly depend on DPI. | |
-const qreal initialTriggerDistanceThreshold = 5; | |
-const qreal maxDoubleTapDistance = 120; | |
+const int maxPanDistance = 5; | |
+const int maxDoubleTapDistance = 120; | |
const int tapAndHoldTime = 800; | |
-const int doubleClickInterval = 400; | |
+const int maxDoubleTapInterval = 400; | |
class QtWebPageEventHandler; | |
@@ -61,7 +61,7 @@ protected: | |
private: | |
QBasicTimer m_doubleTapTimer; | |
QBasicTimer m_tapAndHoldTimer; | |
- OwnPtr<QTouchEvent> m_touchBeginEventForTap; | |
+ OwnPtr<QTouchEvent> m_lastTouchEvent; | |
enum { | |
NoTap, |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment