Created
March 22, 2012 12:24
-
-
Save kenchris/2158016 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/ChangeLog b/Source/WebKit2/ChangeLog | |
index 9496aae..ea4bdde 100644 | |
--- a/Source/WebKit2/ChangeLog | |
+++ b/Source/WebKit2/ChangeLog | |
@@ -1,3 +1,27 @@ | |
+2012-03-22 Kenneth Rohde Christiansen <kenneth@webkit.org> | |
+ | |
+ [Qt] Fix some issues with the gesture recognizers | |
+ | |
+ Reviewed by NOBODY (OOPS!). | |
+ | |
+ Do the handling of 1 and 2 fingers outside of the individual | |
+ gesture recognizers. | |
+ | |
+ Add cancel methods to all gesture recognizers, which is separate | |
+ from the reset methods which are now private. | |
+ | |
+ * UIProcess/qt/QtPanGestureRecognizer.cpp: | |
+ (WebKit::QtPanGestureRecognizer::recognize): | |
+ * UIProcess/qt/QtPinchGestureRecognizer.cpp: | |
+ (WebKit::QtPinchGestureRecognizer::recognize): | |
+ * UIProcess/qt/QtTapGestureRecognizer.cpp: | |
+ (WebKit::QtTapGestureRecognizer::recognize): | |
+ * UIProcess/qt/QtViewportInteractionEngine.cpp: | |
+ (WebKit::QtViewportInteractionEngine::flickableMoveActive): | |
+ (WebKit): | |
+ * UIProcess/qt/QtViewportInteractionEngine.h: | |
+ (QtViewportInteractionEngine): | |
+ | |
2012-03-21 Kenneth Rohde Christiansen <kenneth@webkit.org> | |
The activation highlight does not always hide | |
diff --git a/Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp b/Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp | |
index 44a0d10..710bf0b 100644 | |
--- a/Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp | |
+++ b/Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp | |
@@ -210,7 +210,7 @@ void QQuickWebViewPrivate::didChangeBackForwardList() | |
void QQuickWebViewPrivate::processDidCrash() | |
{ | |
- pageView->eventHandler()->resetGestureRecognizers(); | |
+ pageView->eventHandler()->reset(); | |
QUrl url(KURL(WebCore::ParsedURLString, webPageProxy->urlAtProcessExit())); | |
if (m_loadStartedSignalSent) { | |
QWebLoadRequest loadRequest(url, QQuickWebView::LoadFailedStatus, QLatin1String("The web process crashed."), QQuickWebView::InternalErrorDomain, 0); | |
diff --git a/Source/WebKit2/UIProcess/qt/QtPanGestureRecognizer.cpp b/Source/WebKit2/UIProcess/qt/QtPanGestureRecognizer.cpp | |
index 431f8d8..2fa2314 100644 | |
--- a/Source/WebKit2/UIProcess/qt/QtPanGestureRecognizer.cpp | |
+++ b/Source/WebKit2/UIProcess/qt/QtPanGestureRecognizer.cpp | |
@@ -42,19 +42,13 @@ bool QtPanGestureRecognizer::recognize(const QTouchEvent* event) | |
if (!interactionEngine()) | |
return false; | |
+ ASSERT(event->touchPoints().size() == 1); | |
+ | |
// 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; | |
- // 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()) { | |
@@ -98,6 +92,13 @@ bool QtPanGestureRecognizer::recognize(const QTouchEvent* event) | |
return false; | |
} | |
+void QtPanGestureRecognizer::cancel() | |
+{ | |
+ if (m_state == GestureRecognized) | |
+ interactionEngine()->panGestureCancelled(); | |
+ reset(); | |
+} | |
+ | |
void QtPanGestureRecognizer::reset() | |
{ | |
QtGestureRecognizer::reset(); | |
diff --git a/Source/WebKit2/UIProcess/qt/QtPanGestureRecognizer.h b/Source/WebKit2/UIProcess/qt/QtPanGestureRecognizer.h | |
index e1e9ff3..368481a 100644 | |
--- a/Source/WebKit2/UIProcess/qt/QtPanGestureRecognizer.h | |
+++ b/Source/WebKit2/UIProcess/qt/QtPanGestureRecognizer.h | |
@@ -44,9 +44,11 @@ class QtPanGestureRecognizer : public QtGestureRecognizer { | |
public: | |
QtPanGestureRecognizer(QtWebPageEventHandler*); | |
bool recognize(const QTouchEvent*); | |
- void reset(); | |
+ void cancel(); | |
private: | |
+ void reset(); | |
+ | |
QPointF m_firstPosition; | |
QScopedPointer<QTouchEvent> m_touchBegin; | |
}; | |
diff --git a/Source/WebKit2/UIProcess/qt/QtPinchGestureRecognizer.cpp b/Source/WebKit2/UIProcess/qt/QtPinchGestureRecognizer.cpp | |
index 7699ad3..dcb55fe 100644 | |
--- a/Source/WebKit2/UIProcess/qt/QtPinchGestureRecognizer.cpp | |
+++ b/Source/WebKit2/UIProcess/qt/QtPinchGestureRecognizer.cpp | |
@@ -61,12 +61,8 @@ bool QtPinchGestureRecognizer::recognize(const QTouchEvent* event) | |
return false; | |
const QList<QTouchEvent::TouchPoint>& touchPoints = event->touchPoints(); | |
- if (touchPoints.size() < 2) { | |
- if (m_state == GestureRecognized) | |
- interactionEngine()->pinchGestureEnded(); | |
- reset(); | |
- return false; | |
- } | |
+ | |
+ ASSERT(touchPoints.size() == 2); | |
switch (event->type()) { | |
case QEvent::TouchBegin: | |
@@ -82,12 +78,12 @@ bool QtPinchGestureRecognizer::recognize(const QTouchEvent* event) | |
const int point1Index = findTouchPointIndex(touchPoints, m_point1); | |
if (point1Index < 0) { | |
- reset(); | |
+ cancel(); | |
return false; | |
} | |
const int point2Index = findTouchPointIndex(touchPoints, m_point2); | |
if (point2Index < 0) { | |
- reset(); | |
+ cancel(); | |
return false; | |
} | |
@@ -99,6 +95,7 @@ bool QtPinchGestureRecognizer::recognize(const QTouchEvent* event) | |
if (pinchDistance < pinchInitialTriggerDistanceThreshold) | |
return false; | |
m_state = GestureRecognized; | |
+ interactionEngine()->cancelScrollAnimation(); | |
interactionEngine()->pinchGestureStarted(computePinchCenter(point1, point2)); | |
// We reset the initial position to the previous position in order to avoid the jump caused | |
@@ -133,6 +130,13 @@ bool QtPinchGestureRecognizer::recognize(const QTouchEvent* event) | |
return false; | |
} | |
+void QtPinchGestureRecognizer::cancel() | |
+{ | |
+ if (m_state == GestureRecognized) | |
+ interactionEngine()->pinchGestureEnded(); | |
+ reset(); | |
+} | |
+ | |
void QtPinchGestureRecognizer::reset() | |
{ | |
QtGestureRecognizer::reset(); | |
diff --git a/Source/WebKit2/UIProcess/qt/QtPinchGestureRecognizer.h b/Source/WebKit2/UIProcess/qt/QtPinchGestureRecognizer.h | |
index 7dd3d91..e6c7082 100644 | |
--- a/Source/WebKit2/UIProcess/qt/QtPinchGestureRecognizer.h | |
+++ b/Source/WebKit2/UIProcess/qt/QtPinchGestureRecognizer.h | |
@@ -52,10 +52,11 @@ public: | |
QtPinchGestureRecognizer(QtWebPageEventHandler*); | |
bool recognize(const QTouchEvent*); | |
- void reset(); | |
+ void cancel(); | |
private: | |
void initializeGesture(const QList<QTouchEvent::TouchPoint>& touchPoints); | |
+ void reset(); | |
TouchPointInformation m_point1; | |
TouchPointInformation m_point2; | |
diff --git a/Source/WebKit2/UIProcess/qt/QtTapGestureRecognizer.cpp b/Source/WebKit2/UIProcess/qt/QtTapGestureRecognizer.cpp | |
index 7032220..d1dbc56 100644 | |
--- a/Source/WebKit2/UIProcess/qt/QtTapGestureRecognizer.cpp | |
+++ b/Source/WebKit2/UIProcess/qt/QtTapGestureRecognizer.cpp | |
@@ -39,10 +39,7 @@ QtTapGestureRecognizer::QtTapGestureRecognizer(QtWebPageEventHandler* eventHandl | |
bool QtTapGestureRecognizer::recognize(const QTouchEvent* event, qint64 eventTimestampMillis) | |
{ | |
- if (event->touchPoints().size() != 1) { | |
- reset(); | |
- return false; | |
- } | |
+ ASSERT(event->touchPoints().size() == 1); | |
switch (event->type()) { | |
case QEvent::TouchBegin: | |
@@ -52,7 +49,7 @@ bool QtTapGestureRecognizer::recognize(const QTouchEvent* event, qint64 eventTim | |
m_tapAndHoldTimer.start(tapAndHoldTime, this); | |
if (m_doubleTapTimer.isActive()) { | |
- // Might be double tap. | |
+ // Double tap. | |
ASSERT(m_touchBeginEventForTap); | |
m_doubleTapTimer.stop(); | |
QPointF lastPosition = m_touchBeginEventForTap->touchPoints().first().screenPos(); | |
@@ -61,11 +58,12 @@ bool QtTapGestureRecognizer::recognize(const QTouchEvent* event, qint64 eventTim | |
m_tapState = DoubleTapCandidate; | |
else { | |
// Received a new tap, that is unrelated to the previous one. | |
- tapTimeout(); | |
+ m_eventHandler->handlePotentialSingleTapEvent(QTouchEvent::TouchPoint()); | |
m_tapState = SingleTapStarted; | |
} | |
} else | |
m_tapState = SingleTapStarted; | |
+ | |
m_touchBeginEventForTap = adoptPtr(new QTouchEvent(*event)); | |
if (m_tapState == SingleTapStarted) { | |
@@ -81,7 +79,7 @@ bool QtTapGestureRecognizer::recognize(const QTouchEvent* event, qint64 eventTim | |
const qreal distX = qAbs(offset.x()); | |
const qreal distY = qAbs(offset.y()); | |
if (distX > initialTriggerDistanceThreshold || distY > initialTriggerDistanceThreshold) | |
- reset(); | |
+ cancel(); | |
} | |
break; | |
case QEvent::TouchEnd: | |
@@ -144,10 +142,15 @@ void QtTapGestureRecognizer::tapAndHoldTimeout() | |
m_doubleTapTimer.stop(); | |
} | |
-void QtTapGestureRecognizer::reset() | |
+void QtTapGestureRecognizer::cancel() | |
{ | |
m_eventHandler->handlePotentialSingleTapEvent(QTouchEvent::TouchPoint()); | |
+ reset(); | |
+} | |
+ | |
+void QtTapGestureRecognizer::reset() | |
+{ | |
m_tapState = NoTap; | |
m_touchBeginEventForTap.clear(); | |
m_tapAndHoldTimer.stop(); | |
diff --git a/Source/WebKit2/UIProcess/qt/QtTapGestureRecognizer.h b/Source/WebKit2/UIProcess/qt/QtTapGestureRecognizer.h | |
index a4ec41e..f927398 100644 | |
--- a/Source/WebKit2/UIProcess/qt/QtTapGestureRecognizer.h | |
+++ b/Source/WebKit2/UIProcess/qt/QtTapGestureRecognizer.h | |
@@ -51,7 +51,7 @@ class QtTapGestureRecognizer : public QObject, private QtGestureRecognizer { | |
public: | |
QtTapGestureRecognizer(QtWebPageEventHandler*); | |
bool recognize(const QTouchEvent*, qint64 eventTimestampMillis); | |
- void reset(); | |
+ void cancel(); | |
protected: | |
void timerEvent(QTimerEvent*); | |
@@ -59,6 +59,8 @@ protected: | |
void tapAndHoldTimeout(); | |
private: | |
+ void reset(); | |
+ | |
QBasicTimer m_doubleTapTimer; | |
QBasicTimer m_tapAndHoldTimer; | |
OwnPtr<QTouchEvent> m_touchBeginEventForTap; | |
diff --git a/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.cpp b/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.cpp | |
index 2ffafd7..6430dda 100644 | |
--- a/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.cpp | |
+++ b/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.cpp | |
@@ -218,6 +218,11 @@ void QtViewportInteractionEngine::flickableMoveEnded() | |
disconnect(m_flickProvider, SIGNAL(contentYChanged()), this, SLOT(flickableMovingPositionUpdate())); | |
} | |
+bool QtViewportInteractionEngine::flickableMoveActive() | |
+{ | |
+ return m_flickProvider->isMoving(); | |
+} | |
+ | |
void QtViewportInteractionEngine::flickableMovingPositionUpdate() | |
{ | |
QPointF newPosition = m_flickProvider->contentPos(); | |
diff --git a/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.h b/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.h | |
index b66defd..52acb5a 100644 | |
--- a/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.h | |
+++ b/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.h | |
@@ -100,6 +100,8 @@ public: | |
const Constraints& constraints() const { return m_constraints; } | |
qreal currentCSSScale(); | |
+ bool flickableMoveActive(); | |
+ | |
Q_SIGNALS: | |
void contentSuspendRequested(); | |
void contentResumeRequested(); | |
diff --git a/Source/WebKit2/UIProcess/qt/QtWebPageEventHandler.cpp b/Source/WebKit2/UIProcess/qt/QtWebPageEventHandler.cpp | |
index 280b99c..9cdf27e 100644 | |
--- a/Source/WebKit2/UIProcess/qt/QtWebPageEventHandler.cpp | |
+++ b/Source/WebKit2/UIProcess/qt/QtWebPageEventHandler.cpp | |
@@ -372,13 +372,6 @@ void QtWebPageEventHandler::handleTouchEvent(QTouchEvent* event) | |
#endif | |
} | |
-void QtWebPageEventHandler::resetGestureRecognizers() | |
-{ | |
- m_panGestureRecognizer.reset(); | |
- m_pinchGestureRecognizer.reset(); | |
- m_tapGestureRecognizer.reset(); | |
-} | |
- | |
static void setInputPanelVisible(bool visible) | |
{ | |
if (qApp->inputPanel()->visible() == visible) | |
@@ -432,6 +425,13 @@ void QtWebPageEventHandler::doneWithGestureEvent(const WebGestureEvent& event, b | |
setInputPanelVisible(newVisible); | |
} | |
+void QtWebPageEventHandler::reset() | |
+{ | |
+ m_panGestureRecognizer.cancel(); | |
+ m_pinchGestureRecognizer.cancel(); | |
+ m_tapGestureRecognizer.cancel(); | |
+} | |
+ | |
#if ENABLE(TOUCH_EVENTS) | |
void QtWebPageEventHandler::doneWithTouchEvent(const NativeWebTouchEvent& event, bool wasEventHandled) | |
{ | |
@@ -439,42 +439,35 @@ void QtWebPageEventHandler::doneWithTouchEvent(const NativeWebTouchEvent& event, | |
return; | |
if (wasEventHandled || event.type() == WebEvent::TouchCancel) { | |
- resetGestureRecognizers(); | |
+ m_panGestureRecognizer.cancel(); | |
+ m_pinchGestureRecognizer.cancel(); | |
+ m_tapGestureRecognizer.cancel(); | |
return; | |
} | |
const QTouchEvent* ev = event.nativeEvent(); | |
- switch (ev->type()) { | |
- case QEvent::TouchBegin: | |
- ASSERT(!m_interactionEngine->panGestureActive()); | |
- ASSERT(!m_interactionEngine->pinchGestureActive()); | |
- | |
- // The interaction engine might still be animating kinetic scrolling or a scale animation | |
- // such as double-tap to zoom or the bounce back effect. A touch stops the kinetic scrolling | |
- // where as it does not stop the scale animation. | |
- // Sending the event to the flickProvider will stop the kinetic scrolling animation. | |
- break; | |
- case QEvent::TouchUpdate: | |
- // The scale animation can only be interrupted by a pinch gesture, which will then take over. | |
- if (m_interactionEngine->scaleAnimationActive() && m_pinchGestureRecognizer.isRecognized()) | |
- m_interactionEngine->interruptScaleAnimation(); | |
- break; | |
- default: | |
- break; | |
- } | |
+ // The interaction might be animating kinetic scrolling (aka flicking) or a scale | |
+ // animation such as double-tap to zoom or the bounce back scale effect. | |
+ // | |
+ // The rules are simple: | |
+ // - two fingers touching can interrupt and take over any position/scale animation. | |
+ // - one finger touching can interrupt and take over any position change animation. | |
- // If the scale animation is active we don't pass the event to the recognizers. In the future | |
- // we would want to queue the event here and repost then when the animation ends. | |
- if (m_interactionEngine->scaleAnimationActive()) | |
- return; | |
+ if (ev->touchPoints().size() == 2) { | |
+ if (m_interactionEngine->scaleAnimationActive()) | |
+ m_interactionEngine->interruptScaleAnimation(); | |
- m_panGestureRecognizer.recognize(ev); | |
- m_pinchGestureRecognizer.recognize(ev); | |
+ m_panGestureRecognizer.cancel(); | |
+ m_tapGestureRecognizer.cancel(); | |
- if (m_panGestureRecognizer.isRecognized() || m_pinchGestureRecognizer.isRecognized()) | |
- m_tapGestureRecognizer.reset(); | |
- else { | |
+ m_pinchGestureRecognizer.recognize(ev); | |
+ } else if (ev->touchPoints().size() == 1) { | |
+ m_pinchGestureRecognizer.cancel(); | |
+ if (m_panGestureRecognizer.recognize(ev)) { | |
+ m_tapGestureRecognizer.cancel(); | |
+ return; | |
+ } | |
// Convert the event timestamp from second to millisecond. | |
qint64 eventTimestampMillis = static_cast<qint64>(event.timestamp() * 1000); | |
m_tapGestureRecognizer.recognize(ev, eventTimestampMillis); | |
diff --git a/Source/WebKit2/UIProcess/qt/QtWebPageEventHandler.h b/Source/WebKit2/UIProcess/qt/QtWebPageEventHandler.h | |
index 2040d28..6984011 100644 | |
--- a/Source/WebKit2/UIProcess/qt/QtWebPageEventHandler.h | |
+++ b/Source/WebKit2/UIProcess/qt/QtWebPageEventHandler.h | |
@@ -72,7 +72,8 @@ public: | |
#if ENABLE(TOUCH_EVENTS) | |
void doneWithTouchEvent(const NativeWebTouchEvent&, bool wasEventHandled); | |
#endif | |
- void resetGestureRecognizers(); | |
+ | |
+ void reset(); | |
QtViewportInteractionEngine* interactionEngine() { return m_interactionEngine; } | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment