diff options
author | Simon Hausmann <simon.hausmann@digia.com> | 2012-10-15 16:08:57 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@digia.com> | 2012-10-15 16:08:57 +0200 |
commit | 5466563f4b5b6b86523e3f89bb7f77e5b5270c78 (patch) | |
tree | 8caccf7cd03a15207cde3ba282c88bf132482a91 /Source/WebKit2/UIProcess/PageViewportController.cpp | |
parent | 33b26980cb24288b5a9f2590ccf32a949281bb79 (diff) | |
download | qtwebkit-5466563f4b5b6b86523e3f89bb7f77e5b5270c78.tar.gz |
Imported WebKit commit 0dc6cd75e1d4836eaffbb520be96fac4847cc9d2 (http://svn.webkit.org/repository/webkit/trunk@131300)
WebKit update which introduces the QtWebKitWidgets module that contains the WK1
widgets based API. (In fact it renames QtWebKit to QtWebKitWidgets while we're
working on completing the entire split as part of
https://bugs.webkit.org/show_bug.cgi?id=99314
Diffstat (limited to 'Source/WebKit2/UIProcess/PageViewportController.cpp')
-rw-r--r-- | Source/WebKit2/UIProcess/PageViewportController.cpp | 107 |
1 files changed, 89 insertions, 18 deletions
diff --git a/Source/WebKit2/UIProcess/PageViewportController.cpp b/Source/WebKit2/UIProcess/PageViewportController.cpp index e42006a14..02fd3b699 100644 --- a/Source/WebKit2/UIProcess/PageViewportController.cpp +++ b/Source/WebKit2/UIProcess/PageViewportController.cpp @@ -54,9 +54,6 @@ ViewportUpdateDeferrer::~ViewportUpdateDeferrer() return; m_controller->resumeContent(); - - // Make sure that tiles all around the viewport will be requested. - m_controller->syncVisibleContents(); } PageViewportController::PageViewportController(WebKit::WebPageProxy* proxy, PageViewportControllerClient* client) @@ -109,15 +106,65 @@ FloatPoint PageViewportController::clampViewportToContents(const WebCore::FloatP return FloatPoint(clampTo(viewportPos.x(), 0.f, horizontalRange), clampTo(viewportPos.y(), 0.f, verticalRange)); } -void PageViewportController::didChangeContentsSize(const IntSize& newSize) +void PageViewportController::didCommitLoad() { - if (m_viewportSize.isEmpty() || newSize.isEmpty()) - return; + // Do not count the previous committed page contents as covered. + m_lastFrameCoveredRect = FloatRect(); + + // Reset the position to the top, page/history scroll requests may override this before we re-enable rendering. + applyPositionAfterRenderingContents(FloatPoint()); +} +void PageViewportController::didChangeContentsSize(const IntSize& newSize) +{ m_contentsSize = newSize; updateMinimumScaleToFit(); +} + +void PageViewportController::didRenderFrame(const IntSize& contentsSize, const IntRect& coveredRect) +{ + if (m_clientContentsSize != contentsSize) { + m_clientContentsSize = contentsSize; + // Only update the viewport's contents dimensions along with its render if the + // size actually changed since animations on the page trigger DidRenderFrame + // messages without causing dimension changes. + m_client->didChangeContentsSize(contentsSize); + } + + m_lastFrameCoveredRect = coveredRect; + + // Apply any scale or scroll position we locked to be set on the viewport + // only when there is something to display there. The scale goes first to + // avoid offsetting our deferred position by scaling at the viewport center. + // All position and scale changes resulting from a web process event should + // go through here to be applied on the viewport to avoid showing incomplete + // tiles to the user during a few milliseconds. + if (m_effectiveScaleIsLocked) { + m_client->setContentsScale(m_effectiveScale, false); + m_effectiveScaleIsLocked = false; + } + if (m_viewportPosIsLocked) { + FloatPoint clampedPos = clampViewportToContents(m_viewportPos, m_effectiveScale); + // There might be rendered frames not covering our requested position yet, wait for it. + if (FloatRect(clampedPos, viewportSizeInContentsCoordinates()).intersects(coveredRect)) { + m_client->setViewportPosition(clampedPos); + m_viewportPosIsLocked = false; + } + } +} + +void PageViewportController::pageTransitionViewportReady() +{ + if (!m_rawAttributes.layoutSize.isEmpty()) { + m_hadUserInteraction = false; + applyScaleAfterRenderingContents(innerBoundedViewportScale(toViewportScale(m_rawAttributes.initialScale))); + } - m_client->didChangeContentsSize(); + // At this point we should already have received the first viewport arguments and the requested scroll + // position for the newly loaded page and sent our reactions to the web process. It's now safe to tell + // the web process to start rendering the new page contents and possibly re-use the current tiles. + // This assumes that all messages have been handled in order and that nothing has been pushed back on the event loop. + m_webPageProxy->commitPageTransitionViewport(); } void PageViewportController::pageDidRequestScroll(const IntPoint& cssPosition) @@ -126,7 +173,12 @@ void PageViewportController::pageDidRequestScroll(const IntPoint& cssPosition) if (m_activeDeferrerCount) return; - m_client->setViewportPosition(clampViewportToContents(cssPosition, m_effectiveScale)); + FloatRect endVisibleContentRect(clampViewportToContents(cssPosition, m_effectiveScale), viewportSizeInContentsCoordinates()); + if (m_lastFrameCoveredRect.intersects(endVisibleContentRect)) + m_client->setViewportPosition(endVisibleContentRect.location()); + else + // Keep the unclamped position in case the contents size is changed later on. + applyPositionAfterRenderingContents(cssPosition); } void PageViewportController::didChangeViewportSize(const FloatSize& newSize) @@ -145,8 +197,11 @@ void PageViewportController::didChangeViewportSize(const FloatSize& newSize) void PageViewportController::didChangeContentsVisibility(const FloatPoint& viewportPos, float viewportScale, const FloatPoint& trajectoryVector) { - m_viewportPos = viewportPos; - m_effectiveScale = viewportScale; + if (!m_viewportPosIsLocked) + m_viewportPos = viewportPos; + if (!m_effectiveScaleIsLocked) + m_effectiveScale = viewportScale; + syncVisibleContents(trajectoryVector); } @@ -156,7 +211,7 @@ void PageViewportController::syncVisibleContents(const FloatPoint& trajectoryVec if (!drawingArea || m_viewportSize.isEmpty() || m_contentsSize.isEmpty()) return; - FloatRect visibleContentsRect(clampViewportToContents(m_viewportPos, m_effectiveScale), m_viewportSize / m_effectiveScale); + FloatRect visibleContentsRect(clampViewportToContents(m_viewportPos, m_effectiveScale), viewportSizeInContentsCoordinates()); visibleContentsRect.intersect(FloatRect(FloatPoint::zero(), m_contentsSize)); drawingArea->setVisibleContentsRect(visibleContentsRect, m_effectiveScale, trajectoryVector); @@ -177,6 +232,11 @@ void PageViewportController::didChangeViewportAttributes(const WebCore::Viewport m_client->didChangeViewportAttributes(); } +WebCore::FloatSize PageViewportController::viewportSizeInContentsCoordinates() const +{ + return WebCore::FloatSize(m_viewportSize.width() / m_effectiveScale, m_viewportSize.height() / m_effectiveScale); +} + void PageViewportController::suspendContent() { if (m_hasSuspendedContent) @@ -188,12 +248,6 @@ void PageViewportController::suspendContent() void PageViewportController::resumeContent() { - if (!m_rawAttributes.layoutSize.isEmpty() && m_rawAttributes.initialScale > 0) { - m_hadUserInteraction = false; - m_client->setContentsScale(innerBoundedViewportScale(toViewportScale(m_rawAttributes.initialScale)), /* isInitialScale */ true); - m_rawAttributes.initialScale = -1; // Mark used. - } - m_client->didResumeContent(); if (!m_hasSuspendedContent) @@ -203,15 +257,32 @@ void PageViewportController::resumeContent() m_webPageProxy->resumeActiveDOMObjectsAndAnimations(); } +void PageViewportController::applyScaleAfterRenderingContents(float scale) +{ + m_effectiveScale = scale; + m_effectiveScaleIsLocked = true; + syncVisibleContents(); +} + +void PageViewportController::applyPositionAfterRenderingContents(const FloatPoint& pos) +{ + m_viewportPos = pos; + m_viewportPosIsLocked = true; + syncVisibleContents(); +} + void PageViewportController::updateMinimumScaleToFit() { + if (m_viewportSize.isEmpty()) + return; + float minimumScale = WebCore::computeMinimumScaleFactorForContentContained(m_rawAttributes, WebCore::roundedIntSize(m_viewportSize), WebCore::roundedIntSize(m_contentsSize)); if (!fuzzyCompare(minimumScale, m_minimumScaleToFit, 0.001)) { m_minimumScaleToFit = minimumScale; if (!m_hadUserInteraction && !hasSuspendedContent()) - m_client->setContentsScale(toViewportScale(minimumScale), true /* isInitialScale */); + applyScaleAfterRenderingContents(toViewportScale(minimumScale)); m_client->didChangeViewportAttributes(); } |