Created
November 7, 2011 14:14
-
-
Save kenchris/1345129 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/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