Title: [114389] trunk/Source/WebKit2
Revision
114389
Author
[email protected]
Date
2012-04-17 09:41:29 -0700 (Tue, 17 Apr 2012)

Log Message

[Qt][WK2] Refactor the gesture recognizers
https://bugs.webkit.org/show_bug.cgi?id=83044

Reviewed by Kenneth Rohde Christiansen and Simon Hausmann.

This patch implements a simple decision tree in the web page event handler
on the basis of how many active touch points the current touch event has.

Active touch points are pressed, moved or stationary and the number of these
fully determine which gesture recognizer should be updated, cancelled or
finished.

This new structure makes the internal states of the pinch and pan gesture
recognizers independent from the event type, thus makes it possible to handle
the transitions between these gestures in one centralized place which reduces
code duplication and complexity and fixes some issues regarding incorrectly
handled transitions.

* UIProcess/qt/QtPanGestureRecognizer.cpp:
(WebKit::QtPanGestureRecognizer::update):
(WebKit::QtPanGestureRecognizer::finish):
(WebKit):
(WebKit::QtPanGestureRecognizer::cancel):
* UIProcess/qt/QtPanGestureRecognizer.h:
(QtPanGestureRecognizer):
* UIProcess/qt/QtPinchGestureRecognizer.cpp:
(WebKit):
(WebKit::QtPinchGestureRecognizer::update):
(WebKit::QtPinchGestureRecognizer::finish):
* UIProcess/qt/QtPinchGestureRecognizer.h:
(QtPinchGestureRecognizer):
* UIProcess/qt/QtTapGestureRecognizer.cpp:
(WebKit::QtTapGestureRecognizer::withinDistance):
(WebKit::QtTapGestureRecognizer::update):
(WebKit::QtTapGestureRecognizer::cancel):
(WebKit):
(WebKit::QtTapGestureRecognizer::singleTapTimeout):
(WebKit::QtTapGestureRecognizer::tapAndHoldTimeout):
(WebKit::QtTapGestureRecognizer::reset):
* UIProcess/qt/QtTapGestureRecognizer.h:
(QtTapGestureRecognizer):
* UIProcess/qt/QtViewportInteractionEngine.cpp:
(WebKit):
* UIProcess/qt/QtViewportInteractionEngine.h:
(QtViewportInteractionEngine):
* UIProcess/qt/QtWebPageEventHandler.cpp:
(QtWebPageEventHandler::resetGestureRecognizers):
(QtWebPageEventHandler::doneWithTouchEvent):

Modified Paths

Diff

Modified: trunk/Source/WebKit2/ChangeLog (114388 => 114389)


