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