Skip to content

Instantly share code, notes, and snippets.

@kenchris
Created April 3, 2012 16:00
Show Gist options
  • Save kenchris/2293169 to your computer and use it in GitHub Desktop.
Save kenchris/2293169 to your computer and use it in GitHub Desktop.
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