--- trunk/Source/WebKit2/ChangeLog	2012-04-17 16:31:01 UTC (rev 114388)
+++ trunk/Source/WebKit2/ChangeLog	2012-04-17 16:41:29 UTC (rev 114389)
@@ -1,3 +1,54 @@
+2012-04-17  Andras Becsi  <[email protected]>
+
+        [Qt][WK2] Refactor the gesture recognizers
+        https://bugs.webkit.org/show_bug.cgi?id=83044
+
+        Reviewed by Kenneth Rohde Christiansen and Simon Hausmann.
+
+        This patch implements a simple decision tree in the web page event handler
+        on the basis of how many active touch points the current touch event has.
+
+        Active touch points are pressed, moved or stationary and the number of these
+        fully determine which gesture recognizer should be updated, cancelled or
+        finished.
+
+        This new structure makes the internal states of the pinch and pan gesture
+        recognizers independent from the event type, thus makes it possible to handle
+        the transitions between these gestures in one centralized place which reduces
+        code duplication and complexity and fixes some issues regarding incorrectly
+        handled transitions.
+
+        * UIProcess/qt/QtPanGestureRecognizer.cpp:
+        (WebKit::QtPanGestureRecognizer::update):
+        (WebKit::QtPanGestureRecognizer::finish):
+        (WebKit):
+        (WebKit::QtPanGestureRecognizer::cancel):
+        * UIProcess/qt/QtPanGestureRecognizer.h:
+        (QtPanGestureRecognizer):
+        * UIProcess/qt/QtPinchGestureRecognizer.cpp:
+        (WebKit):
+        (WebKit::QtPinchGestureRecognizer::update):
+        (WebKit::QtPinchGestureRecognizer::finish):
+        * UIProcess/qt/QtPinchGestureRecognizer.h:
+        (QtPinchGestureRecognizer):
+        * UIProcess/qt/QtTapGestureRecognizer.cpp:
+        (WebKit::QtTapGestureRecognizer::withinDistance):
+        (WebKit::QtTapGestureRecognizer::update):
+        (WebKit::QtTapGestureRecognizer::cancel):
+        (WebKit):
+        (WebKit::QtTapGestureRecognizer::singleTapTimeout):
+        (WebKit::QtTapGestureRecognizer::tapAndHoldTimeout):
+        (WebKit::QtTapGestureRecognizer::reset):
+        * UIProcess/qt/QtTapGestureRecognizer.h:
+        (QtTapGestureRecognizer):
+        * UIProcess/qt/QtViewportInteractionEngine.cpp:
+        (WebKit):
+        * UIProcess/qt/QtViewportInteractionEngine.h:
+        (QtViewportInteractionEngine):
+        * UIProcess/qt/QtWebPageEventHandler.cpp:
+        (QtWebPageEventHandler::resetGestureRecognizers):
+        (QtWebPageEventHandler::doneWithTouchEvent):
+
 2012-04-17  Allan Sandfeld Jensen  <[email protected]>
 
         REGRESSION(r113172) Wheel events are scrolling inversed.

Modified: trunk/Source/WebKit2/UIProcess/qt/QtPanGestureRecognizer.cpp (114388 => 114389)


--- trunk/Source/WebKit2/UIProcess/qt/QtPanGestureRecognizer.cpp	2012-04-17 16:31:01 UTC (rev 114388)
+++ trunk/Source/WebKit2/UIProcess/qt/QtPanGestureRecognizer.cpp	2012-04-17 16:41:29 UTC (rev 114389)
@@ -27,7 +27,6 @@
 #include "QtPanGestureRecognizer.h"
 
 #include "QtWebPageEventHandler.h"
-#include <QTouchEvent>
 
 namespace WebKit {
 
@@ -37,71 +36,58 @@
     reset();
 }
 
