Skip to content

Instantly share code, notes, and snippets.

@kenchris
Created November 7, 2011 14:14
Show Gist options
  • Save kenchris/1345129 to your computer and use it in GitHub Desktop.
Save kenchris/1345129 to your computer and use it in GitHub Desktop.
diff --git a/Source/WebKit2/UIProcess/qt/QtGestureRecognizer.h b/Source/WebKit2/UIProcess/qt/QtGestureRecognizer.h
index 0994c46..f5222c7 100644
--- a/Source/WebKit2/UIProcess/qt/QtGestureRecognizer.h
+++ b/Source/WebKit2/UIProcess/qt/QtGestureRecognizer.h
@@ -31,6 +31,9 @@ namespace WebKit {
class QtViewportInteractionEngine;
class QtGestureRecognizer {
+public:
+ bool isRecognized() const { return m_state == GestureRecognized; }
+
protected:
QtGestureRecognizer(QtViewportInteractionEngine*);
void reset();
diff --git a/Source/WebKit2/UIProcess/qt/QtPanGestureRecognizer.cpp b/Source/WebKit2/UIProcess/qt/QtPanGestureRecognizer.cpp
index 1fa620f..40c979a 100644
--- a/Source/WebKit2/UIProcess/qt/QtPanGestureRecognizer.cpp
+++ b/Source/WebKit2/UIProcess/qt/QtPanGestureRecognizer.cpp
@@ -57,15 +57,6 @@ bool QtPanGestureRecognizer::recognize(const QTouchEvent* event, qint64 eventTim
switch (event->type()) {
case QEvent::TouchBegin:
ASSERT(m_state == NoGesture);
- // The pan gesture might still be animating kinetic scrolling/bounce back effect.
- if (m_viewportInteractionEngine->panAnimationActive())
- m_viewportInteractionEngine->panGestureCancelled();
-
- // We do not stop bounce back effects for pinch zoom, but instead ignore the touch event.
- // FIXME: We should queue the events instead and repost then when done with the animation.
- if (m_viewportInteractionEngine->pinchAnimationActive())
- return false;
-
m_state = GestureRecognitionStarted;
m_firstPosition = touchPoint.screenPos();
return false;
diff --git a/Source/WebKit2/UIProcess/qt/QtPanGestureRecognizer.h b/Source/WebKit2/UIProcess/qt/QtPanGestureRecognizer.h
index 2f27537..29caf06 100644
--- a/Source/WebKit2/UIProcess/qt/QtPanGestureRecognizer.h
+++ b/Source/WebKit2/UIProcess/qt/QtPanGestureRecognizer.h
@@ -39,7 +39,7 @@ namespace WebKit {
const qreal panningInitialTriggerDistanceThreshold = 5.;
-class QtPanGestureRecognizer : private QtGestureRecognizer {
+class QtPanGestureRecognizer : public QtGestureRecognizer {
public:
QtPanGestureRecognizer(QtViewportInteractionEngine*);
bool recognize(const QTouchEvent*, qint64 eventTimestampMillis);
diff --git a/Source/WebKit2/UIProcess/qt/QtPinchGestureRecognizer.cpp b/Source/WebKit2/UIProcess/qt/QtPinchGestureRecognizer.cpp
index 892b773..16db5dd 100644
--- a/Source/WebKit2/UIProcess/qt/QtPinchGestureRecognizer.cpp
+++ b/Source/WebKit2/UIProcess/qt/QtPinchGestureRecognizer.cpp
@@ -65,15 +65,6 @@ bool QtPinchGestureRecognizer::recognize(const QTouchEvent* event)
return false;
}
- // The pan gesture might still be animating kinetic scrolling/bounce back effect.
- if (m_viewportInteractionEngine->panAnimationActive())
- m_viewportInteractionEngine->panGestureCancelled();
-
- // We do not stop bounce back effects for pinch zoom, but instead ignore the touch event.
- // FIXME: We should queue the events instead and repost then when done with the animation.
- if (m_viewportInteractionEngine->pinchAnimationActive())
- return false;
-
switch (event->type()) {
case QEvent::TouchBegin:
case QEvent::TouchUpdate:
diff --git a/Source/WebKit2/UIProcess/qt/QtPinchGestureRecognizer.h b/Source/WebKit2/UIProcess/qt/QtPinchGestureRecognizer.h
index 4cec8aa..30d15fc 100644
--- a/Source/WebKit2/UIProcess/qt/QtPinchGestureRecognizer.h
+++ b/Source/WebKit2/UIProcess/qt/QtPinchGestureRecognizer.h
@@ -38,7 +38,7 @@ QT_END_NAMESPACE
namespace WebKit {
-class QtPinchGestureRecognizer : private QtGestureRecognizer {
+class QtPinchGestureRecognizer : public QtGestureRecognizer {
public:
struct TouchPointInformation {
inline TouchPointInformation();
diff --git a/Source/WebKit2/UIProcess/qt/QtTouchWebPageProxy.cpp b/Source/WebKit2/UIProcess/qt/QtTouchWebPageProxy.cpp
index ef38d33..e226cb4 100644
--- a/Source/WebKit2/UIProcess/qt/QtTouchWebPageProxy.cpp
+++ b/Source/WebKit2/UIProcess/qt/QtTouchWebPageProxy.cpp
@@ -25,12 +25,14 @@
#include <IntRect.h>
#include <NativeWebTouchEvent.h>
#include <WebEventFactoryQt.h>
+#include "QtViewportInteractionEngine.h"
#include <qwebpreferences_p.h>
using namespace WebCore;
QtTouchWebPageProxy::QtTouchWebPageProxy(QtTouchViewInterface* viewInterface, QtViewportInteractionEngine* viewportInteractionEngine)
: QtWebPageProxy(viewInterface, 0)
+ , m_interactionEngine(viewportInteractionEngine)
, m_panGestureRecognizer(viewportInteractionEngine)
, m_pinchGestureRecognizer(viewportInteractionEngine)
{
@@ -67,12 +69,42 @@ void QtTouchWebPageProxy::doneWithTouchEvent(const NativeWebTouchEvent& event, b
if (wasEventHandled || event.type() == WebEvent::TouchCancel) {
m_panGestureRecognizer.reset();
m_pinchGestureRecognizer.reset();
- } else {
- // Convert the event timestamp from second to millisecond.
- qint64 eventTimestampMillis = static_cast<qint64>(event.timestamp() * 1000);
- m_panGestureRecognizer.recognize(event.nativeEvent(), eventTimestampMillis);
- m_pinchGestureRecognizer.recognize(event.nativeEvent());
+ 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.
+ if (m_interactionEngine->scrollAnimationActive())
+ m_interactionEngine->panGestureCancelled();
+ 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;
+
+ // 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()) {
+ const_cast<QTouchEvent*>(ev)->ignore();
+ return;
+ }
+
+ // Convert the event timestamp from second to millisecond.
+ qint64 eventTimestampMillis = static_cast<qint64>(event.timestamp() * 1000);
+ m_panGestureRecognizer.recognize(ev, eventTimestampMillis);
+ m_pinchGestureRecognizer.recognize(ev);
}
#endif
diff --git a/Source/WebKit2/UIProcess/qt/QtTouchWebPageProxy.h b/Source/WebKit2/UIProcess/qt/QtTouchWebPageProxy.h
index b125a8f3..1fad15b 100644
--- a/Source/WebKit2/UIProcess/qt/QtTouchWebPageProxy.h
+++ b/Source/WebKit2/UIProcess/qt/QtTouchWebPageProxy.h
@@ -61,6 +61,7 @@ private:
void touchEvent(QTouchEvent*);
+ QtViewportInteractionEngine* m_interactionEngine;
QtPanGestureRecognizer m_panGestureRecognizer;
QtPinchGestureRecognizer m_pinchGestureRecognizer;
};
diff --git a/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.cpp b/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.cpp
index 287a446..b073c39 100644
--- a/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.cpp
+++ b/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.cpp
@@ -204,7 +204,7 @@ static inline QPointF boundPosition(const QPointF minPosition, const QPointF& po
void QtViewportInteractionEngine::pagePositionRequest(const QPoint& pagePosition)
{
// FIXME: Assert when we are suspending properly.
- if (panAnimationActive() || pinchAnimationActive() || m_pinchViewportUpdateDeferrer)
+ if (scrollAnimationActive() || scaleAnimationActive() || pinchGestureActive())
return; // Ignore.
qreal endItemScale = m_content->scale(); // Stay at same scale.
@@ -230,7 +230,7 @@ QRectF QtViewportInteractionEngine::computePosRangeForItemAtScale(qreal itemScal
void QtViewportInteractionEngine::ensureContentWithinViewportBoundary()
{
- if (panAnimationActive() || pinchAnimationActive())
+ if (scrollAnimationActive() || scaleAnimationActive())
return;
qreal currentCSSScale = cssScaleFromItem(m_content->scale());
@@ -302,11 +302,23 @@ void QtViewportInteractionEngine::setConstraints(const Constraints& constraints)
ensureContentWithinViewportBoundary();
}
-bool QtViewportInteractionEngine::panAnimationActive() const
+bool QtViewportInteractionEngine::scrollAnimationActive() const
{
QScroller* scroller = const_cast<QtViewportInteractionEngine*>(this)->scroller();
+ return scroller->state() == QScroller::Scrolling;
+}
+
+void QtViewportInteractionEngine::interruptScrollAnimation()
+{
+ // Stopping the scroller immediately stops kinetic scrolling and if the view is out of bounds it
+ // is moved inside valid bounds immediately as well. This is the behavior that we want.
+ scroller()->stop();
+}
- return scroller->state() != QScroller::Inactive;
+bool QtViewportInteractionEngine::panGestureActive() const
+{
+ QScroller* scroller = const_cast<QtViewportInteractionEngine*>(this)->scroller();
+ return scroller->state() == QScroller::Pressed || scroller->state() == QScroller::Dragging;
}
void QtViewportInteractionEngine::panGestureStarted(const QPointF& touchPoint, qint64 eventTimestampMillis)
@@ -335,11 +347,22 @@ void QtViewportInteractionEngine::panGestureEnded(const QPointF& touchPoint, qin
scroller()->handleInput(QScroller::InputRelease, m_viewport->mapFromItem(m_content, touchPoint), eventTimestampMillis);
}
-bool QtViewportInteractionEngine::pinchAnimationActive() const
+bool QtViewportInteractionEngine::scaleAnimationActive() const
{
return m_scaleAnimation->state() == QAbstractAnimation::Running;
}
+void QtViewportInteractionEngine::interruptScaleAnimation()
+{
+ // This interrupts the scale animation exactly where it is, even if it is out of bounds.
+ m_scaleAnimation->stop();
+}
+
+bool QtViewportInteractionEngine::pinchGestureActive() const
+{
+ return !!m_pinchViewportUpdateDeferrer;
+}
+
void QtViewportInteractionEngine::pinchGestureStarted(const QPointF& pinchCenterInContentCoordinates)
{
if (!m_constraints.isUserScalable)
diff --git a/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.h b/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.h
index dfcceab..a6ce19f 100644
--- a/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.h
+++ b/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.h
@@ -68,13 +68,19 @@ public:
void pagePositionRequest(const QPoint& pos);
- bool panAnimationActive() const;
+ bool scrollAnimationActive() const;
+ void interruptScrollAnimation();
+
+ bool panGestureActive() const;
void panGestureStarted(const QPointF& touchPoint, qint64 eventTimestampMillis);
void panGestureRequestUpdate(const QPointF& touchPoint, qint64 eventTimestampMillis);
void panGestureCancelled();
void panGestureEnded(const QPointF& touchPoint, qint64 eventTimestampMillis);
- bool pinchAnimationActive() const;
+ bool scaleAnimationActive() const;
+ void interruptScaleAnimation();
+
+ bool pinchGestureActive() const;
void pinchGestureStarted(const QPointF& pinchCenterInContentCoordinates);
void pinchGestureRequestUpdate(const QPointF& pinchCenterInContentCoordinates, qreal totalScaleFactor);
void pinchGestureEnded();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment