diff options
5 files changed, 80 insertions, 60 deletions
diff --git a/Source/WebKit2/UIProcess/PageViewportController.cpp b/Source/WebKit2/UIProcess/PageViewportController.cpp index 05ff8b98a..a34782c8f 100644 --- a/Source/WebKit2/UIProcess/PageViewportController.cpp +++ b/Source/WebKit2/UIProcess/PageViewportController.cpp @@ -45,7 +45,6 @@ PageViewportController::PageViewportController(WebKit::WebPageProxy* proxy, Page , m_allowsUserScaling(false) , m_minimumScaleToFit(1) , m_initiallyFitToViewport(true) - , m_hasSuspendedContent(false) , m_hadUserInteraction(false) , m_pageScaleFactor(1) , m_viewportPosIsLocked(false) @@ -177,7 +176,7 @@ void PageViewportController::pageTransitionViewportReady() void PageViewportController::pageDidRequestScroll(const IntPoint& cssPosition) { // Ignore the request if suspended. Can only happen due to delay in event delivery. - if (m_hasSuspendedContent) + if (m_webPageProxy->areActiveDOMObjectsAndAnimationsSuspended()) return; FloatRect endVisibleContentRect(clampViewportToContents(cssPosition, m_pageScaleFactor), viewportSizeInContentsCoordinates()); @@ -246,26 +245,6 @@ WebCore::FloatSize PageViewportController::viewportSizeInContentsCoordinates() c return WebCore::FloatSize(m_viewportSize.width() / m_pageScaleFactor, m_viewportSize.height() / m_pageScaleFactor); } -void PageViewportController::suspendContent() -{ - if (m_hasSuspendedContent) - return; - - m_hasSuspendedContent = true; - m_webPageProxy->suspendActiveDOMObjectsAndAnimations(); -} - -void PageViewportController::resumeContent() -{ - m_client->didResumeContent(); - - if (!m_hasSuspendedContent) - return; - - m_hasSuspendedContent = false; - m_webPageProxy->resumeActiveDOMObjectsAndAnimations(); -} - void PageViewportController::applyScaleAfterRenderingContents(float scale) { m_pageScaleFactor = scale; @@ -295,7 +274,7 @@ bool PageViewportController::updateMinimumScaleToFit(bool userInitiatedUpdate) if (!fuzzyCompare(minimumScale, m_minimumScaleToFit, 0.001)) { m_minimumScaleToFit = minimumScale; - if (!hasSuspendedContent()) { + if (!m_webPageProxy->areActiveDOMObjectsAndAnimationsSuspended()) { if (!m_hadUserInteraction || (userInitiatedUpdate && currentlyScaledToFit)) applyScaleAfterRenderingContents(m_minimumScaleToFit); else { diff --git a/Source/WebKit2/UIProcess/PageViewportController.h b/Source/WebKit2/UIProcess/PageViewportController.h index dadbbbefe..fcc4e170d 100644 --- a/Source/WebKit2/UIProcess/PageViewportController.h +++ b/Source/WebKit2/UIProcess/PageViewportController.h @@ -22,8 +22,6 @@ #ifndef PageViewportController_h #define PageViewportController_h -#if USE(TILED_BACKING_STORE) - #include <WebCore/FloatPoint.h> #include <WebCore/FloatRect.h> #include <WebCore/FloatSize.h> @@ -47,14 +45,10 @@ public: PageViewportController(WebKit::WebPageProxy*, PageViewportControllerClient*); virtual ~PageViewportController() { } - void suspendContent(); - void resumeContent(); - float innerBoundedViewportScale(float) const; float outerBoundedViewportScale(float) const; WebCore::FloatPoint clampViewportToContents(const WebCore::FloatPoint& viewportPos, float viewportScale); - bool hasSuspendedContent() const { return m_hasSuspendedContent; } bool hadUserInteraction() const { return m_hadUserInteraction; } bool allowsUserScaling() const { return m_allowsUserScaling; } @@ -94,7 +88,6 @@ private: float m_minimumScaleToFit; bool m_initiallyFitToViewport; - bool m_hasSuspendedContent; bool m_hadUserInteraction; WebCore::FloatPoint m_viewportPos; @@ -112,6 +105,4 @@ bool fuzzyCompare(float, float, float epsilon); } // namespace WebKit -#endif - #endif // PageViewportController_h diff --git a/Source/WebKit2/UIProcess/WebPageProxy.h b/Source/WebKit2/UIProcess/WebPageProxy.h index ff8ec5133..1b2e9a2b7 100644 --- a/Source/WebKit2/UIProcess/WebPageProxy.h +++ b/Source/WebKit2/UIProcess/WebPageProxy.h @@ -472,6 +472,7 @@ public: void setCustomTextEncodingName(const String&); String customTextEncodingName() const { return m_customTextEncodingName; } + bool areActiveDOMObjectsAndAnimationsSuspended() const { return m_isPageSuspended; } void resumeActiveDOMObjectsAndAnimations(); void suspendActiveDOMObjectsAndAnimations(); diff --git a/Source/WebKit2/UIProcess/qt/PageViewportControllerClientQt.cpp b/Source/WebKit2/UIProcess/qt/PageViewportControllerClientQt.cpp index c0eb16ab9..61f2aaf57 100644 --- a/Source/WebKit2/UIProcess/qt/PageViewportControllerClientQt.cpp +++ b/Source/WebKit2/UIProcess/qt/PageViewportControllerClientQt.cpp @@ -23,12 +23,14 @@ #include "config.h" #include "PageViewportControllerClientQt.h" +#include "WebPageProxy.h" #include "qquickwebpage_p.h" #include "qquickwebview_p.h" #include "qwebkittest_p.h" #include <QPointF> #include <QTransform> #include <QtQuick/qquickitem.h> +#include <WKAPICast.h> #include <WebCore/FloatRect.h> #include <WebCore/FloatSize.h> @@ -41,12 +43,14 @@ static const int kScaleAnimationDurationMillis = 250; PageViewportControllerClientQt::PageViewportControllerClientQt(QQuickWebView* viewportItem, QQuickWebPage* pageItem) : m_viewportItem(viewportItem) , m_pageItem(pageItem) + , m_scaleChange(this) + , m_scrollChange(this) + , m_touchInteraction(this, false /* shouldSuspend */) , m_scaleAnimation(new ScaleAnimation(this)) + , m_activeInteractionCount(0) , m_pinchStartScale(-1) , m_lastCommittedScale(-1) , m_zoomOutScale(0) - , m_isUserInteracting(false) - , m_ignoreViewportChanges(false) { m_scaleAnimation->setDuration(kScaleAnimationDurationMillis); m_scaleAnimation->setEasingCurve(QEasingCurve::OutCubic); @@ -76,6 +80,32 @@ void PageViewportControllerClientQt::ScaleAnimation::updateCurrentValue(const QV m_controllerClient->setContentRectVisiblePositionAtScale(itemRect.topLeft(), itemScale); } +void PageViewportControllerClientQt::ViewportInteractionTracker::begin() +{ + if (m_inProgress) + return; + + m_inProgress = true; + + if (m_shouldSuspend) + toImpl(m_controllerClient->m_viewportItem->pageRef())->suspendActiveDOMObjectsAndAnimations(); + + ++(m_controllerClient->m_activeInteractionCount); +} + +void PageViewportControllerClientQt::ViewportInteractionTracker::end() +{ + if (!m_inProgress) + return; + + m_inProgress = false; + + ASSERT(m_controllerClient->m_activeInteractionCount > 0); + + if (!(--(m_controllerClient->m_activeInteractionCount))) + toImpl(m_controllerClient->m_viewportItem->pageRef())->resumeActiveDOMObjectsAndAnimations(); +} + PageViewportControllerClientQt::~PageViewportControllerClientQt() { } @@ -103,7 +133,8 @@ void PageViewportControllerClientQt::animateContentRectVisible(const QRectF& con QRectF viewportRectInContentCoords = m_viewportItem->mapRectToWebContent(m_viewportItem->boundingRect()); if (contentRect == viewportRectInContentCoords) { - m_controller->resumeContent(); + m_scaleChange.end(); + updateViewportController(); return; } @@ -121,22 +152,20 @@ void PageViewportControllerClientQt::animateContentRectVisible(const QRectF& con void PageViewportControllerClientQt::flickMoveStarted() { - m_controller->suspendContent(); - + m_scrollChange.begin(); m_lastScrollPosition = m_viewportItem->contentPos(); } void PageViewportControllerClientQt::flickMoveEnded() { // This method is called on the end of the pan or pan kinetic animation. - - if (!m_isUserInteracting) - m_controller->resumeContent(); + m_scrollChange.end(); + updateViewportController(); } void PageViewportControllerClientQt::pageItemPositionChanged() { - if (m_ignoreViewportChanges) + if (m_scaleChange.inProgress()) return; QPointF newPosition = m_viewportItem->contentPos(); @@ -150,13 +179,11 @@ void PageViewportControllerClientQt::scaleAnimationStateChanged(QAbstractAnimati { switch (newState) { case QAbstractAnimation::Running: - m_ignoreViewportChanges = true; - m_viewportItem->cancelFlick(); - m_controller->suspendContent(); + m_scaleChange.begin(); break; case QAbstractAnimation::Stopped: - m_ignoreViewportChanges = false; - m_controller->resumeContent(); + m_scaleChange.end(); + updateViewportController(); break; default: break; @@ -167,13 +194,14 @@ void PageViewportControllerClientQt::touchBegin() { m_controller->setHadUserInteraction(true); - // Prevents resuming the page between the user's flicks of the page. - m_isUserInteracting = true; + // Prevent resuming the page during transition between gestures while the user is interacting. + // The content is suspended as soon as a pan or pinch gesture or an animation is started. + m_touchInteraction.begin(); } void PageViewportControllerClientQt::touchEnd() { - m_isUserInteracting = false; + m_touchInteraction.end(); } void PageViewportControllerClientQt::focusEditableArea(const QRectF& caretArea, const QRectF& targetArea) @@ -217,7 +245,7 @@ void PageViewportControllerClientQt::zoomToAreaGestureEnded(const QPointF& touch if (!targetArea.isValid()) return; - if (m_controller->hasSuspendedContent()) + if (m_scrollChange.inProgress() || m_scaleChange.inProgress()) return; const float margin = 10; // We want at least a little bit of margin. @@ -425,9 +453,7 @@ void PageViewportControllerClientQt::pinchGestureStarted(const QPointF& pinchCen return; clearRelativeZoomState(); - - m_ignoreViewportChanges = true; - m_controller->suspendContent(); + m_scaleChange.begin(); m_lastPinchCenterInViewportCoordinates = pinchCenterInViewportCoordinates; m_pinchStartScale = m_pageItem->contentsScale(); @@ -435,11 +461,12 @@ void PageViewportControllerClientQt::pinchGestureStarted(const QPointF& pinchCen void PageViewportControllerClientQt::pinchGestureRequestUpdate(const QPointF& pinchCenterInViewportCoordinates, qreal totalScaleFactor) { - ASSERT(m_controller->hasSuspendedContent()); + ASSERT(m_scaleChange.inProgress()); if (!m_controller->allowsUserScaling()) return; + ASSERT(m_pinchStartScale > 0); // Changes of the center position should move the page even if the zoom factor does not change. const qreal pinchScale = m_pinchStartScale * totalScaleFactor; @@ -456,12 +483,11 @@ void PageViewportControllerClientQt::pinchGestureRequestUpdate(const QPointF& pi void PageViewportControllerClientQt::pinchGestureEnded() { - ASSERT(m_controller->hasSuspendedContent()); + ASSERT(m_scaleChange.inProgress()); if (!m_controller->allowsUserScaling()) return; - m_ignoreViewportChanges = false; m_pinchStartScale = -1; // This will take care of resuming the content, even if no animation was performed. @@ -471,7 +497,8 @@ void PageViewportControllerClientQt::pinchGestureEnded() void PageViewportControllerClientQt::pinchGestureCancelled() { m_pinchStartScale = -1; - m_controller->resumeContent(); + m_scaleChange.end(); + updateViewportController(); } void PageViewportControllerClientQt::didChangeContentsSize(const IntSize& newSize) @@ -482,7 +509,7 @@ void PageViewportControllerClientQt::didChangeContentsSize(const IntSize& newSiz // we didn't do scale adjustment. emit m_viewportItem->experimental()->test()->contentsScaleCommitted(); - if (!m_controller->hasSuspendedContent()) + if (!m_scaleChange.inProgress() && !m_scrollChange.inProgress()) setContentsRectToNearestValidBounds(); } diff --git a/Source/WebKit2/UIProcess/qt/PageViewportControllerClientQt.h b/Source/WebKit2/UIProcess/qt/PageViewportControllerClientQt.h index 687f29193..22c4c3d3c 100644 --- a/Source/WebKit2/UIProcess/qt/PageViewportControllerClientQt.h +++ b/Source/WebKit2/UIProcess/qt/PageViewportControllerClientQt.h @@ -103,6 +103,24 @@ private: virtual void updateCurrentValue(const QVariant&); }; + class ViewportInteractionTracker { + public: + ViewportInteractionTracker(PageViewportControllerClientQt* client, bool shouldSuspend = true) + : m_controllerClient(client) + , m_shouldSuspend(shouldSuspend) + , m_inProgress(false) + { } + + void begin(); + void end(); + bool inProgress() const { return m_inProgress; } + + private: + PageViewportControllerClientQt* m_controllerClient; + bool m_shouldSuspend; + bool m_inProgress; + }; + struct ScaleStackItem { ScaleStackItem(qreal scale, qreal xPosition) : scale(scale) @@ -113,6 +131,7 @@ private: qreal xPosition; }; + friend class ViewportInteractionTracker; friend class ScaleAnimation; friend class ::QWebKitTest; @@ -130,15 +149,18 @@ private: void scaleContent(qreal itemScale, const QPointF& centerInCSSCoordinates = QPointF()); void clearRelativeZoomState(); + ViewportInteractionTracker m_scaleChange; + ViewportInteractionTracker m_scrollChange; + ViewportInteractionTracker m_touchInteraction; + ScaleAnimation* m_scaleAnimation; QPointF m_lastPinchCenterInViewportCoordinates; QPointF m_lastScrollPosition; + int m_activeInteractionCount; qreal m_pinchStartScale; qreal m_lastCommittedScale; qreal m_zoomOutScale; QList<ScaleStackItem> m_scaleStack; - bool m_isUserInteracting; - bool m_ignoreViewportChanges; }; } // namespace WebKit |
