void PinchViewports::setupScrollbar(WebScrollbar::Orientation orientation) { bool isHorizontal = orientation == WebScrollbar::Horizontal; GraphicsLayer* scrollbarGraphicsLayer = isHorizontal ? m_overlayScrollbarHorizontal.get() : m_overlayScrollbarVertical.get(); OwnPtr<WebScrollbarLayer>& webScrollbarLayer = isHorizontal ? m_webOverlayScrollbarHorizontal : m_webOverlayScrollbarVertical; const int overlayScrollbarThickness = m_owner->settingsImpl()->pinchOverlayScrollbarThickness(); if (!webScrollbarLayer) { WebCore::ScrollingCoordinator* coordinator = m_owner->page()->scrollingCoordinator(); ASSERT(coordinator); WebCore::ScrollbarOrientation webcoreOrientation = isHorizontal ? WebCore::HorizontalScrollbar : WebCore::VerticalScrollbar; webScrollbarLayer = coordinator->createSolidColorScrollbarLayer(webcoreOrientation, overlayScrollbarThickness, false); webScrollbarLayer->setClipLayer(m_innerViewportContainerLayer->platformLayer()); scrollbarGraphicsLayer->setContentsToPlatformLayer(webScrollbarLayer->layer()); scrollbarGraphicsLayer->setDrawsContent(false); } int xPosition = isHorizontal ? 0 : m_innerViewportContainerLayer->size().width() - overlayScrollbarThickness; int yPosition = isHorizontal ? m_innerViewportContainerLayer->size().height() - overlayScrollbarThickness : 0; int width = isHorizontal ? m_innerViewportContainerLayer->size().width() - overlayScrollbarThickness : overlayScrollbarThickness; int height = isHorizontal ? overlayScrollbarThickness : m_innerViewportContainerLayer->size().height() - overlayScrollbarThickness; // Use the GraphicsLayer to position the scrollbars. scrollbarGraphicsLayer->setPosition(WebCore::IntPoint(xPosition, yPosition)); scrollbarGraphicsLayer->setSize(WebCore::IntSize(width, height)); scrollbarGraphicsLayer->setContentsRect(WebCore::IntRect(0, 0, width, height)); }
PinchViewports::PinchViewports(WebViewImpl* owner) : m_owner(owner) , m_innerViewportContainerLayer(GraphicsLayer::create(m_owner->graphicsLayerFactory(), this)) , m_pageScaleLayer(GraphicsLayer::create(m_owner->graphicsLayerFactory(), this)) , m_innerViewportScrollLayer(GraphicsLayer::create(m_owner->graphicsLayerFactory(), this)) , m_overlayScrollbarHorizontal(GraphicsLayer::create(m_owner->graphicsLayerFactory(), this)) , m_overlayScrollbarVertical(GraphicsLayer::create(m_owner->graphicsLayerFactory(), this)) { ASSERT(m_owner); WebCore::ScrollingCoordinator* coordinator = m_owner->page()->scrollingCoordinator(); ASSERT(coordinator); coordinator->setLayerIsContainerForFixedPositionLayers(m_innerViewportScrollLayer.get(), true); // No need for the inner viewport to clip, since the compositing // surface takes care of it -- and clipping here would interfere with // dynamically-sized viewports on Android. m_innerViewportContainerLayer->setMasksToBounds(false); m_innerViewportScrollLayer->platformLayer()->setScrollClipLayer( m_innerViewportContainerLayer->platformLayer()); m_innerViewportScrollLayer->platformLayer()->setUserScrollable(true, true); m_innerViewportContainerLayer->addChild(m_pageScaleLayer.get()); m_pageScaleLayer->addChild(m_innerViewportScrollLayer.get()); m_innerViewportContainerLayer->addChild(m_overlayScrollbarHorizontal.get()); m_innerViewportContainerLayer->addChild(m_overlayScrollbarVertical.get()); // Setup the inner viewport overlay scrollbars. setupScrollbar(WebScrollbar::Horizontal); setupScrollbar(WebScrollbar::Vertical); }
// Modifies the top of the graphics layer tree to add layers needed to support // the inner/outer viewport fixed-position model for pinch zoom. When finished, // the tree will look like this (with * denoting added layers): // // *rootTransformLayer // +- *innerViewportContainerLayer (fixed pos container) // +- *pageScaleLayer // | +- *innerViewportScrollLayer // | +-- overflowControlsHostLayer (root layer) // | +-- outerViewportContainerLayer (fixed pos container) [frame container layer in RenderLayerCompositor] // | | +-- outerViewportScrollLayer [frame scroll layer in RenderLayerCompositor] // | | +-- content layers ... // | +-- horizontal ScrollbarLayer (non-overlay) // | +-- verticalScrollbarLayer (non-overlay) // | +-- scroll corner (non-overlay) // +- *horizontalScrollbarLayer (overlay) // +- *verticalScrollbarLayer (overlay) // void PinchViewport::attachToLayerTree(GraphicsLayer* currentLayerTreeRoot, GraphicsLayerFactory* graphicsLayerFactory) { TRACE_EVENT1("blink", "PinchViewport::attachToLayerTree", "currentLayerTreeRoot", (bool)currentLayerTreeRoot); if (!currentLayerTreeRoot) { m_innerViewportScrollLayer->removeAllChildren(); return; } if (currentLayerTreeRoot->parent() && currentLayerTreeRoot->parent() == m_innerViewportScrollLayer) return; if (!m_innerViewportScrollLayer) { ASSERT(!m_overlayScrollbarHorizontal && !m_overlayScrollbarVertical && !m_pageScaleLayer && !m_innerViewportContainerLayer); // FIXME: The root transform layer should only be created on demand. m_rootTransformLayer = GraphicsLayer::create(graphicsLayerFactory, this); m_innerViewportContainerLayer = GraphicsLayer::create(graphicsLayerFactory, this); m_pageScaleLayer = GraphicsLayer::create(graphicsLayerFactory, this); m_innerViewportScrollLayer = GraphicsLayer::create(graphicsLayerFactory, this); m_overlayScrollbarHorizontal = GraphicsLayer::create(graphicsLayerFactory, this); m_overlayScrollbarVertical = GraphicsLayer::create(graphicsLayerFactory, this); WebCore::ScrollingCoordinator* coordinator = m_frameHost.page().scrollingCoordinator(); ASSERT(coordinator); coordinator->setLayerIsContainerForFixedPositionLayers(m_innerViewportScrollLayer.get(), true); // Set masks to bounds so the compositor doesn't clobber a manually // set inner viewport container layer size. m_innerViewportContainerLayer->setMasksToBounds(m_frameHost.settings().mainFrameClipsContent()); m_innerViewportContainerLayer->setSize(m_size); m_innerViewportScrollLayer->platformLayer()->setScrollClipLayer( m_innerViewportContainerLayer->platformLayer()); m_innerViewportScrollLayer->platformLayer()->setUserScrollable(true, true); m_rootTransformLayer->addChild(m_innerViewportContainerLayer.get()); m_innerViewportContainerLayer->addChild(m_pageScaleLayer.get()); m_pageScaleLayer->addChild(m_innerViewportScrollLayer.get()); m_innerViewportContainerLayer->addChild(m_overlayScrollbarHorizontal.get()); m_innerViewportContainerLayer->addChild(m_overlayScrollbarVertical.get()); // Ensure this class is set as the scroll layer's ScrollableArea. coordinator->scrollableAreaScrollLayerDidChange(this); // Setup the inner viewport overlay scrollbars. setupScrollbar(WebScrollbar::Horizontal); setupScrollbar(WebScrollbar::Vertical); } m_innerViewportScrollLayer->removeAllChildren(); m_innerViewportScrollLayer->addChild(currentLayerTreeRoot); // We only need to disable the existing (outer viewport) scrollbars // if the existing ones are already overlay. // FIXME: If we knew in advance before the overflowControlsHostLayer goes // away, we would re-enable the drawing of these scrollbars. // FIXME: This doesn't seem to work (at least on Android). Commenting out for now until // I figure out how to access RenderLayerCompositor from here. // if (GraphicsLayer* scrollbar = m_frameHost->compositor()->layerForHorizontalScrollbar()) // scrollbar->setDrawsContent(!page->mainFrame()->view()->hasOverlayScrollbars()); // if (GraphicsLayer* scrollbar = m_frameHost->compositor()->layerForVerticalScrollbar()) // scrollbar->setDrawsContent(!page->mainFrame()->view()->hasOverlayScrollbars()); }