-bool QtPanGestureRecognizer::recognize(const QTouchEvent* event)
+bool QtPanGestureRecognizer::update(const QTouchEvent::TouchPoint& touchPoint, qint64 eventTimestampMillis)
 {
     if (!interactionEngine())
         return false;
 
-    // Pan gesture always starts on TouchBegin unless the engine is suspended, or
-    // we ignored the event.
-    if (m_state == NoGesture && event->type() != QEvent::TouchBegin)
-        return false;
+    m_lastPosition = touchPoint.pos();
+    m_lastEventTimestampMillis = eventTimestampMillis;
 
-    // Having multiple touch points cancel the panning gesture.
-    if (event->touchPoints().size() > 1) {
-        if (m_state == GestureRecognized)
-            interactionEngine()->panGestureCancelled();
-        reset();
-        return false;
-    }
-
-    const QTouchEvent::TouchPoint& touchPoint = event->touchPoints().first();
-
-    switch (event->type()) {
-    case QEvent::TouchBegin:
-        ASSERT(m_state == NoGesture);
+    switch (m_state) {
+    case NoGesture:
         m_state = GestureRecognitionStarted;
-        m_firstPosition = touchPoint.screenPos();
-        m_touchBegin.reset(new QTouchEvent(*event));
+        m_firstScreenPosition = touchPoint.scenePos();
         interactionEngine()->cancelScrollAnimation();
         return false;
-    case QEvent::TouchUpdate: {
-        ASSERT(m_state != NoGesture);
-        if (m_state == GestureRecognitionStarted) {
-            // To start the gesture, the delta from start in screen coordinates
-            // must be bigger than the trigger threshold.
-            QPointF totalOffsetFromStart(touchPoint.screenPos() - m_firstPosition);
-            if (qAbs(totalOffsetFromStart.x()) < panningInitialTriggerDistanceThreshold && qAbs(totalOffsetFromStart.y()) < panningInitialTriggerDistanceThreshold)
-                return false;
+    case GestureRecognitionStarted: {
+        // To start the gesture, the delta from start in screen coordinates
+        // must be bigger than the trigger threshold.
+        QPointF totalOffsetFromStart(touchPoint.scenePos() - m_firstScreenPosition);
+        if (qAbs(totalOffsetFromStart.x()) < panningInitialTriggerDistanceThreshold && qAbs(totalOffsetFromStart.y()) < panningInitialTriggerDistanceThreshold)
+            return false;
 
-            m_state = GestureRecognized;
-            ASSERT(m_touchBegin);
-            interactionEngine()->panGestureStarted(touchPoint.pos(), event->timestamp());
-        }
-
-        ASSERT(m_state == GestureRecognized);
-        interactionEngine()->panGestureRequestUpdate(touchPoint.pos(), event->timestamp());
+        m_state = GestureRecognized;
+        interactionEngine()->panGestureStarted(touchPoint.pos(), eventTimestampMillis);
         return true;
     }
-    case QEvent::TouchEnd:
-        if (m_state == GestureRecognized) {
-            interactionEngine()->panGestureEnded(touchPoint.pos(), event->timestamp());
-            reset();
-            return true;
-        }
-        ASSERT(m_state == GestureRecognitionStarted);
-        reset();
-        return false;
+    case GestureRecognized:
+        interactionEngine()->panGestureRequestUpdate(touchPoint.pos(), eventTimestampMillis);
+        return true;
     default:
         ASSERT_NOT_REACHED();
     }
     return false;
 }
 
-void QtPanGestureRecognizer::reset()
+void QtPanGestureRecognizer::finish(const QTouchEvent::TouchPoint& touchPoint, qint64 eventTimestampMillis)
 {
-    QtGestureRecognizer::reset();
-    m_firstPosition = QPointF();
+    if (m_state == NoGesture)
+        return;
+
+    ASSERT(interactionEngine());
+    interactionEngine()->panGestureEnded(touchPoint.pos(), eventTimestampMillis);
+    reset();
 }
 
+void QtPanGestureRecognizer::cancel()
+{
+    if (m_state == NoGesture)
+        return;
+
+    interactionEngine()->panGestureEnded(m_lastPosition, m_lastEventTimestampMillis);
+    interactionEngine()->panGestureCancelled();
+    reset();
+}
+
 } // namespace WebKit

Modified: trunk/Source/WebKit2/UIProcess/qt/QtPanGestureRecognizer.h (114388 => 114389)


--- trunk/Source/WebKit2/UIProcess/qt/QtPanGestureRecognizer.h	2012-04-17 16:31:01 UTC (rev 114388)
+++ trunk/Source/WebKit2/UIProcess/qt/QtPanGestureRecognizer.h	2012-04-17 16:41:29 UTC (rev 114389)
@@ -30,12 +30,8 @@
 
 #include <QPointF>
 #include <QScopedPointer>
-#include <QtCore/QtGlobal>
+#include <QTouchEvent>
 
-QT_BEGIN_NAMESPACE
-class QTouchEvent;
-QT_END_NAMESPACE
-
 namespace WebKit {
 
 const qreal panningInitialTriggerDistanceThreshold = 5.;
@@ -43,12 +39,14 @@
 class QtPanGestureRecognizer : public QtGestureRecognizer {
 public:
     QtPanGestureRecognizer(QtWebPageEventHandler*);
-    bool recognize(const QTouchEvent*);
-    void reset();
+    bool update(const QTouchEvent::TouchPoint&, qint64 eventTimestampMillis);
+    void finish(const QTouchEvent::TouchPoint&, qint64 eventTimestampMillis);
+    void cancel();
 
 private:
-    QPointF m_firstPosition;
-    QScopedPointer<QTouchEvent> m_touchBegin;
+    QPointF m_firstScreenPosition;
+    QPointF m_lastPosition;
+    qint64 m_lastEventTimestampMillis;
 };
 
 } // namespace WebKit

Modified: trunk/Source/WebKit2/UIProcess/qt/QtPinchGestureRecognizer.cpp (114388 => 114389)


--- trunk/Source/WebKit2/UIProcess/qt/QtPinchGestureRecognizer.cpp	2012-04-17 16:31:01 UTC (rev 114388)
+++ trunk/Source/WebKit2/UIProcess/qt/QtPinchGestureRecognizer.cpp	2012-04-17 16:41:29 UTC (rev 114389)
@@ -33,17 +33,6 @@
 
 const qreal pinchInitialTriggerDistanceThreshold = 5.;
 
-static inline int findTouchPointIndex(const QList<QTouchEvent::TouchPoint>& touchPoints, const QtPinchGestureRecognizer::TouchPointInformation& pointInformation)
-{
-    const int touchCount = touchPoints.size();
-    for (int i = 0; i < touchCount; ++i) {
-        const QTouchEvent::TouchPoint& touchPoint = touchPoints.at(i);
-        if (touchPoint.id() == pointInformation.id)
-            return i;
-    }
-    return -1;
-}
-
 static inline QPointF computePinchCenter(const QTouchEvent::TouchPoint& point1, const QTouchEvent::TouchPoint& point2)
 {
     return (point1.pos() + point2.pos()) / 2.0f;
@@ -55,103 +44,59 @@
     reset();
 }
 
-bool QtPinchGestureRecognizer::recognize(const QTouchEvent* event)
+bool QtPinchGestureRecognizer::update(const QTouchEvent::TouchPoint& point1, const QTouchEvent::TouchPoint& point2)
 {
-    if (!interactionEngine())
+    ASSERT(interactionEngine());
+    const qreal currentFingerDistance = QLineF(point1.screenPos(), point2.screenPos()).length();
+    switch (m_state) {
+    case NoGesture:
+        m_initialFingerDistance = currentFingerDistance;
+        m_state = GestureRecognitionStarted;
         return false;
-
-    const QList<QTouchEvent::TouchPoint>& touchPoints = event->touchPoints();
-    if (touchPoints.size() < 2) {
-        if (m_state == GestureRecognized)
-            interactionEngine()->pinchGestureEnded();
-        reset();
-        return false;
-    }
-
-    switch (event->type()) {
-    case QEvent::TouchBegin:
-    case QEvent::TouchUpdate:
-        switch (m_state) {
-        case NoGesture:
-            initializeGesture(touchPoints);
+    case GestureRecognitionStarted: {
+        const qreal pinchDistance = qAbs(currentFingerDistance - m_initialFingerDistance);
+        if (pinchDistance < pinchInitialTriggerDistanceThreshold)
             return false;
-        case GestureRecognitionStarted:
-        case GestureRecognized:
-            ASSERT(m_point1.isValid());
-            ASSERT(m_point2.isValid());
+        m_state = GestureRecognized;
+        interactionEngine()->pinchGestureStarted(computePinchCenter(point1, point2));
 
-            const int point1Index = findTouchPointIndex(touchPoints, m_point1);
-            if (point1Index < 0) {
-                reset();
-                return false;
-            }
-            const int point2Index = findTouchPointIndex(touchPoints, m_point2);
-            if (point2Index < 0) {
-                reset();
-                return false;
-            }
+        // We reset the initial span distance to the current distance of the
+        // touch points in order to avoid the jump caused by the events which
+        // were skipped between the recognition start and the actual recognition.
+        m_initialFingerDistance = currentFingerDistance;
 
-            const QTouchEvent::TouchPoint& point1 = touchPoints.at(point1Index);
-            const QTouchEvent::TouchPoint& point2 = touchPoints.at(point2Index);
-            if (m_state == GestureRecognitionStarted) {
-                // FIXME: The gesture should only start if the touch events were not accepted at the start of the touch sequence.
-                const qreal pinchDistance = qAbs(QLineF(point1.screenPos(), point2.screenPos()).length() - QLineF(m_point1.initialScreenPosition, m_point2.initialScreenPosition).length());
-                if (pinchDistance < pinchInitialTriggerDistanceThreshold)
-                    return false;
-                m_state = GestureRecognized;
-                interactionEngine()->pinchGestureStarted(computePinchCenter(point1, point2));
-
-                // We reset the initial position to the previous position in order to avoid the jump caused
-                // by skipping all the events between the beginning and when the threshold is hit.
-                m_point1.initialPosition = point1.lastPos();
-                m_point1.initialScreenPosition = point1.lastScreenPos();
-                m_point2.initialPosition = point2.lastPos();
-                m_point2.initialScreenPosition = point2.lastScreenPos();
-            }
-            ASSERT(m_state == GestureRecognized);
-            const qreal currentSpanDistance = QLineF(point1.screenPos(), point2.screenPos()).length();
-            const qreal initialSpanDistance = QLineF(m_point1.initialScreenPosition, m_point2.initialScreenPosition).length();
-            const qreal totalScaleFactor = currentSpanDistance / initialSpanDistance;
-            const QPointF touchCenterInViewCoordinates = computePinchCenter(point1, point2);
-            interactionEngine()->pinchGestureRequestUpdate(touchCenterInViewCoordinates, totalScaleFactor);
-            return true;
-            break;
-        }
+        // fall through
+    }
+    case GestureRecognized:
+        const qreal totalScaleFactor = currentFingerDistance / m_initialFingerDistance;
+        const QPointF touchCenterInViewCoordinates = computePinchCenter(point1, point2);
+        interactionEngine()->pinchGestureRequestUpdate(touchCenterInViewCoordinates, totalScaleFactor);
+        return true;
         break;
-    case QEvent::TouchEnd:
-        if (m_state == GestureRecognized) {
-            interactionEngine()->pinchGestureEnded();
-            reset();
-            return true;
-        }
-        reset();
-        break;
-    default:
-        ASSERT_NOT_REACHED();
     }
 
+    ASSERT_NOT_REACHED();
     return false;
 }
 
-void QtPinchGestureRecognizer::reset()
+void QtPinchGestureRecognizer::finish()
 {
-    QtGestureRecognizer::reset();
-    m_point1 = TouchPointInformation();
-    m_point2 = TouchPointInformation();
+    if (m_state == NoGesture)
+        return;
+
+    ASSERT(interactionEngine());
+    interactionEngine()->pinchGestureEnded();
+    reset();
 }
 
-void QtPinchGestureRecognizer::initializeGesture(const QList<QTouchEvent::TouchPoint>& touchPoints)
+void QtPinchGestureRecognizer::cancel()
 {
-    ASSERT(!m_point1.isValid());
-    ASSERT(!m_point2.isValid());
+    if (m_state == NoGesture)
+        return;
 
-    m_state = GestureRecognitionStarted;
-
-    m_point1 = TouchPointInformation(touchPoints.at(0));
-    m_point2 = TouchPointInformation(touchPoints.at(1));
-
-    ASSERT(m_point1.isValid());
-    ASSERT(m_point2.isValid());
+    ASSERT(interactionEngine());
+    interactionEngine()->pinchGestureCancelled();
+    reset();
 }
 
 }

Modified: trunk/Source/WebKit2/UIProcess/qt/QtPinchGestureRecognizer.h (114388 => 114389)


--- trunk/Source/WebKit2/UIProcess/qt/QtPinchGestureRecognizer.h	2012-04-17 16:31:01 UTC (rev 114388)
+++ trunk/Source/WebKit2/UIProcess/qt/QtPinchGestureRecognizer.h	2012-04-17 16:41:29 UTC (rev 114389)
@@ -32,10 +32,6 @@
 #include <QtCore/QList>
 #include <QtCore/QPointF>
 
-QT_BEGIN_NAMESPACE
-class QTouchEvent;
-QT_END_NAMESPACE
-
 namespace WebKit {
 
 class QtPinchGestureRecognizer : public QtGestureRecognizer {
@@ -51,33 +47,14 @@
     };
 
     QtPinchGestureRecognizer(QtWebPageEventHandler*);
-    bool recognize(const QTouchEvent*);
-    void reset();
+    bool update(const QTouchEvent::TouchPoint& point1, const QTouchEvent::TouchPoint& point2);
+    void finish();
+    void cancel();
 
 private:
-    void initializeGesture(const QList<QTouchEvent::TouchPoint>& touchPoints);
-
-    TouchPointInformation m_point1;
-    TouchPointInformation m_point2;
+    qreal m_initialFingerDistance;
 };
 
-inline QtPinchGestureRecognizer::TouchPointInformation::TouchPointInformation()
-    : id(-1)
-{
 }
 
-inline QtPinchGestureRecognizer::TouchPointInformation::TouchPointInformation(const QTouchEvent::TouchPoint& touchPoint)
-    : id(touchPoint.id())
-    , initialScreenPosition(touchPoint.screenPos())
-    , initialPosition(touchPoint.pos())
-{
-}
-
-inline bool QtPinchGestureRecognizer::TouchPointInformation::isValid() const
-{
-    return id >= 0;
-}
-
-}
-
 #endif /* QtPinchGestureRecognizer_h */

