Example #1
0
void AsyncScrollingCoordinator::frameViewLayoutUpdated(FrameView& frameView)
{
    ASSERT(isMainThread());
    ASSERT(m_page);

    // If there isn't a root node yet, don't do anything. We'll be called again after creating one.
    if (!m_scrollingStateTree->rootStateNode())
        return;

    // Compute the region of the page that we can't do fast scrolling for. This currently includes
    // all scrollable areas, such as subframes, overflow divs and list boxes. We need to do this even if the
    // frame view whose layout was updated is not the main frame.
    // In the future, we may want to have the ability to set non-fast scrolling regions for more than
    // just the root node. But right now, this concept only applies to the root.
    m_scrollingStateTree->rootStateNode()->setNonFastScrollableRegion(computeNonFastScrollableRegion(m_page->mainFrame(), IntPoint()));
    m_nonFastScrollableRegionDirty = false;

    if (!coordinatesScrollingForFrameView(frameView))
        return;

    ScrollingStateFrameScrollingNode* node = downcast<ScrollingStateFrameScrollingNode>(m_scrollingStateTree->stateNodeForID(frameView.scrollLayerID()));
    if (!node)
        return;

    Scrollbar* verticalScrollbar = frameView.verticalScrollbar();
    Scrollbar* horizontalScrollbar = frameView.horizontalScrollbar();
    node->setScrollbarPaintersFromScrollbars(verticalScrollbar, horizontalScrollbar);
    
    node->setFrameScaleFactor(frameView.frame().frameScaleFactor());
    node->setHeaderHeight(frameView.headerHeight());
    node->setFooterHeight(frameView.footerHeight());
    node->setTopContentInset(frameView.topContentInset());

    node->setScrollOrigin(frameView.scrollOrigin());
    node->setScrollableAreaSize(frameView.visibleContentRect().size());
    node->setTotalContentsSize(frameView.totalContentsSize());
    node->setReachableContentsSize(frameView.totalContentsSize());

#if ENABLE(CSS_SCROLL_SNAP)
    frameView.updateSnapOffsets();
    if (const Vector<LayoutUnit>* horizontalSnapOffsets = frameView.horizontalSnapOffsets())
        setStateScrollingNodeSnapOffsetsAsFloat(*node, ScrollEventAxis::Horizontal, *horizontalSnapOffsets, m_page->deviceScaleFactor());

    if (const Vector<LayoutUnit>* verticalSnapOffsets = frameView.verticalSnapOffsets())
        setStateScrollingNodeSnapOffsetsAsFloat(*node, ScrollEventAxis::Vertical, *verticalSnapOffsets, m_page->deviceScaleFactor());
#endif

    ScrollableAreaParameters scrollParameters;
    scrollParameters.horizontalScrollElasticity = frameView.horizontalScrollElasticity();
    scrollParameters.verticalScrollElasticity = frameView.verticalScrollElasticity();
    scrollParameters.hasEnabledHorizontalScrollbar = horizontalScrollbar && horizontalScrollbar->enabled();
    scrollParameters.hasEnabledVerticalScrollbar = verticalScrollbar && verticalScrollbar->enabled();
    scrollParameters.horizontalScrollbarMode = frameView.horizontalScrollbarMode();
    scrollParameters.verticalScrollbarMode = frameView.verticalScrollbarMode();

    node->setScrollableAreaParameters(scrollParameters);
}
void AsyncScrollingCoordinator::frameViewLayoutUpdated(FrameView& frameView)
{
    ASSERT(isMainThread());
    ASSERT(m_page);

    // If there isn't a root node yet, don't do anything. We'll be called again after creating one.
    if (!m_scrollingStateTree->rootStateNode())
        return;

    // Compute the region of the page that we can't do fast scrolling for. This currently includes
    // all scrollable areas, such as subframes, overflow divs and list boxes. We need to do this even if the
    // frame view whose layout was updated is not the main frame.
    // In the future, we may want to have the ability to set non-fast scrolling regions for more than
    // just the root node. But right now, this concept only applies to the root.
    m_scrollingStateTree->rootStateNode()->setNonFastScrollableRegion(absoluteNonFastScrollableRegion());
    m_nonFastScrollableRegionDirty = false;

    if (!coordinatesScrollingForFrameView(frameView))
        return;

    ScrollingStateFrameScrollingNode* node = downcast<ScrollingStateFrameScrollingNode>(m_scrollingStateTree->stateNodeForID(frameView.scrollLayerID()));
    if (!node)
        return;

    Scrollbar* verticalScrollbar = frameView.verticalScrollbar();
    Scrollbar* horizontalScrollbar = frameView.horizontalScrollbar();
    node->setScrollbarPaintersFromScrollbars(verticalScrollbar, horizontalScrollbar);
    
    node->setFrameScaleFactor(frameView.frame().frameScaleFactor());
    node->setHeaderHeight(frameView.headerHeight());
    node->setFooterHeight(frameView.footerHeight());
    node->setTopContentInset(frameView.topContentInset());

    node->setScrollOrigin(frameView.scrollOrigin());
    node->setScrollableAreaSize(frameView.visibleContentRect().size());
    node->setTotalContentsSize(frameView.totalContentsSize());
    node->setReachableContentsSize(frameView.totalContentsSize());
    node->setFixedElementsLayoutRelativeToFrame(frameView.fixedElementsLayoutRelativeToFrame());

#if ENABLE(CSS_SCROLL_SNAP)
    frameView.updateSnapOffsets();
    updateScrollSnapPropertiesWithFrameView(frameView);
#endif

#if PLATFORM(COCOA)
    Page* page = frameView.frame().page();
    if (page && page->expectsWheelEventTriggers()) {
        LOG(WheelEventTestTriggers, "    AsyncScrollingCoordinator::frameViewLayoutUpdated: Expects wheel event test trigger=%d", page->expectsWheelEventTriggers());
        node->setExpectsWheelEventTestTrigger(page->expectsWheelEventTriggers());
    }
#endif

    ScrollableAreaParameters scrollParameters;
    scrollParameters.horizontalScrollElasticity = frameView.horizontalScrollElasticity();
    scrollParameters.verticalScrollElasticity = frameView.verticalScrollElasticity();
    scrollParameters.hasEnabledHorizontalScrollbar = horizontalScrollbar && horizontalScrollbar->enabled();
    scrollParameters.hasEnabledVerticalScrollbar = verticalScrollbar && verticalScrollbar->enabled();
    scrollParameters.horizontalScrollbarMode = frameView.horizontalScrollbarMode();
    scrollParameters.verticalScrollbarMode = frameView.verticalScrollbarMode();

    node->setScrollableAreaParameters(scrollParameters);
}
void AsyncScrollingCoordinator::updateScrollPositionAfterAsyncScroll(ScrollingNodeID scrollingNodeID, const FloatPoint& scrollPosition, bool programmaticScroll, SetOrSyncScrollingLayerPosition scrollingLayerPositionAction)
{
    ASSERT(isMainThread());

    if (!m_page)
        return;

    FrameView* frameView = m_page->mainFrame().view();
    if (!frameView)
        return;

    // Main frame.
    if (scrollingNodeID == frameView->scrollLayerID()) {
        bool oldProgrammaticScroll = frameView->inProgrammaticScroll();
        frameView->setInProgrammaticScroll(programmaticScroll);

        frameView->setConstrainsScrollingToContentEdge(false);
        frameView->notifyScrollPositionChanged(roundedIntPoint(scrollPosition));
        frameView->setConstrainsScrollingToContentEdge(true);

        frameView->setInProgrammaticScroll(oldProgrammaticScroll);

        if (GraphicsLayer* scrollLayer = scrollLayerForFrameView(frameView)) {
            GraphicsLayer* counterScrollingLayer = counterScrollingLayerForFrameView(frameView);
            GraphicsLayer* insetClipLayer = insetClipLayerForFrameView(frameView);
            GraphicsLayer* contentShadowLayer = contentShadowLayerForFrameView(frameView);
            GraphicsLayer* scrolledContentsLayer = rootContentLayerForFrameView(frameView);
            GraphicsLayer* headerLayer = headerLayerForFrameView(frameView);
            GraphicsLayer* footerLayer = footerLayerForFrameView(frameView);
            LayoutSize scrollOffsetForFixed = frameView->scrollOffsetForFixedPosition();

            float topContentInset = frameView->topContentInset();
            FloatPoint positionForInsetClipLayer = FloatPoint(0, FrameView::yPositionForInsetClipLayer(scrollPosition, topContentInset));
            FloatPoint positionForContentsLayer = FloatPoint(scrolledContentsLayer->position().x(),
                FrameView::yPositionForRootContentLayer(scrollPosition, topContentInset, frameView->headerHeight()));
            FloatPoint positionForHeaderLayer = FloatPoint(scrollOffsetForFixed.width(), FrameView::yPositionForHeaderLayer(scrollPosition, topContentInset));
            FloatPoint positionForFooterLayer = FloatPoint(scrollOffsetForFixed.width(),
                FrameView::yPositionForFooterLayer(scrollPosition, topContentInset, frameView->totalContentsSize().height(), frameView->footerHeight()));

            if (programmaticScroll || scrollingLayerPositionAction == SetScrollingLayerPosition) {
                scrollLayer->setPosition(-frameView->scrollPosition());
                if (counterScrollingLayer)
                    counterScrollingLayer->setPosition(toLayoutPoint(scrollOffsetForFixed));
                if (insetClipLayer)
                    insetClipLayer->setPosition(positionForInsetClipLayer);
                if (contentShadowLayer)
                    contentShadowLayer->setPosition(positionForContentsLayer);
                if (scrolledContentsLayer)
                    scrolledContentsLayer->setPosition(positionForContentsLayer);
                if (headerLayer)
                    headerLayer->setPosition(positionForHeaderLayer);
                if (footerLayer)
                    footerLayer->setPosition(positionForFooterLayer);
            } else {
                scrollLayer->syncPosition(-frameView->scrollPosition());
                if (counterScrollingLayer)
                    counterScrollingLayer->syncPosition(toLayoutPoint(scrollOffsetForFixed));
                if (insetClipLayer)
                    insetClipLayer->syncPosition(positionForInsetClipLayer);
                if (contentShadowLayer)
                    contentShadowLayer->syncPosition(positionForContentsLayer);
                if (scrolledContentsLayer)
                    scrolledContentsLayer->syncPosition(positionForContentsLayer);
                if (headerLayer)
                    headerLayer->syncPosition(positionForHeaderLayer);
                if (footerLayer)
                    footerLayer->syncPosition(positionForFooterLayer);

                LayoutRect viewportRect = frameView->viewportConstrainedVisibleContentRect();
                syncChildPositions(viewportRect);
            }
        }

        return;
    }

    // Overflow-scroll area.
    if (ScrollableArea* scrollableArea = frameView->scrollableAreaForScrollLayerID(scrollingNodeID)) {
        scrollableArea->setIsUserScroll(scrollingLayerPositionAction == SyncScrollingLayerPosition);
        scrollableArea->scrollToOffsetWithoutAnimation(scrollPosition);
        scrollableArea->setIsUserScroll(false);
    }
}