Title: [113165] trunk/Source/WebKit2
- Revision
- 113165
- Author
- kenn...@webkit.org
- Date
- 2012-04-04 04:00:21 -0700 (Wed, 04 Apr 2012)
Log Message
[Qt] Improve the tap gesture recognizer
https://bugs.webkit.org/show_bug.cgi?id=83135
Reviewed by Simon Hausmann.
Clean up the code and make sure that the first single tap
event, as part of a double tap gesture, is ignored.
* UIProcess/qt/QtTapGestureRecognizer.cpp:
(WebKit::QtTapGestureRecognizer::withinDistance):
(WebKit):
(WebKit::QtTapGestureRecognizer::recognize):
(WebKit::QtTapGestureRecognizer::singleTapTimeout):
(WebKit::QtTapGestureRecognizer::tapAndHoldTimeout):
(WebKit::QtTapGestureRecognizer::reset):
* UIProcess/qt/QtTapGestureRecognizer.h:
(QtTapGestureRecognizer):
Modified Paths
Diff
Modified: trunk/Source/WebKit2/ChangeLog (113164 => 113165)
--- trunk/Source/WebKit2/ChangeLog 2012-04-04 10:56:25 UTC (rev 113164)
+++ trunk/Source/WebKit2/ChangeLog 2012-04-04 11:00:21 UTC (rev 113165)
@@ -1,3 +1,23 @@
+2012-04-04 Kenneth Rohde Christiansen <kenn...@webkit.org>
+
+ [Qt] Improve the tap gesture recognizer
+ https://bugs.webkit.org/show_bug.cgi?id=83135
+
+ Reviewed by Simon Hausmann.
+
+ Clean up the code and make sure that the first single tap
+ event, as part of a double tap gesture, is ignored.
+
+ * UIProcess/qt/QtTapGestureRecognizer.cpp:
+ (WebKit::QtTapGestureRecognizer::withinDistance):
+ (WebKit):
+ (WebKit::QtTapGestureRecognizer::recognize):
+ (WebKit::QtTapGestureRecognizer::singleTapTimeout):
+ (WebKit::QtTapGestureRecognizer::tapAndHoldTimeout):
+ (WebKit::QtTapGestureRecognizer::reset):
+ * UIProcess/qt/QtTapGestureRecognizer.h:
+ (QtTapGestureRecognizer):
+
2012-04-03 Geoffrey Garen <gga...@apple.com>
Fixed some WebKit2 crashes seen on the buildbot after my last patch.
Modified: trunk/Source/WebKit2/UIProcess/qt/QtTapGestureRecognizer.cpp (113164 => 113165)
--- trunk/Source/WebKit2/UIProcess/qt/QtTapGestureRecognizer.cpp 2012-04-04 10:56:25 UTC (rev 113164)
+++ trunk/Source/WebKit2/UIProcess/qt/QtTapGestureRecognizer.cpp 2012-04-04 11:00:21 UTC (rev 113165)
@@ -37,83 +37,59 @@
{
}
+bool QtTapGestureRecognizer::withinDistance(const QTouchEvent::TouchPoint& touchPoint, int distance)
+{
+ return QLineF(touchPoint.screenPos(), m_lastTouchEvent->touchPoints().first().screenPos()).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_doubleTapTimer.stop(); // Cancel other pending single tap event.
+ ASSERT(!m_tapAndHoldTimer.isActive());
m_tapAndHoldTimer.start(tapAndHoldTime, this);
- 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();
- m_tapState = SingleTapStarted;
- }
- } else
+ if (m_lastTouchEvent && withinDistance(touchPoint, maxDoubleTapDistance))
+ m_tapState = DoubleTapCandidate;
+ else {
m_tapState = SingleTapStarted;
- m_touchBeginEventForTap = adoptPtr(new QTouchEvent(*event));
-
- if (m_tapState == SingleTapStarted) {
- const QTouchEvent::TouchPoint& touchPoint = event->touchPoints().first();
+ // The below in facts resets any previous single tap event.
m_eventHandler->handlePotentialSingleTapEvent(touchPoint);
+ m_lastTouchEvent = adoptPtr(new QTouchEvent(*event));
+ m_doubleTapTimer.start(maxDoubleTapInterval, this);
}
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 && 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;
}
@@ -121,41 +97,38 @@
return false;
}
-void QtTapGestureRecognizer::tapTimeout()
+void QtTapGestureRecognizer::singleTapTimeout()
{
- 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);
+ const QTouchEvent::TouchPoint& touchPoint = m_lastTouchEvent->touchPoints().first();
+ WebGestureEvent event(WebEvent::GestureTapAndHold, touchPoint.pos().toPoint(), touchPoint.screenPos().toPoint(), WebEvent::Modifiers(0), 0);
+ m_eventHandler->handleGestureEvent(event);
#endif
- m_touchBeginEventForTap.clear();
- m_tapState = TapAndHold;
-
- ASSERT(!m_doubleTapTimer.isActive());
- m_doubleTapTimer.stop();
}
void QtTapGestureRecognizer::reset()
{
- if (m_tapState == NoTap)
- return;
+ if (m_tapState != NoTap)
+ m_eventHandler->handlePotentialSingleTapEvent(QTouchEvent::TouchPoint());
- m_eventHandler->handlePotentialSingleTapEvent(QTouchEvent::TouchPoint());
-
m_tapState = NoTap;
- m_touchBeginEventForTap.clear();
m_tapAndHoldTimer.stop();
+ m_doubleTapTimer.stop();
+ m_lastTouchEvent.clear();
QtGestureRecognizer::reset();
}
@@ -164,7 +137,7 @@
{
int timerId = ev->timerId();
if (timerId == m_doubleTapTimer.timerId())
- tapTimeout();
+ singleTapTimeout();
else if (timerId == m_tapAndHoldTimer.timerId())
tapAndHoldTimeout();
else
Modified: trunk/Source/WebKit2/UIProcess/qt/QtTapGestureRecognizer.h (113164 => 113165)
--- trunk/Source/WebKit2/UIProcess/qt/QtTapGestureRecognizer.h 2012-04-04 10:56:25 UTC (rev 113164)
+++ trunk/Source/WebKit2/UIProcess/qt/QtTapGestureRecognizer.h 2012-04-04 11:00:21 UTC (rev 113165)
@@ -28,20 +28,17 @@
#include "QtGestureRecognizer.h"
+#include <QTouchEvent>
#include <QtCore/QBasicTimer>
#include <QtCore/QObject>
#include <QtCore/QtGlobal>
#include <wtf/OwnPtr.h>
-QT_BEGIN_NAMESPACE
-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;
@@ -55,13 +52,15 @@
protected:
void timerEvent(QTimerEvent*);
- void tapTimeout();
+ void singleTapTimeout();
void tapAndHoldTimeout();
private:
+ bool withinDistance(const QTouchEvent::TouchPoint&, int distance);
+
QBasicTimer m_doubleTapTimer;
QBasicTimer m_tapAndHoldTimer;
- OwnPtr<QTouchEvent> m_touchBeginEventForTap;
+ OwnPtr<QTouchEvent> m_lastTouchEvent;
enum {
NoTap,
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes