Changeset 167614 in webkit


Ignore:
Timestamp:
Apr 21, 2014 1:10:12 PM (10 years ago)
Author:
benjamin@webkit.org
Message:

[iOS][WK2] Make dynamic viewport size update content aware
https://bugs.webkit.org/show_bug.cgi?id=131874

Patch by Benjamin Poulain <bpoulain@apple.com> on 2014-04-21
Reviewed by Tim Horton.

When possible, adjust the scroll position based on the content on dynamic viewport resize.

  • WebProcess/WebPage/WebPage.cpp:

(WebKit::WebPage::WebPage):
(WebKit::WebPage::scalePage):
(WebKit::WebPage::pageDidScroll):

  • WebProcess/WebPage/WebPage.h:

The scrolling heuristic are not invertible, especially the content heuristic. To have the right
behavior when doing resize without changing the page, we save the old scroll position and restore
it when the content size and scale is restored.

  • WebProcess/WebPage/ios/WebPageIOS.mm:

(WebKit::WebPage::dynamicViewportSizeUpdate):
On dynamic update, start by finding what node is at the center of the screen. After the layout, put that
node back in the center.

(WebKit::WebPage::updateVisibleContentRects):

Location:
trunk/Source/WebKit2
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit2/ChangeLog

    r167611 r167614  
     12014-04-21  Benjamin Poulain  <bpoulain@apple.com>
     2
     3        [iOS][WK2] Make dynamic viewport size update content aware
     4        https://bugs.webkit.org/show_bug.cgi?id=131874
     5
     6        Reviewed by Tim Horton.
     7
     8        When possible, adjust the scroll position based on the content on dynamic viewport resize.
     9
     10        * WebProcess/WebPage/WebPage.cpp:
     11        (WebKit::WebPage::WebPage):
     12        (WebKit::WebPage::scalePage):
     13        (WebKit::WebPage::pageDidScroll):
     14        * WebProcess/WebPage/WebPage.h:
     15        The scrolling heuristic are not invertible, especially the content heuristic. To have the right
     16        behavior when doing resize without changing the page, we save the old scroll position and restore
     17        it when the content size and scale is restored.
     18
     19        * WebProcess/WebPage/ios/WebPageIOS.mm:
     20        (WebKit::WebPage::dynamicViewportSizeUpdate):
     21        On dynamic update, start by finding what node is at the center of the screen. After the layout, put that
     22        node back in the center.
     23
     24        (WebKit::WebPage::updateVisibleContentRects):
     25
    1262014-04-21  Anders Carlsson  <andersca@apple.com>
    227
  • trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp

    r167610 r167614  
    289289    , m_screenSize(parameters.screenSize)
    290290    , m_availableScreenSize(parameters.availableScreenSize)
     291    , m_inDynamicSizeUpdate(false)
    291292#endif
    292293    , m_inspectorClient(0)
     
    12871288
    12881289#if PLATFORM(IOS)
     1290    if (!m_inDynamicSizeUpdate)
     1291        m_dynamicSizeUpdateHistory.clear();
    12891292    m_scaleWasSetByUIProcess = false;
    12901293#endif
     
    16211624void WebPage::pageDidScroll()
    16221625{
     1626#if PLATFORM(IOS)
     1627    if (!m_inDynamicSizeUpdate)
     1628        m_dynamicSizeUpdateHistory.clear();
     1629#endif
    16231630    m_uiClient->pageDidScroll(this);
    16241631
  • trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h

    r167610 r167614  
    5151#include <WebCore/FrameLoaderTypes.h>
    5252#include <WebCore/IntRect.h>
     53#include <WebCore/IntSizeHash.h>
    5354#include <WebCore/Page.h>
    5455#include <WebCore/PageVisibilityState.h>
     
    11601161    WebCore::FloatSize m_availableScreenSize;
    11611162    WebCore::IntSize m_blockSelectionDesiredSize;
     1163    bool m_inDynamicSizeUpdate;
     1164    HashMap<std::pair<WebCore::IntSize, double>, WebCore::IntPoint> m_dynamicSizeUpdateHistory;
    11621165#endif
    11631166
  • trunk/Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm

    r167481 r167614  
    7676#import <WebCore/RenderBlock.h>
    7777#import <WebCore/RenderImage.h>
     78#import <WebCore/RenderView.h>
    7879#import <WebCore/ResourceBuffer.h>
    7980#import <WebCore/SharedBuffer.h>
     
    8283#import <WebCore/WKContentObservation.h>
    8384#import <WebCore/WebEvent.h>
     85#import <wtf/TemporaryChange.h>
    8486
    8587using namespace WebCore;
     
    17651767void WebPage::dynamicViewportSizeUpdate(const IntSize& minimumLayoutSize, const FloatRect& targetExposedContentRect, const FloatRect& targetUnobscuredRect, double targetScale)
    17661768{
     1769    TemporaryChange<bool> dynamicSizeUpdateGuard(m_inDynamicSizeUpdate, true);
    17671770    // FIXME: this does not handle the cases where the content would change the content size or scroll position from JavaScript.
    17681771    // To handle those cases, we would need to redo this computation on every change until the next visible content rect update.
     
    17701773    FrameView& frameView = *m_page->mainFrame().view();
    17711774    IntSize oldContentSize = frameView.contentsSize();
     1775    float oldPageScaleFactor = m_page->pageScaleFactor();
     1776
     1777    m_dynamicSizeUpdateHistory.add(std::make_pair(oldContentSize, oldPageScaleFactor), IntPoint(frameView.scrollOffset()));
     1778
     1779    RefPtr<Node> oldNodeAtCenter;
     1780    float relativeHorizontalPositionInNodeAtCenter = 0;
     1781    float relativeVerticalPositionInNodeAtCenter = 0;
     1782    {
     1783        IntRect unobscuredContentRect = frameView.unobscuredContentRect();
     1784        IntPoint unobscuredContentRectCenter = unobscuredContentRect.center();
     1785
     1786        HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::DisallowShadowContent);
     1787        HitTestResult hitTestResult = HitTestResult(unobscuredContentRectCenter);
     1788
     1789        RenderView* mainFrameRenderView = frameView.renderView();
     1790        mainFrameRenderView->hitTest(request, hitTestResult);
     1791
     1792        if (Node* node = hitTestResult.innerNode()) {
     1793            if (RenderObject* renderer = node->renderer()) {
     1794                FrameView& containingView = *node->document().frame()->view();
     1795                FloatRect boundingBox = containingView.contentsToRootView(renderer->absoluteBoundingBoxRect(true));
     1796                relativeHorizontalPositionInNodeAtCenter = (unobscuredContentRectCenter.x() - boundingBox.x()) / boundingBox.width();
     1797                relativeVerticalPositionInNodeAtCenter = (unobscuredContentRectCenter.y() - boundingBox.y()) / boundingBox.height();
     1798                oldNodeAtCenter = node;
     1799            }
     1800        }
     1801    }
    17721802
    17731803    m_viewportConfiguration.setMinimumLayoutSize(minimumLayoutSize);
     
    18081838                                          newUnobscuredRectWidth + obscuredLeftMargin + obscuredRightMargin,
    18091839                                          newUnobscuredRectHeight + obscuredTopMargin + obscuredBottomMargin);
    1810 
    1811         // FIXME: Adjust the rects based on the content.
    18121840    }
    18131841
    18141842    if (oldContentSize != newContentSize || scale != targetScale) {
    18151843        // Snap the new unobscured rect back into the content rect.
    1816         newUnobscuredContentRect.setWidth(std::min(static_cast<float>(newContentSize.width()), newExposedContentRect.width()));
    1817         newUnobscuredContentRect.setHeight(std::min(static_cast<float>(newContentSize.height()), newExposedContentRect.height()));
    1818 
    1819         if (oldContentSize != newContentSize) {
    1820             // If the content size has changed, keep the same relative position.
    1821             FloatPoint oldContentCenter = targetUnobscuredRect.center();
    1822             float relativeHorizontalPosition = oldContentCenter.x() / oldContentSize.width();
    1823             float relativeVerticalPosition =  oldContentCenter.y() / oldContentSize.height();
    1824             FloatPoint newRelativeContentCenter(relativeHorizontalPosition * newContentSize.width(), relativeVerticalPosition * newContentSize.height());
     1844        newUnobscuredContentRect.setWidth(std::min(static_cast<float>(newContentSize.width()), newUnobscuredContentRect.width()));
     1845        newUnobscuredContentRect.setHeight(std::min(static_cast<float>(newContentSize.height()), newUnobscuredContentRect.height()));
     1846
     1847        const auto& previousPosition = m_dynamicSizeUpdateHistory.find(std::pair<IntSize, float>(newContentSize, scale));
     1848        if (previousPosition != m_dynamicSizeUpdateHistory.end()) {
     1849            IntPoint restoredPosition = previousPosition->value;
     1850            FloatPoint deltaPosition(restoredPosition.x() - newUnobscuredContentRect.x(), restoredPosition.y() - newUnobscuredContentRect.y());
     1851            newUnobscuredContentRect.moveBy(deltaPosition);
     1852            newExposedContentRect.moveBy(deltaPosition);
     1853        } else if (oldContentSize != newContentSize) {
     1854            FloatPoint newRelativeContentCenter;
     1855
     1856            if (RenderObject* renderer = oldNodeAtCenter ? oldNodeAtCenter->renderer() : nullptr) {
     1857                FrameView& containingView = *oldNodeAtCenter->document().frame()->view();
     1858                FloatRect newBoundingBox = containingView.contentsToRootView(renderer->absoluteBoundingBoxRect(true));
     1859                newRelativeContentCenter = FloatPoint(newBoundingBox.x() + relativeHorizontalPositionInNodeAtCenter * newBoundingBox.width(), newBoundingBox.y() + relativeVerticalPositionInNodeAtCenter * newBoundingBox.height());
     1860            } else {
     1861                // If the content size has changed, keep the same relative position.
     1862                FloatPoint oldContentCenter = targetUnobscuredRect.center();
     1863                float relativeHorizontalPosition = oldContentCenter.x() / oldContentSize.width();
     1864                float relativeVerticalPosition =  oldContentCenter.y() / oldContentSize.height();
     1865                newRelativeContentCenter = FloatPoint(relativeHorizontalPosition * newContentSize.width(), relativeVerticalPosition * newContentSize.height());
     1866            }
     1867
    18251868            FloatPoint newUnobscuredContentRectCenter = newUnobscuredContentRect.center();
    18261869            FloatPoint positionDelta(newRelativeContentCenter.x() - newUnobscuredContentRectCenter.x(), newRelativeContentCenter.y() - newUnobscuredContentRectCenter.y());
     
    18641907
    18651908    if (scale == targetScale)
    1866         scalePage(scale, frameView.scrollPosition());
     1909        scalePage(scale, roundedUnobscuredContentRect.location());
    18671910
    18681911    if (scale != targetScale || roundedIntPoint(targetUnobscuredRect.location()) != roundedUnobscuredContentRect.location())
    1869         send(Messages::WebPageProxy::DynamicViewportUpdateChangedTarget(scale, frameView.scrollPosition()));
     1912        send(Messages::WebPageProxy::DynamicViewportUpdateChangedTarget(scale, roundedUnobscuredContentRect.location()));
    18701913}
    18711914
     
    19582001        m_scaleWasSetByUIProcess = true;
    19592002
     2003        m_dynamicSizeUpdateHistory.clear();
     2004
    19602005        m_page->setPageScaleFactor(floatBoundedScale, scrollPosition);
    1961         if (m_drawingArea->layerTreeHost())
    1962             m_drawingArea->layerTreeHost()->deviceOrPageScaleFactorChanged();
     2006        if (LayerTreeHost* layerTreeHost = m_drawingArea->layerTreeHost())
     2007            layerTreeHost->deviceOrPageScaleFactorChanged();
    19632008        send(Messages::WebPageProxy::PageScaleFactorDidChange(floatBoundedScale));
    19642009    }
    19652010
    1966     m_page->mainFrame().view()->setScrollOffset(scrollPosition);
    1967     m_page->mainFrame().view()->setUnobscuredContentRect(roundedUnobscuredRect);
     2011    FrameView& frameView = *m_page->mainFrame().view();
     2012    if (scrollPosition != IntPoint(frameView.scrollOffset()))
     2013        m_dynamicSizeUpdateHistory.clear();
     2014
     2015    frameView.setScrollOffset(scrollPosition);
     2016    frameView.setUnobscuredContentRect(roundedUnobscuredRect);
    19682017
    19692018    double horizontalVelocity = visibleContentRectUpdateInfo.horizontalVelocity();
     
    19722021    adjustVelocityDataForBoundedScale(horizontalVelocity, verticalVelocity, scaleChangeRate, visibleContentRectUpdateInfo.scale(), boundedScale);
    19732022
    1974     m_page->mainFrame().view()->setScrollVelocity(horizontalVelocity, verticalVelocity, scaleChangeRate, visibleContentRectUpdateInfo.timestamp());
     2023    frameView.setScrollVelocity(horizontalVelocity, verticalVelocity, scaleChangeRate, visibleContentRectUpdateInfo.timestamp());
    19752024
    19762025    if (visibleContentRectUpdateInfo.inStableState())
Note: See TracChangeset for help on using the changeset viewer.