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 ScrollingCoordinator::updateMainFrameScrollPosition(const IntPoint& scrollPosition, bool programmaticScroll, SetOrSyncScrollingLayerPosition scrollingLayerPositionAction) { ASSERT(isMainThread()); if (!m_page) return; FrameView* frameView = m_page->mainFrame().view(); if (!frameView) return; bool oldProgrammaticScroll = frameView->inProgrammaticScroll(); frameView->setInProgrammaticScroll(programmaticScroll); frameView->setConstrainsScrollingToContentEdge(false); frameView->notifyScrollPositionChanged(scrollPosition); frameView->setConstrainsScrollingToContentEdge(true); frameView->setInProgrammaticScroll(oldProgrammaticScroll); #if USE(ACCELERATED_COMPOSITING) if (GraphicsLayer* scrollLayer = scrollLayerForFrameView(frameView)) { GraphicsLayer* counterScrollingLayer = counterScrollingLayerForFrameView(frameView); GraphicsLayer* headerLayer = headerLayerForFrameView(frameView); GraphicsLayer* footerLayer = footerLayerForFrameView(frameView); IntSize scrollOffsetForFixed = frameView->scrollOffsetForFixedPosition(); if (programmaticScroll || scrollingLayerPositionAction == SetScrollingLayerPosition) { scrollLayer->setPosition(-frameView->scrollPosition()); if (counterScrollingLayer) counterScrollingLayer->setPosition(IntPoint(scrollOffsetForFixed)); if (headerLayer) headerLayer->setPosition(FloatPoint(scrollOffsetForFixed.width(), 0)); if (footerLayer) footerLayer->setPosition(FloatPoint(scrollOffsetForFixed.width(), frameView->totalContentsSize().height() - frameView->footerHeight())); } else { scrollLayer->syncPosition(-frameView->scrollPosition()); if (counterScrollingLayer) counterScrollingLayer->syncPosition(IntPoint(scrollOffsetForFixed)); if (headerLayer) headerLayer->syncPosition(FloatPoint(scrollOffsetForFixed.width(), 0)); if (footerLayer) footerLayer->syncPosition(FloatPoint(scrollOffsetForFixed.width(), frameView->totalContentsSize().height() - frameView->footerHeight())); LayoutRect viewportRect = frameView->viewportConstrainedVisibleContentRect(); syncChildPositions(viewportRect); } } #else UNUSED_PARAM(scrollingLayerPositionAction); #endif }
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); } }
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; bool oldProgrammaticScroll = frameView->inProgrammaticScroll(); frameView->setInProgrammaticScroll(programmaticScroll); frameView->setConstrainsScrollingToContentEdge(false); frameView->notifyScrollPositionChanged(roundedIntPoint(scrollPosition)); frameView->setConstrainsScrollingToContentEdge(true); frameView->setInProgrammaticScroll(oldProgrammaticScroll); if (scrollingNodeID == frameView->scrollLayerID()) { if (GraphicsLayer* scrollLayer = scrollLayerForFrameView(frameView)) { GraphicsLayer* counterScrollingLayer = counterScrollingLayerForFrameView(frameView); GraphicsLayer* headerLayer = headerLayerForFrameView(frameView); GraphicsLayer* footerLayer = footerLayerForFrameView(frameView); IntSize scrollOffsetForFixed = frameView->scrollOffsetForFixedPosition(); if (programmaticScroll || scrollingLayerPositionAction == SetScrollingLayerPosition) { scrollLayer->setPosition(-frameView->scrollPosition()); if (counterScrollingLayer) counterScrollingLayer->setPosition(IntPoint(scrollOffsetForFixed)); if (headerLayer) headerLayer->setPosition(FloatPoint(scrollOffsetForFixed.width(), 0)); if (footerLayer) footerLayer->setPosition(FloatPoint(scrollOffsetForFixed.width(), frameView->totalContentsSize().height() - frameView->footerHeight())); } else { scrollLayer->syncPosition(-frameView->scrollPosition()); if (counterScrollingLayer) counterScrollingLayer->syncPosition(IntPoint(scrollOffsetForFixed)); if (headerLayer) headerLayer->syncPosition(FloatPoint(scrollOffsetForFixed.width(), 0)); if (footerLayer) footerLayer->syncPosition(FloatPoint(scrollOffsetForFixed.width(), frameView->totalContentsSize().height() - frameView->footerHeight())); LayoutRect viewportRect = frameView->viewportConstrainedVisibleContentRect(); syncChildPositions(viewportRect); } } } // FIXME: handle non-main scrolling nodes. }