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)) { if (programmaticScroll || scrollingLayerPositionAction == SetScrollingLayerPosition) scrollLayer->setPosition(-frameView->scrollPosition()); else { scrollLayer->syncPosition(-frameView->scrollPosition()); LayoutRect viewportRect = frameView->visibleContentRect(); viewportRect.setLocation(IntPoint(frameView->scrollOffsetForFixedPosition())); syncChildPositions(viewportRect); } } #else UNUSED_PARAM(scrollingLayerPositionAction); #endif }
void ScrollingCoordinator::updateMainFrameScrollPosition(const IntPoint& scrollPosition, bool programmaticScroll) { 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)) { if (programmaticScroll) scrollLayer->setPosition(-frameView->scrollPosition()); else scrollLayer->syncPosition(-frameView->scrollPosition()); } #endif }
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::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. }
void PaintLayerCompositor::frameViewDidScroll() { FrameView* frameView = m_layoutView.frameView(); IntPoint scrollPosition = frameView->scrollPosition(); if (!m_scrollLayer) return; bool scrollingCoordinatorHandlesOffset = false; if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator()) { scrollingCoordinatorHandlesOffset = scrollingCoordinator->scrollableAreaScrollLayerDidChange(frameView); } // Scroll position = scroll minimum + scroll offset. Adjust the layer's // position to handle whatever the scroll coordinator isn't handling. // The minimum scroll position is non-zero for RTL pages with overflow. if (scrollingCoordinatorHandlesOffset) m_scrollLayer->setPosition(-frameView->minimumScrollPosition()); else m_scrollLayer->setPosition(-scrollPosition); Platform::current()->histogramEnumeration("Renderer.AcceleratedFixedRootBackground", ScrolledMainFrameBucket, AcceleratedFixedRootBackgroundHistogramMax); }
void ScrollingCoordinator::updateMainFrameScrollPositionAndScrollLayerPosition() { #if USE(ACCELERATED_COMPOSITING) && ENABLE(THREADED_SCROLLING) ASSERT(isMainThread()); if (!m_page) return; FrameView* frameView = m_page->mainFrame()->view(); if (!frameView) return; IntPoint scrollPosition = m_scrollingTree->mainFrameScrollPosition(); // Make sure to update the main frame scroll position before changing the scroll layer position, // otherwise we'll introduce jittering on pages with slow repaint objects (like background-attachment: fixed). frameView->updateCompositingLayers(); frameView->setConstrainsScrollingToContentEdge(false); frameView->notifyScrollPositionChanged(scrollPosition); frameView->setConstrainsScrollingToContentEdge(true); if (GraphicsLayer* scrollLayer = scrollLayerForFrameView(frameView)) scrollLayer->setPosition(-frameView->scrollPosition()); #endif }
void HistoryController::saveScrollPositionAndViewStateToItem(HistoryItem* item) { FrameView* frameView = m_frame.view(); if (!item || !frameView) return; if (m_frame.document()->inPageCache()) item->setScrollPosition(frameView->cachedScrollPosition()); else item->setScrollPosition(frameView->scrollPosition()); #if PLATFORM(IOS) item->setExposedContentRect(frameView->exposedContentRect()); item->setUnobscuredContentRect(frameView->unobscuredContentRect()); #endif Page* page = m_frame.page(); if (page && m_frame.isMainFrame()) { item->setPageScaleFactor(page->pageScaleFactor() / page->viewScaleFactor()); #if PLATFORM(IOS) item->setObscuredInset(page->obscuredInset()); #endif } // FIXME: It would be great to work out a way to put this code in WebCore instead of calling through to the client. m_frame.loader().client().saveViewStateToItem(*item); // Notify clients that the HistoryItem has changed. item->notifyChanged(); }
bool DevToolsEmulator::handleInputEvent(const WebInputEvent& inputEvent) { Page* page = m_webViewImpl->page(); if (!page) return false; // FIXME: This workaround is required for touch emulation on Mac, where // compositor-side pinch handling is not enabled. See http://crbug.com/138003. bool isPinch = inputEvent.type == WebInputEvent::GesturePinchBegin || inputEvent.type == WebInputEvent::GesturePinchUpdate || inputEvent.type == WebInputEvent::GesturePinchEnd; if (isPinch && m_touchEventEmulationEnabled) { FrameView* frameView = page->deprecatedLocalMainFrame()->view(); PlatformGestureEventBuilder gestureEvent(frameView, static_cast<const WebGestureEvent&>(inputEvent)); float pageScaleFactor = page->pageScaleFactor(); if (gestureEvent.type() == PlatformEvent::GesturePinchBegin) { m_lastPinchAnchorCss = adoptPtr(new IntPoint(frameView->scrollPosition() + gestureEvent.position())); m_lastPinchAnchorDip = adoptPtr(new IntPoint(gestureEvent.position())); m_lastPinchAnchorDip->scale(pageScaleFactor, pageScaleFactor); } if (gestureEvent.type() == PlatformEvent::GesturePinchUpdate && m_lastPinchAnchorCss) { float newPageScaleFactor = pageScaleFactor * gestureEvent.scale(); IntPoint anchorCss(*m_lastPinchAnchorDip.get()); anchorCss.scale(1.f / newPageScaleFactor, 1.f / newPageScaleFactor); m_webViewImpl->setPageScaleFactor(newPageScaleFactor); m_webViewImpl->mainFrame()->setScrollOffset(toIntSize(*m_lastPinchAnchorCss.get() - toIntSize(anchorCss))); } if (gestureEvent.type() == PlatformEvent::GesturePinchEnd) { m_lastPinchAnchorCss.clear(); m_lastPinchAnchorDip.clear(); } return true; } return false; }
void Page::setPageScaleFactor(float scale, const IntPoint& origin) { if (!mainFrame()->isLocalFrame()) return; FrameView* view = deprecatedLocalMainFrame()->view(); PinchViewport& viewport = frameHost().pinchViewport(); if (scale != viewport.scale()) { viewport.setScale(scale); if (view && !settings().pinchVirtualViewportEnabled()) view->setVisibleContentScaleFactor(scale); deprecatedLocalMainFrame()->deviceOrPageScaleFactorChanged(); m_chrome->client().deviceOrPageScaleFactorChanged(); // FIXME: In virtual-viewport pinch mode, scale doesn't change the fixed-pos viewport; // remove once it's the only pinch mode in town. if (view) view->viewportConstrainedVisibleContentSizeChanged(true, true); deprecatedLocalMainFrame()->loader().saveScrollState(); } if (view && view->scrollPosition() != origin) view->notifyScrollPositionChanged(origin); }
InRegionScrollableArea::InRegionScrollableArea(WebPagePrivate* webPage, RenderLayer* layer) : m_webPage(webPage) , m_layer(layer) { ASSERT(webPage); ASSERT(layer); m_isNull = false; // FIXME: Add an ASSERT here as the 'layer' must be scrollable. RenderObject* layerRenderer = layer->renderer(); ASSERT(layerRenderer); if (layerRenderer->isRenderView()) { // #document case FrameView* view = toRenderView(layerRenderer)->frameView(); ASSERT(view); Frame* frame = view->frame(); ASSERT_UNUSED(frame, frame); m_scrollPosition = m_webPage->mapToTransformed(view->scrollPosition()); m_contentsSize = m_webPage->mapToTransformed(view->contentsSize()); m_viewportSize = m_webPage->mapToTransformed(view->visibleContentRect(false /*includeScrollbars*/)).size(); m_visibleWindowRect = m_webPage->mapToTransformed(m_webPage->getRecursiveVisibleWindowRect(view)); IntRect transformedWindowRect = IntRect(IntPoint::zero(), m_webPage->transformedViewportSize()); m_visibleWindowRect.intersect(transformedWindowRect); m_scrollsHorizontally = view->contentsWidth() > view->visibleWidth(); m_scrollsVertically = view->contentsHeight() > view->visibleHeight(); m_overscrollLimitFactor = 0.0; // FIXME eventually support overscroll } else { // RenderBox-based elements case (scrollable boxes (div's, p's, textarea's, etc)). RenderBox* box = m_layer->renderBox(); ASSERT(box); ASSERT(box->canBeScrolledAndHasScrollableArea()); ScrollableArea* scrollableArea = static_cast<ScrollableArea*>(m_layer); m_scrollPosition = m_webPage->mapToTransformed(scrollableArea->scrollPosition()); m_contentsSize = m_webPage->mapToTransformed(scrollableArea->contentsSize()); m_viewportSize = m_webPage->mapToTransformed(scrollableArea->visibleContentRect(false /*includeScrollbars*/)).size(); m_visibleWindowRect = m_layer->renderer()->absoluteClippedOverflowRect(); m_visibleWindowRect = m_layer->renderer()->frame()->view()->contentsToWindow(m_visibleWindowRect); IntRect visibleFrameWindowRect = m_webPage->getRecursiveVisibleWindowRect(m_layer->renderer()->frame()->view()); m_visibleWindowRect.intersect(visibleFrameWindowRect); m_visibleWindowRect = m_webPage->mapToTransformed(m_visibleWindowRect); IntRect transformedWindowRect = IntRect(IntPoint::zero(), m_webPage->transformedViewportSize()); m_visibleWindowRect.intersect(transformedWindowRect); m_scrollsHorizontally = box->scrollWidth() != box->clientWidth() && box->scrollsOverflowX(); m_scrollsVertically = box->scrollHeight() != box->clientHeight() && box->scrollsOverflowY(); m_overscrollLimitFactor = 0.0; // FIXME eventually support overscroll } }
bool WebDevToolsAgentImpl::handleInputEvent(WebCore::Page* page, const WebInputEvent& inputEvent) { if (!m_attached && !m_generatingEvent) return false; // FIXME: This workaround is required for touch emulation on Mac, where // compositor-side pinch handling is not enabled. See http://crbug.com/138003. bool isPinch = inputEvent.type == WebInputEvent::GesturePinchBegin || inputEvent.type == WebInputEvent::GesturePinchUpdate || inputEvent.type == WebInputEvent::GesturePinchEnd; if (isPinch && m_touchEventEmulationEnabled && m_emulateViewportEnabled) { FrameView* frameView = page->mainFrame()->view(); PlatformGestureEventBuilder gestureEvent(frameView, *static_cast<const WebGestureEvent*>(&inputEvent)); float pageScaleFactor = page->pageScaleFactor(); if (gestureEvent.type() == PlatformEvent::GesturePinchBegin) { m_lastPinchAnchorCss = adoptPtr(new WebCore::IntPoint(frameView->scrollPosition() + gestureEvent.position())); m_lastPinchAnchorDip = adoptPtr(new WebCore::IntPoint(gestureEvent.position())); m_lastPinchAnchorDip->scale(pageScaleFactor, pageScaleFactor); } if (gestureEvent.type() == PlatformEvent::GesturePinchUpdate && m_lastPinchAnchorCss) { float newPageScaleFactor = pageScaleFactor * gestureEvent.scale(); WebCore::IntPoint anchorCss(*m_lastPinchAnchorDip.get()); anchorCss.scale(1.f / newPageScaleFactor, 1.f / newPageScaleFactor); m_webViewImpl->setPageScaleFactor(newPageScaleFactor); m_webViewImpl->setMainFrameScrollOffset(*m_lastPinchAnchorCss.get() - toIntSize(anchorCss)); } if (gestureEvent.type() == PlatformEvent::GesturePinchEnd) { m_lastPinchAnchorCss.clear(); m_lastPinchAnchorDip.clear(); } return true; } InspectorController* ic = inspectorController(); if (!ic) return false; if (WebInputEvent::isGestureEventType(inputEvent.type) && inputEvent.type == WebInputEvent::GestureTap) { // Only let GestureTab in (we only need it and we know PlatformGestureEventBuilder supports it). PlatformGestureEvent gestureEvent = PlatformGestureEventBuilder(page->mainFrame()->view(), *static_cast<const WebGestureEvent*>(&inputEvent)); return ic->handleGestureEvent(page->mainFrame(), gestureEvent); } if (WebInputEvent::isMouseEventType(inputEvent.type) && inputEvent.type != WebInputEvent::MouseEnter) { // PlatformMouseEventBuilder does not work with MouseEnter type, so we filter it out manually. PlatformMouseEvent mouseEvent = PlatformMouseEventBuilder(page->mainFrame()->view(), *static_cast<const WebMouseEvent*>(&inputEvent)); return ic->handleMouseEvent(page->mainFrame(), mouseEvent); } if (WebInputEvent::isTouchEventType(inputEvent.type)) { PlatformTouchEvent touchEvent = PlatformTouchEventBuilder(page->mainFrame()->view(), *static_cast<const WebTouchEvent*>(&inputEvent)); return ic->handleTouchEvent(page->mainFrame(), touchEvent); } if (WebInputEvent::isKeyboardEventType(inputEvent.type)) { PlatformKeyboardEvent keyboardEvent = PlatformKeyboardEventBuilder(*static_cast<const WebKeyboardEvent*>(&inputEvent)); return ic->handleKeyboardEvent(page->mainFrame(), keyboardEvent); } return false; }
IntSize WebFrame::scrollOffset() const { if (!m_coreFrame) return IntSize(); FrameView* view = m_coreFrame->view(); if (!view) return IntSize(); return toIntSize(view->scrollPosition()); }
void Page::setPageScaleFactor(float scale, const IntPoint& origin) { Document* document = mainFrame()->document(); FrameView* view = document->view(); if (scale == m_pageScaleFactor) { if (view && (view->scrollPosition() != origin || view->delegatesScrolling())) { if (!m_settings->applyPageScaleFactorInCompositor()) document->updateLayoutIgnorePendingStylesheets(); view->setScrollPosition(origin); } return; } m_pageScaleFactor = scale; if (!m_settings->applyPageScaleFactorInCompositor()) { if (document->renderer()) document->renderer()->setNeedsLayout(true); document->recalcStyle(Style::Force); // Transform change on RenderView doesn't trigger repaint on non-composited contents. mainFrame()->view()->invalidateRect(IntRect(LayoutRect::infiniteRect())); } #if USE(ACCELERATED_COMPOSITING) mainFrame()->deviceOrPageScaleFactorChanged(); #endif if (view && view->fixedElementsLayoutRelativeToFrame()) view->setViewportConstrainedObjectsNeedLayout(); if (view && view->scrollPosition() != origin) { if (!m_settings->applyPageScaleFactorInCompositor() && document->renderer() && document->renderer()->needsLayout() && view->didFirstLayout()) view->layout(); view->setScrollPosition(origin); } }
void AsyncScrollingCoordinator::updateMainFrameScrollLayerPosition() { ASSERT(isMainThread()); if (!m_page) return; FrameView* frameView = m_page->mainFrame().view(); if (!frameView) return; if (GraphicsLayer* scrollLayer = scrollLayerForFrameView(*frameView)) scrollLayer->setPosition(-frameView->scrollPosition()); }
void PluginViewPrivate::setVisibleRects(const NPRect rects[], int32_t count) { m_keepVisibleRect = IntRect(); if (!m_view->parent() || !count) return; for (int i = 0; i < count; i++) { IntRect addRect = IntRect(rects[i].left, rects[i].top, rects[i].right - rects[i].left, rects[i].bottom - rects[i].top); m_keepVisibleRect.unite(addRect); } // Don't cause a possible scroll if the result is an empty rectangle. if (m_keepVisibleRect.isEmpty()) return; // Adjust the rect to the parent window and then adjust for scrolling. m_keepVisibleRect = m_view->convertToContainingWindow(m_keepVisibleRect); FrameView* frameView = static_cast<FrameView*>(m_view->parent()); m_keepVisibleRect.move(frameView->scrollPosition().x(), frameView->scrollPosition().y()); frameView->hostWindow()->platformPageClient()->ensureContentVisible(); }
PassRefPtr<WebImage> InjectedBundleRangeHandle::renderedImage(SnapshotOptions options) { Document& ownerDocument = m_range->ownerDocument(); Frame* frame = ownerDocument.frame(); if (!frame) return nullptr; FrameView* frameView = frame->view(); if (!frameView) return nullptr; Ref<Frame> protector(*frame); VisibleSelection oldSelection = frame->selection().selection(); frame->selection().setSelection(VisibleSelection(*m_range)); float scaleFactor = (options & SnapshotOptionsExcludeDeviceScaleFactor) ? 1 : frame->page()->deviceScaleFactor(); IntRect paintRect = enclosingIntRect(m_range->absoluteBoundingRect()); IntSize backingStoreSize = paintRect.size(); backingStoreSize.scale(scaleFactor); RefPtr<ShareableBitmap> backingStore = ShareableBitmap::createShareable(backingStoreSize, ShareableBitmap::SupportsAlpha); if (!backingStore) return nullptr; auto graphicsContext = backingStore->createGraphicsContext(); graphicsContext->scale(scaleFactor); paintRect.move(frameView->frameRect().x(), frameView->frameRect().y()); paintRect.moveBy(-frameView->scrollPosition()); graphicsContext->translate(-paintRect.x(), -paintRect.y()); PaintBehavior oldPaintBehavior = frameView->paintBehavior(); PaintBehavior paintBehavior = oldPaintBehavior | PaintBehaviorSelectionOnly | PaintBehaviorFlattenCompositingLayers; if (options & SnapshotOptionsForceBlackText) paintBehavior |= PaintBehaviorForceBlackText; if (options & SnapshotOptionsForceWhiteText) paintBehavior |= PaintBehaviorForceWhiteText; frameView->setPaintBehavior(paintBehavior); ownerDocument.updateLayout(); frameView->paint(*graphicsContext, paintRect); frameView->setPaintBehavior(oldPaintBehavior); frame->selection().setSelection(oldSelection); return WebImage::create(backingStore); }
void Page::setPageScaleFactor(float scale, const IntPoint& origin) { FrameView* view = mainFrame()->view(); if (scale == m_pageScaleFactor) { if (view && view->scrollPosition() != origin) view->setScrollPosition(origin); return; } m_pageScaleFactor = scale; if (view) view->setVisibleContentScaleFactor(scale); mainFrame()->deviceOrPageScaleFactorChanged(); if (view) view->setViewportConstrainedObjectsNeedLayout(); if (view && view->scrollPosition() != origin) view->setScrollPosition(origin); }
void ScrollingCoordinator::updateMainFrameScrollPositionAndScrollLayerPosition(const IntPoint& scrollPosition) { FrameView* frameView = m_page->mainFrame()->view(); RenderView* renderView = m_page->mainFrame()->contentRenderer(); if (!renderView) return; GraphicsLayer* scrollLayer = renderView->compositor()->scrollLayer(); if (!scrollLayer) return; frameView->updateCompositingLayers(); frameView->setConstrainsScrollingToContentEdge(false); frameView->notifyScrollPositionChanged(scrollPosition); frameView->setConstrainsScrollingToContentEdge(true); scrollLayer->setPosition(-frameView->scrollPosition()); }
void PinchViewport::scrollIntoView(const FloatRect& rect) { if (!mainFrame() || !mainFrame()->view()) return; FrameView* view = mainFrame()->view(); float centeringOffsetX = (visibleRect().width() - rect.width()) / 2; float centeringOffsetY = (visibleRect().height() - rect.height()) / 2; FloatPoint targetOffset( rect.x() - centeringOffsetX - visibleRect().x(), rect.y() - centeringOffsetY - visibleRect().y()); view->setScrollPosition(flooredIntPoint(targetOffset)); FloatPoint remainder = FloatPoint(targetOffset - view->scrollPosition()); move(remainder); }
static bool pointWithScrollAndZoomIfPossible(const Document& document, IntPoint& point) { LocalFrame* frame = document.frame(); if (!frame) return false; FrameView* frameView = frame->view(); if (!frameView) return false; FloatPoint pointInDocument(point); pointInDocument.scale(frame->pageZoomFactor(), frame->pageZoomFactor()); pointInDocument.moveBy(frameView->scrollPosition()); IntPoint roundedPointInDocument = roundedIntPoint(pointInDocument); if (!frameView->visibleContentRect().contains(roundedPointInDocument)) return false; point = roundedPointInDocument; return true; }
void Page::setPageScaleFactor(float scale, const IntPoint& origin) { FrameView* view = mainFrame()->view(); if (scale != m_pageScaleFactor) { m_pageScaleFactor = scale; if (view) view->setVisibleContentScaleFactor(scale); mainFrame()->deviceOrPageScaleFactorChanged(); m_chrome->client().deviceOrPageScaleFactorChanged(); if (view) view->viewportConstrainedVisibleContentSizeChanged(true, true); } if (view && view->scrollPosition() != origin) view->notifyScrollPositionChanged(origin); }
void Page::setPageScaleFactor(float scale, const IntPoint& origin) { FrameView* view = mainFrame()->view(); bool oldProgrammaticScroll = view->inProgrammaticScroll(); view->setInProgrammaticScroll(false); if (scale != m_pageScaleFactor) { m_pageScaleFactor = scale; if (view) view->setVisibleContentScaleFactor(scale); mainFrame()->deviceOrPageScaleFactorChanged(); if (view) view->setViewportConstrainedObjectsNeedLayout(); } if (view && view->scrollPosition() != origin) view->notifyScrollPositionChanged(origin); view->setInProgrammaticScroll(oldProgrammaticScroll); }
InRegionScrollableArea::InRegionScrollableArea(WebPagePrivate* webPage, RenderLayer* layer) : m_webPage(webPage) , m_layer(layer) , m_document(0) , m_hasWindowVisibleRectCalculated(false) { ASSERT(webPage); ASSERT(layer); m_isNull = false; // Add a pointer to the enclosing document as the pointer to layer or node along the way may become invalid. if (m_layer->enclosingElement()) m_document = m_layer->enclosingElement()->document(); // FIXME: Add an ASSERT here as the 'layer' must be scrollable. RenderObject* layerRenderer = layer->renderer(); ASSERT(layerRenderer); if (layerRenderer->isRenderView()) { // #document case RenderView* renderView = toRenderView(layerRenderer); ASSERT(renderView); FrameView* view = toRenderView(layerRenderer)->frameView(); ASSERT(view); Frame* frame = view->frame(); ASSERT_UNUSED(frame, frame); const Platform::ViewportAccessor* viewportAccessor = m_webPage->m_webkitThreadViewportAccessor; m_scrollPosition = viewportAccessor->roundToPixelFromDocumentContents(WebCore::FloatPoint(view->scrollPosition())); m_contentsSize = viewportAccessor->roundToPixelFromDocumentContents(Platform::FloatRect(Platform::FloatPoint::zero(), WebCore::FloatSize(view->contentsSize()))).size(); m_viewportSize = viewportAccessor->roundToPixelFromDocumentContents(WebCore::FloatRect(view->visibleContentRect(ScrollableArea::ExcludeScrollbars))).size(); m_documentViewportRect = view->frameRect(); m_scrollsHorizontally = view->contentsWidth() > view->visibleWidth(); m_scrollsVertically = view->contentsHeight() > view->visibleHeight(); m_supportsCompositedScrolling = true; m_scrollTarget = InnerFrame; ASSERT(!m_cachedNonCompositedScrollableNode); m_camouflagedCompositedScrollableLayer = reinterpret_cast<unsigned>(renderView->compositor()->scrollLayer()->platformLayer()); m_cachedCompositedScrollableLayer = renderView->compositor()->scrollLayer()->platformLayer(); } else { // RenderBox-based elements case (scrollable boxes (div's, p's, textarea's, etc)). RenderBox* box = m_layer->renderBox(); ASSERT(box); ASSERT(InRegionScrollerPrivate::canScrollRenderBox(box)); const Platform::ViewportAccessor* viewportAccessor = m_webPage->m_webkitThreadViewportAccessor; ScrollableArea* scrollableArea = static_cast<ScrollableArea*>(m_layer); m_scrollPosition = viewportAccessor->roundToPixelFromDocumentContents(WebCore::FloatPoint(scrollableArea->scrollPosition())); m_contentsSize = viewportAccessor->roundToPixelFromDocumentContents(Platform::FloatRect(Platform::FloatPoint::zero(), WebCore::FloatSize(scrollableArea->contentsSize()))).size(); m_viewportSize = viewportAccessor->roundToPixelFromDocumentContents(WebCore::FloatRect(scrollableArea->visibleContentRect(ScrollableArea::ExcludeScrollbars))).size(); m_documentViewportRect = enclosingIntRect(box->absoluteClippedOverflowRect()); m_scrollsHorizontally = box->scrollWidth() != box->clientWidth(); m_scrollsVertically = box->scrollHeight() != box->clientHeight(); // Check the overflow if its not an input field because overflow can be set to hidden etc. by the content. if (!DOMSupport::isShadowHostTextInputElement(box->node())) { m_scrollsHorizontally = m_scrollsHorizontally && box->scrollsOverflowX(); m_scrollsVertically = m_scrollsVertically && box->scrollsOverflowY(); } m_scrollTarget = BlockElement; // Both caches below are self-exclusive. if (m_layer->usesCompositedScrolling()) { m_forceContentToBeHorizontallyScrollable = m_scrollsHorizontally; m_forceContentToBeVerticallyScrollable = m_scrollsVertically; // Force content to be scrollable even if it doesn't need to scroll in either direction. if (!m_scrollsHorizontally && !m_scrollsVertically) { if (box->scrollsOverflowY()) m_forceContentToBeVerticallyScrollable = true; else if (box->scrollsOverflowX()) // If it's already forced scrollable vertically, don't force it to scroll horizontally m_forceContentToBeHorizontallyScrollable = true; } m_supportsCompositedScrolling = true; ASSERT(m_layer->backing()->hasScrollingLayer()); m_camouflagedCompositedScrollableLayer = reinterpret_cast<unsigned>(m_layer->backing()->scrollingContentsLayer()->platformLayer()); m_cachedCompositedScrollableLayer = m_layer->backing()->scrollingContentsLayer()->platformLayer(); ASSERT(!m_cachedNonCompositedScrollableNode); } else { m_camouflagedCompositedScrollableLayer = reinterpret_cast<unsigned>(m_layer->enclosingElement()); m_cachedNonCompositedScrollableNode = m_layer->enclosingElement(); ASSERT(!m_cachedCompositedScrollableLayer); } } }
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); } }
InRegionScrollableArea::InRegionScrollableArea(WebPagePrivate* webPage, RenderLayer* layer) : m_webPage(webPage) , m_layer(layer) , m_document(0) , m_hasWindowVisibleRectCalculated(false) { ASSERT(webPage); ASSERT(layer); m_isNull = false; // Add a pointer to the enclosing document as the pointer to layer or node along the way may become invalid. if (m_layer->enclosingElement()) m_document = m_layer->enclosingElement()->document(); // FIXME: Add an ASSERT here as the 'layer' must be scrollable. RenderObject* layerRenderer = layer->renderer(); ASSERT(layerRenderer); if (layerRenderer->isRenderView()) { // #document case RenderView* renderView = toRenderView(layerRenderer); ASSERT(renderView); FrameView* view = toRenderView(layerRenderer)->frameView(); ASSERT(view); Frame* frame = view->frame(); ASSERT_UNUSED(frame, frame); m_scrollPosition = m_webPage->mapToTransformed(view->scrollPosition()); m_contentsSize = m_webPage->mapToTransformed(view->contentsSize()); m_viewportSize = m_webPage->mapToTransformed(view->visibleContentRect(ScrollableArea::ExcludeScrollbars)).size(); m_documentViewportRect = view->frameRect(); m_scrollsHorizontally = view->contentsWidth() > view->visibleWidth(); m_scrollsVertically = view->contentsHeight() > view->visibleHeight(); m_supportsCompositedScrolling = true; m_scrollTarget = InnerFrame; ASSERT(!m_cachedNonCompositedScrollableNode); m_camouflagedCompositedScrollableLayer = reinterpret_cast<unsigned>(renderView->compositor()->scrollLayer()->platformLayer()); m_cachedCompositedScrollableLayer = renderView->compositor()->scrollLayer()->platformLayer(); } else { // RenderBox-based elements case (scrollable boxes (div's, p's, textarea's, etc)). RenderBox* box = m_layer->renderBox(); ASSERT(box); ASSERT(InRegionScrollerPrivate::canScrollRenderBox(box)); ScrollableArea* scrollableArea = static_cast<ScrollableArea*>(m_layer); m_scrollPosition = m_webPage->mapToTransformed(scrollableArea->scrollPosition()); m_contentsSize = m_webPage->mapToTransformed(scrollableArea->contentsSize()); m_viewportSize = m_webPage->mapToTransformed(scrollableArea->visibleContentRect(ScrollableArea::ExcludeScrollbars)).size(); m_documentViewportRect = enclosingIntRect(box->absoluteClippedOverflowRect()); m_scrollsHorizontally = box->scrollWidth() != box->clientWidth(); m_scrollsVertically = box->scrollHeight() != box->clientHeight(); // Check the overflow if its not an input field because overflow can be set to hidden etc. by the content. if (!box->node() || !box->node()->rendererIsEditable()) { m_scrollsHorizontally = m_scrollsHorizontally && box->scrollsOverflowX(); m_scrollsVertically = m_scrollsVertically && box->scrollsOverflowY(); } m_scrollTarget = BlockElement; // Both caches below are self-exclusive. if (m_layer->usesCompositedScrolling()) { m_forceContentToBeVerticallyScrollable = true; m_supportsCompositedScrolling = true; ASSERT(m_layer->backing()->hasScrollingLayer()); m_camouflagedCompositedScrollableLayer = reinterpret_cast<unsigned>(m_layer->backing()->scrollingContentsLayer()->platformLayer()); m_cachedCompositedScrollableLayer = m_layer->backing()->scrollingContentsLayer()->platformLayer(); ASSERT(!m_cachedNonCompositedScrollableNode); } else { m_camouflagedCompositedScrollableLayer = reinterpret_cast<unsigned>(m_layer->enclosingElement()); m_cachedNonCompositedScrollableNode = m_layer->enclosingElement(); ASSERT(!m_cachedCompositedScrollableLayer); } } }