void FocusController::setContainingWindowIsVisible(bool containingWindowIsVisible) { if (m_containingWindowIsVisible == containingWindowIsVisible) return; m_containingWindowIsVisible = containingWindowIsVisible; FrameView* view = m_page->mainFrame()->view(); if (!view) return; contentAreaDidShowOrHide(view, containingWindowIsVisible); for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree()->traverseNext()) { FrameView* frameView = frame->view(); if (!frameView) continue; const HashSet<ScrollableArea*>* scrollableAreas = frameView->scrollableAreas(); if (!scrollableAreas) continue; for (HashSet<ScrollableArea*>::const_iterator it = scrollableAreas->begin(), end = scrollableAreas->end(); it != end; ++it) { ScrollableArea* scrollableArea = *it; ASSERT(scrollableArea->scrollbarsCanBeActive() || m_page->shouldSuppressScrollbarAnimations()); contentAreaDidShowOrHide(scrollableArea, containingWindowIsVisible); } } }
Region ScrollingCoordinator::computeNonFastScrollableRegion(const Frame* frame, const IntPoint& frameLocation) const { #if ENABLE(IOS_TOUCH_EVENTS) // On iOS, we use nonFastScrollableRegion to represent the region covered by elements with touch event handlers. ASSERT(frame->isMainFrame()); UNUSED_PARAM(frameLocation); Document* document = frame->document(); if (!document) return Region(); Vector<IntRect> touchRects; document->getTouchRects(touchRects); Region touchRegion; for (const auto& rect : touchRects) touchRegion.unite(rect); return touchRegion; #else Region nonFastScrollableRegion; FrameView* frameView = frame->view(); if (!frameView) return nonFastScrollableRegion; IntPoint offset = frameLocation; offset.moveBy(frameView->frameRect().location()); offset.move(0, frameView->topContentInset()); if (const FrameView::ScrollableAreaSet* scrollableAreas = frameView->scrollableAreas()) { for (FrameView::ScrollableAreaSet::const_iterator it = scrollableAreas->begin(), end = scrollableAreas->end(); it != end; ++it) { ScrollableArea* scrollableArea = *it; // Composited scrollable areas can be scrolled off the main thread. if (scrollableArea->usesCompositedScrolling()) continue; IntRect box = scrollableArea->scrollableAreaBoundingBox(); box.moveBy(offset); nonFastScrollableRegion.unite(box); } } for (const auto& child : frameView->children()) { if (!child->isPluginViewBase()) continue; PluginViewBase* pluginViewBase = toPluginViewBase(child.get()); if (pluginViewBase->wantsWheelEvents()) nonFastScrollableRegion.unite(pluginViewBase->frameRect()); } for (Frame* subframe = frame->tree().firstChild(); subframe; subframe = subframe->tree().nextSibling()) nonFastScrollableRegion.unite(computeNonFastScrollableRegion(subframe, offset)); return nonFastScrollableRegion; #endif }
Region ScrollingCoordinator::computeNonFastScrollableRegion(Frame* frame, const IntPoint& frameLocation) { Region nonFastScrollableRegion; FrameView* frameView = frame->view(); if (!frameView) return nonFastScrollableRegion; IntPoint offset = frameLocation; offset.moveBy(frameView->frameRect().location()); if (const FrameView::ScrollableAreaSet* scrollableAreas = frameView->scrollableAreas()) { for (FrameView::ScrollableAreaSet::const_iterator it = scrollableAreas->begin(), end = scrollableAreas->end(); it != end; ++it) { ScrollableArea* scrollableArea = *it; #if USE(ACCELERATED_COMPOSITING) // Composited scrollable areas can be scrolled off the main thread. if (scrollableArea->usesCompositedScrolling()) continue; #endif IntRect box = scrollableArea->scrollableAreaBoundingBox(); box.moveBy(offset); nonFastScrollableRegion.unite(box); } } if (const HashSet<RefPtr<Widget> >* children = frameView->children()) { for (HashSet<RefPtr<Widget> >::const_iterator it = children->begin(), end = children->end(); it != end; ++it) { if (!(*it)->isPluginViewBase()) continue; PluginViewBase* pluginViewBase = static_cast<PluginViewBase*>((*it).get()); if (pluginViewBase->wantsWheelEvents()) nonFastScrollableRegion.unite(pluginViewBase->frameRect()); } } FrameTree* tree = frame->tree(); for (Frame* subFrame = tree->firstChild(); subFrame; subFrame = subFrame->tree()->nextSibling()) nonFastScrollableRegion.unite(computeNonFastScrollableRegion(subFrame, offset)); return nonFastScrollableRegion; }
void Page::setShouldSuppressScrollbarAnimations(bool suppressAnimations) { if (suppressAnimations == m_suppressScrollbarAnimations) return; if (!suppressAnimations) { // If animations are not going to be suppressed anymore, then there is nothing to do here but // change the cached value. m_suppressScrollbarAnimations = suppressAnimations; return; } // On the other hand, if we are going to start suppressing animations, then we need to make sure we // finish any current scroll animations first. FrameView* view = mainFrame()->view(); if (!view) return; view->finishCurrentScrollAnimations(); for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext()) { FrameView* frameView = frame->view(); if (!frameView) continue; const HashSet<ScrollableArea*>* scrollableAreas = frameView->scrollableAreas(); if (!scrollableAreas) continue; for (HashSet<ScrollableArea*>::const_iterator it = scrollableAreas->begin(), end = scrollableAreas->end(); it != end; ++it) { ScrollableArea* scrollableArea = *it; ASSERT(scrollableArea->scrollbarsCanBeActive()); scrollableArea->finishCurrentScrollAnimations(); } } m_suppressScrollbarAnimations = suppressAnimations; }
Region ScrollingCoordinator::absoluteNonFastScrollableRegionForFrame(const Frame& frame) const { RenderView* renderView = frame.contentRenderer(); if (!renderView || renderView->documentBeingDestroyed()) return Region(); #if ENABLE(IOS_TOUCH_EVENTS) // On iOS, we use nonFastScrollableRegion to represent the region covered by elements with touch event handlers. ASSERT(frame.isMainFrame()); Document* document = frame.document(); if (!document) return Region(); Vector<IntRect> touchRects; document->getTouchRects(touchRects); Region touchRegion; for (const auto& rect : touchRects) touchRegion.unite(rect); // FIXME: use absoluteRegionForEventTargets(). return touchRegion; #else Region nonFastScrollableRegion; FrameView* frameView = frame.view(); if (!frameView) return nonFastScrollableRegion; // FIXME: should ASSERT(!frameView->needsLayout()) here, but need to fix DebugPageOverlays // to not ask for regions at bad times. if (const FrameView::ScrollableAreaSet* scrollableAreas = frameView->scrollableAreas()) { for (auto& scrollableArea : *scrollableAreas) { // Composited scrollable areas can be scrolled off the main thread. if (scrollableArea->usesAsyncScrolling()) continue; bool isInsideFixed; IntRect box = scrollableArea->scrollableAreaBoundingBox(&isInsideFixed); if (isInsideFixed) box = IntRect(frameView->fixedScrollableAreaBoundsInflatedForScrolling(LayoutRect(box))); nonFastScrollableRegion.unite(box); } } for (auto& widget : frameView->widgetsInRenderTree()) { RenderWidget* renderWidget = RenderWidget::find(widget); if (!renderWidget || !is<PluginViewBase>(*widget)) continue; if (downcast<PluginViewBase>(*widget).wantsWheelEvents()) nonFastScrollableRegion.unite(renderWidget->absoluteBoundingBoxRect()); } // FIXME: if we've already accounted for this subframe as a scrollable area, we can avoid recursing into it here. for (Frame* subframe = frame.tree().firstChild(); subframe; subframe = subframe->tree().nextSibling()) { FrameView* subframeView = subframe->view(); if (!subframeView) continue; Region subframeRegion = absoluteNonFastScrollableRegionForFrame(*subframe); // Map from the frame document to our document. IntPoint offset = subframeView->contentsToContainingViewContents(IntPoint()); // FIXME: this translation ignores non-trival transforms on the frame. subframeRegion.translate(toIntSize(offset)); nonFastScrollableRegion.unite(subframeRegion); } Document::RegionFixedPair wheelHandlerRegion = frame.document()->absoluteRegionForEventTargets(frame.document()->wheelEventTargets()); bool wheelHandlerInFixedContent = wheelHandlerRegion.second; if (wheelHandlerInFixedContent) { // FIXME: need to handle position:sticky here too. LayoutRect inflatedWheelHandlerBounds = frameView->fixedScrollableAreaBoundsInflatedForScrolling(LayoutRect(wheelHandlerRegion.first.bounds())); wheelHandlerRegion.first.unite(enclosingIntRect(inflatedWheelHandlerBounds)); } nonFastScrollableRegion.unite(wheelHandlerRegion.first); // FIXME: If this is not the main frame, we could clip the region to the frame's bounds. return nonFastScrollableRegion; #endif }