Skip to content

Instantly share code, notes, and snippets.

@kenchris
Created March 22, 2012 12:24
Show Gist options
  • Save kenchris/2158016 to your computer and use it in GitHub Desktop.
Save kenchris/2158016 to your computer and use it in GitHub Desktop.
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