Modified: trunk/Source/WebKit2/UIProcess/qt/QtTapGestureRecognizer.cpp (114388 => 114389)


--- trunk/Source/WebKit2/UIProcess/qt/QtTapGestureRecognizer.cpp	2012-04-17 16:31:01 UTC (rev 114388)
+++ trunk/Source/WebKit2/UIProcess/qt/QtTapGestureRecognizer.cpp	2012-04-17 16:41:29 UTC (rev 114389)
@@ -39,34 +39,27 @@
 
 bool QtTapGestureRecognizer::withinDistance(const QTouchEvent::TouchPoint& touchPoint, int distance)
 {
-    return QLineF(touchPoint.screenPos(), m_lastTouchEvent->touchPoints().first().screenPos()).length() < distance;
+    return QLineF(touchPoint.screenPos(), m_lastTouchPoint.screenPos()).length() < distance;
 }
 
-bool QtTapGestureRecognizer::recognize(const QTouchEvent* event, qint64 eventTimestampMillis)
+bool QtTapGestureRecognizer::update(QEvent::Type eventType, const QTouchEvent::TouchPoint& touchPoint)
 {
     ASSERT(m_eventHandler);
 
-    if (event->touchPoints().size() != 1) {
-        reset();
-        return false;
-    }
-
-    const QTouchEvent::TouchPoint& touchPoint = event->touchPoints().first();
-
-    switch (event->type()) {
+    switch (eventType) {
     case QEvent::TouchBegin:
         m_doubleTapTimer.stop(); // Cancel other pending single tap event.
 
         ASSERT(!m_tapAndHoldTimer.isActive());
         m_tapAndHoldTimer.start(tapAndHoldTime, this);
 
-        if (m_lastTouchEvent && withinDistance(touchPoint, maxDoubleTapDistance))
+        if (m_lastTouchPoint.id() != -1 && withinDistance(touchPoint, maxDoubleTapDistance))
             m_candidate = DoubleTapCandidate;
         else {
             m_candidate = SingleTapCandidate;
             // The below in facts resets any previous single tap event.
             m_eventHandler->handlePotentialSingleTapEvent(touchPoint);
-            m_lastTouchEvent = adoptPtr(new QTouchEvent(*event));
+            m_lastTouchPoint = touchPoint;
             m_doubleTapTimer.start(maxDoubleTapInterval, this);
         }
         break;
@@ -98,30 +91,35 @@
     return false;
 }
 
+void QtTapGestureRecognizer::cancel()
+{
+    if (m_candidate == Invalid)
+        return;
+
+    reset();
+}
+
 void QtTapGestureRecognizer::singleTapTimeout()
 {
     // Finger is still pressed, ignore.
     if (m_tapAndHoldTimer.isActive())
         return;
 
-    ASSERT(m_lastTouchEvent);
-    const QTouchEvent::TouchPoint& touchPoint = m_lastTouchEvent->touchPoints().first();
+    ASSERT(m_lastTouchPoint.id() != -1);
 
     if (m_candidate == SingleTapCandidate) {
         m_eventHandler->handlePotentialSingleTapEvent(QTouchEvent::TouchPoint());
-        m_eventHandler->handleSingleTapEvent(touchPoint);
+        m_eventHandler->handleSingleTapEvent(m_lastTouchPoint);
     }
     reset();
 }
 
 void QtTapGestureRecognizer::tapAndHoldTimeout()
 {
-    ASSERT(m_lastTouchEvent);
+    ASSERT(m_lastTouchPoint.id() != -1);
 #if 0 // No support for synthetic context menus in WK2 yet.
-    const QTouchEvent::TouchPoint& touchPoint = m_lastTouchEvent->touchPoints().first();
-
     m_eventHandler->handlePotentialSingleTapEvent(QTouchEvent::TouchPoint());
-    m_eventHandler->handleTapAndHoldEvent(touchPoint);
+    m_eventHandler->handleTapAndHoldEvent(m_lastTouchPoint);
 #endif
     reset();
 }
@@ -134,7 +132,7 @@
     m_candidate = Invalid;
     m_tapAndHoldTimer.stop();
     m_doubleTapTimer.stop();
-    m_lastTouchEvent.clear();
+    m_lastTouchPoint.setId(-1);
 
     QtGestureRecognizer::reset();
 }

Modified: trunk/Source/WebKit2/UIProcess/qt/QtTapGestureRecognizer.h (114388 => 114389)


--- trunk/Source/WebKit2/UIProcess/qt/QtTapGestureRecognizer.h	2012-04-17 16:31:01 UTC (rev 114388)
+++ trunk/Source/WebKit2/UIProcess/qt/QtTapGestureRecognizer.h	2012-04-17 16:41:29 UTC (rev 114389)
@@ -47,8 +47,8 @@
 class QtTapGestureRecognizer : public QObject, private QtGestureRecognizer {
 public:
     QtTapGestureRecognizer(QtWebPageEventHandler*);
-    bool recognize(const QTouchEvent*, qint64 eventTimestampMillis);
-    void reset();
+    bool update(QEvent::Type eventType, const QTouchEvent::TouchPoint&);
+    void cancel();
 
 protected:
     void timerEvent(QTimerEvent*);
@@ -56,11 +56,12 @@
     void tapAndHoldTimeout();
 
 private:
+    void reset();
     bool withinDistance(const QTouchEvent::TouchPoint&, int distance);
 
     QBasicTimer m_doubleTapTimer;
     QBasicTimer m_tapAndHoldTimer;
-    OwnPtr<QTouchEvent> m_lastTouchEvent;
+    QTouchEvent::TouchPoint m_lastTouchPoint;
 
     enum {
         Invalid,

Modified: trunk/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.cpp (114388 => 114389)


--- trunk/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.cpp	2012-04-17 16:31:01 UTC (rev 114388)
+++ trunk/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.cpp	2012-04-17 16:41:29 UTC (rev 114389)
@@ -579,6 +579,12 @@
         m_scaleUpdateDeferrer.clear();
 }
 
+void QtViewportInteractionEngine::pinchGestureCancelled()
+{
+    m_pinchStartScale = -1;
+    m_scaleUpdateDeferrer.clear();
+}
+
 void QtViewportInteractionEngine::itemSizeChanged()
 {
     // FIXME: This needs to be done smarter. What happens if it resizes when we were interacting?

Modified: trunk/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.h (114388 => 114389)


--- trunk/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.h	2012-04-17 16:31:01 UTC (rev 114388)
+++ trunk/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.h	2012-04-17 16:41:29 UTC (rev 114389)
@@ -75,9 +75,11 @@
     void cancelScrollAnimation();
 
     bool panGestureActive() const;
+
     void panGestureStarted(const QPointF& position, qint64 eventTimestampMillis);
     void panGestureRequestUpdate(const QPointF& position, qint64 eventTimestampMillis);
     void panGestureEnded(const QPointF& position, qint64 eventTimestampMillis);
+
     void panGestureCancelled();
 
     bool scaleAnimationActive() const;
@@ -87,6 +89,7 @@
     void pinchGestureStarted(const QPointF& pinchCenterInViewportCoordinates);
     void pinchGestureRequestUpdate(const QPointF& pinchCenterInViewportCoordinates, qreal totalScaleFactor);
     void pinchGestureEnded();
+    void pinchGestureCancelled();
 
     void zoomToAreaGestureEnded(const QPointF& touchPoint, const QRectF& targetArea);
     void focusEditableArea(const QRectF& caretArea, const QRectF& targetArea);

Modified: trunk/Source/WebKit2/UIProcess/qt/QtWebPageEventHandler.cpp (114388 => 114389)


--- trunk/Source/WebKit2/UIProcess/qt/QtWebPageEventHandler.cpp	2012-04-17 16:31:01 UTC (rev 114388)
+++ trunk/Source/WebKit2/UIProcess/qt/QtWebPageEventHandler.cpp	2012-04-17 16:41:29 UTC (rev 114389)
@@ -373,9 +373,9 @@
 
 void QtWebPageEventHandler::resetGestureRecognizers()
 {
-    m_panGestureRecognizer.reset();
-    m_pinchGestureRecognizer.reset();
-    m_tapGestureRecognizer.reset();
+    m_panGestureRecognizer.cancel();
+    m_pinchGestureRecognizer.cancel();
+    m_tapGestureRecognizer.cancel();
 }
 
 static void setInputPanelVisible(bool visible)
@@ -472,16 +472,40 @@
     if (m_interactionEngine->scaleAnimationActive())
         return;
 
-    m_panGestureRecognizer.recognize(ev);
-    m_pinchGestureRecognizer.recognize(ev);
+    const QList<QTouchEvent::TouchPoint>& touchPoints = ev->touchPoints();
+    const int touchPointCount = touchPoints.size();
+    qint64 eventTimestampMillis = ev->timestamp();
+    QList<QTouchEvent::TouchPoint> activeTouchPoints;
+    activeTouchPoints.reserve(touchPointCount);
 
+    for (int i = 0; i < touchPointCount; ++i) {
+        if (touchPoints[i].state() != Qt::TouchPointReleased)
+            activeTouchPoints << touchPoints[i];
+    }
+
+    const int activeTouchPointCount = activeTouchPoints.size();
+
+    if (!activeTouchPointCount) {
+        if (touchPointCount == 1)
+           // No active touch points, one finger released.
+           m_panGestureRecognizer.finish(touchPoints.first(), eventTimestampMillis);
+        else
+           m_pinchGestureRecognizer.finish();
+    } else if (activeTouchPointCount == 1) {
+        // If the pinch gesture recognizer was previously in active state the content might
+        // be out of valid zoom boundaries, thus we need to finish the pinch gesture here.
+        // This will resume the content to valid zoom levels before the pan gesture is started.
+        m_pinchGestureRecognizer.finish();
+        m_panGestureRecognizer.update(activeTouchPoints.first(), eventTimestampMillis);
+    } else if (activeTouchPointCount == 2) {
+        m_panGestureRecognizer.cancel();
+        m_pinchGestureRecognizer.update(activeTouchPoints.first(), activeTouchPoints.last());
+    }
+
     if (m_panGestureRecognizer.isRecognized() || m_pinchGestureRecognizer.isRecognized())
-        m_tapGestureRecognizer.reset();
-    else {
-        // Convert the event timestamp from second to millisecond.
-        qint64 eventTimestampMillis = static_cast<qint64>(event.timestamp() * 1000);
-        m_tapGestureRecognizer.recognize(ev, eventTimestampMillis);
-    }
+        m_tapGestureRecognizer.cancel();
+    else if (touchPointCount == 1)
+        m_tapGestureRecognizer.update(ev->type(), touchPoints.first());
 }
 #endif
 
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to