diff options
Diffstat (limited to 'Source/WebCore/rendering/RenderLayer.cpp')
-rw-r--r-- | Source/WebCore/rendering/RenderLayer.cpp | 108 |
1 files changed, 80 insertions, 28 deletions
diff --git a/Source/WebCore/rendering/RenderLayer.cpp b/Source/WebCore/rendering/RenderLayer.cpp index bc0d440..3c6bc31 100644 --- a/Source/WebCore/rendering/RenderLayer.cpp +++ b/Source/WebCore/rendering/RenderLayer.cpp @@ -178,6 +178,7 @@ RenderLayer::RenderLayer(RenderBoxModelObject* renderer) , m_hasCompositingDescendant(false) , m_mustOverlapCompositedLayers(false) #endif + , m_containsDirtyOverlayScrollbars(false) #if ENABLE(ANDROID_OVERFLOW_SCROLL) , m_hasOverflowScroll(false) #endif @@ -194,6 +195,13 @@ RenderLayer::RenderLayer(RenderBoxModelObject* renderer) m_visibleContentStatusDirty = false; m_hasVisibleContent = renderer->style()->visibility() == VISIBLE; } + + if (Frame* frame = renderer->frame()) { + if (Page* page = frame->page()) { + m_page = page; + m_page->addScrollableArea(this); + } + } } RenderLayer::~RenderLayer() @@ -203,6 +211,9 @@ RenderLayer::~RenderLayer() frame->eventHandler()->resizeLayerDestroyed(); } + if (m_page) + m_page->removeScrollableArea(this); + destroyScrollbar(HorizontalScrollbar); destroyScrollbar(VerticalScrollbar); @@ -268,19 +279,6 @@ bool RenderLayer::canRender3DTransforms() const void RenderLayer::updateLayerPositions(UpdateLayerPositionsFlags flags, IntPoint* cachedOffset) { - if (flags & DoFullRepaint) { - renderer()->repaint(); -#if USE(ACCELERATED_COMPOSITING) - flags &= ~CheckForRepaint; - // We need the full repaint to propagate to child layers if we are hardware compositing. - if (!compositor()->inCompositingMode()) - flags &= ~DoFullRepaint; -#else - flags &= ~(CheckForRepaint | DoFullRepaint); -#endif - } - - updateLayerPosition(); // For relpositioned layers or non-positioned layers, // we need to keep in sync, since we may have shifted relative // to our parent layer. @@ -1121,6 +1119,7 @@ void RenderLayer::removeOnlyThisLayer() RenderLayer* next = current->nextSibling(); removeChild(current); parent->addChild(current, nextSib); + current->setNeedsFullRepaint(); current->updateLayerPositions(); // Depends on hasLayer() already being false for proper layout. current = next; } @@ -1806,6 +1805,19 @@ int RenderLayer::visibleWidth() const return m_width; } +bool RenderLayer::shouldSuspendScrollAnimations() const +{ + RenderView* view = renderer()->view(); + if (!view) + return true; + return view->frameView()->shouldSuspendScrollAnimations(); +} + +IntPoint RenderLayer::currentMousePosition() const +{ + return renderer()->frame() ? renderer()->frame()->eventHandler()->currentMousePosition() : IntPoint(); +} + IntSize RenderLayer::scrollbarOffset(const Scrollbar* scrollbar) const { RenderBox* box = renderBox(); @@ -1915,16 +1927,16 @@ void RenderLayer::setHasVerticalScrollbar(bool hasScrollbar) #endif } -int RenderLayer::verticalScrollbarWidth() const +int RenderLayer::verticalScrollbarWidth(OverlayScrollbarSizeRelevancy relevancy) const { - if (!m_vBar || m_vBar->isOverlayScrollbar()) + if (!m_vBar || (m_vBar->isOverlayScrollbar() && relevancy == IgnoreOverlayScrollbarSize)) return 0; return m_vBar->width(); } -int RenderLayer::horizontalScrollbarHeight() const +int RenderLayer::horizontalScrollbarHeight(OverlayScrollbarSizeRelevancy relevancy) const { - if (!m_hBar || m_hBar->isOverlayScrollbar()) + if (!m_hBar || (m_hBar->isOverlayScrollbar() && relevancy == IgnoreOverlayScrollbarSize)) return 0; return m_hBar->height(); } @@ -2214,16 +2226,36 @@ void RenderLayer::updateScrollInfoAfterLayout() #endif } -void RenderLayer::paintOverflowControls(GraphicsContext* context, int tx, int ty, const IntRect& damageRect) +void RenderLayer::paintOverflowControls(GraphicsContext* context, int tx, int ty, const IntRect& damageRect, bool paintingOverlayControls) { // Don't do anything if we have no overflow. if (!renderer()->hasOverflowClip()) return; - + + // Overlay scrollbars paint in a second pass through the layer tree so that they will paint + // on top of everything else. If this is the normal painting pass, paintingOverlayControls + // will be false, and we should just tell the root layer that there are overlay scrollbars + // that need to be painted. That will cause the second pass through the layer tree to run, + // and we'll paint the scrollbars then. In the meantime, cache tx and ty so that the + // second pass doesn't need to re-enter the RenderTree to get it right. + if (hasOverlayScrollbars() && !paintingOverlayControls) { + RenderLayer* rootLayer = renderer()->view()->layer(); + rootLayer->setContainsDirtyOverlayScrollbars(true); + m_cachedOverlayScrollbarOffset = IntPoint(tx, ty); + return; + } + + int offsetX = tx; + int offsetY = ty; + if (paintingOverlayControls) { + offsetX = m_cachedOverlayScrollbarOffset.x(); + offsetY = m_cachedOverlayScrollbarOffset.y(); + } + // Move the scrollbar widgets if necessary. We normally move and resize widgets during layout, but sometimes // widgets can move without layout occurring (most notably when you scroll a document that // contains fixed positioned elements). - positionOverflowControls(tx, ty); + positionOverflowControls(offsetX, offsetY); // Now that we're sure the scrollbars are in the right place, paint them. if (m_hBar) @@ -2233,10 +2265,10 @@ void RenderLayer::paintOverflowControls(GraphicsContext* context, int tx, int ty // We fill our scroll corner with white if we have a scrollbar that doesn't run all the way up to the // edge of the box. - paintScrollCorner(context, tx, ty, damageRect); + paintScrollCorner(context, offsetX, offsetY, damageRect); // Paint our resizer last, since it sits on top of the scroll corner. - paintResizer(context, tx, ty, damageRect); + paintResizer(context, offsetX, offsetY, damageRect); } void RenderLayer::paintScrollCorner(GraphicsContext* context, int tx, int ty, const IntRect& damageRect) @@ -2258,8 +2290,11 @@ void RenderLayer::paintScrollCorner(GraphicsContext* context, int tx, int ty, co m_scrollCorner->paintIntoRect(context, tx, ty, absRect); return; } - - context->fillRect(absRect, Color::white, box->style()->colorSpace()); + + // We don't want to paint white if we have overlay scrollbars, since we need + // to see what is behind it. + if (!hasOverlayScrollbars()) + context->fillRect(absRect, Color::white, box->style()->colorSpace()); } void RenderLayer::paintResizer(GraphicsContext* context, int tx, int ty, const IntRect& damageRect) @@ -2376,6 +2411,15 @@ void RenderLayer::paint(GraphicsContext* p, const IntRect& damageRect, PaintBeha it->first->setOverlapTestResult(false); } +void RenderLayer::paintOverlayScrollbars(GraphicsContext* p, const IntRect& damageRect, PaintBehavior paintBehavior, RenderObject *paintingRoot) +{ + if (!m_containsDirtyOverlayScrollbars) + return; + paintLayer(this, p, damageRect, paintBehavior, paintingRoot, 0, PaintLayerHaveTransparency | PaintLayerTemporaryClipRects + | PaintLayerPaintingOverlayScrollbars); + m_containsDirtyOverlayScrollbars = false; +} + static void setClip(GraphicsContext* p, const IntRect& paintDirtyRect, const IntRect& clipRect) { if (paintDirtyRect == clipRect) @@ -2526,9 +2570,11 @@ void RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p, if (overlapTestRequests && isSelfPaintingLayer()) performOverlapTests(*overlapTestRequests, rootLayer, this); + bool paintingOverlayScrollbars = paintFlags & PaintLayerPaintingOverlayScrollbars; + // We want to paint our layer, but only if we intersect the damage rect. bool shouldPaint = intersectsDamageRect(layerBounds, damageRect, rootLayer) && m_hasVisibleContent && isSelfPaintingLayer(); - if (shouldPaint && !selectionOnly && !damageRect.isEmpty()) { + if (shouldPaint && !selectionOnly && !damageRect.isEmpty() && !paintingOverlayScrollbars) { // Begin transparency layers lazily now that we know we have to paint something. if (haveTransparency) beginTransparencyLayers(p, rootLayer, paintBehavior); @@ -2549,7 +2595,7 @@ void RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p, paintList(m_negZOrderList, rootLayer, p, paintDirtyRect, paintBehavior, paintingRoot, overlapTestRequests, localPaintFlags); // Now establish the appropriate clip and paint our child RenderObjects. - if (shouldPaint && !clipRectToApply.isEmpty()) { + if (shouldPaint && !clipRectToApply.isEmpty() && !paintingOverlayScrollbars) { // Begin transparency layers lazily now that we know we have to paint something. if (haveTransparency) beginTransparencyLayers(p, rootLayer, paintBehavior); @@ -2574,7 +2620,7 @@ void RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p, restoreClip(p, paintDirtyRect, clipRectToApply); } - if (!outlineRect.isEmpty() && isSelfPaintingLayer()) { + if (!outlineRect.isEmpty() && isSelfPaintingLayer() && !paintingOverlayScrollbars) { // Paint our own outline PaintInfo paintInfo(p, outlineRect, PaintPhaseSelfOutline, false, paintingRootForRenderer, 0); setClip(p, paintDirtyRect, outlineRect); @@ -2588,7 +2634,7 @@ void RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p, // Now walk the sorted list of children with positive z-indices. paintList(m_posZOrderList, rootLayer, p, paintDirtyRect, paintBehavior, paintingRoot, overlapTestRequests, localPaintFlags); - if (renderer()->hasMask() && shouldPaint && !selectionOnly && !damageRect.isEmpty()) { + if (renderer()->hasMask() && shouldPaint && !selectionOnly && !damageRect.isEmpty() && !paintingOverlayScrollbars) { setClip(p, paintDirtyRect, damageRect); // Paint the mask. @@ -2599,6 +2645,12 @@ void RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p, restoreClip(p, paintDirtyRect, damageRect); } + if (paintingOverlayScrollbars) { + setClip(p, paintDirtyRect, damageRect); + paintOverflowControls(p, tx, ty, damageRect, true); + restoreClip(p, paintDirtyRect, damageRect); + } + // End our transparency layer if (haveTransparency && m_usedTransparency && !m_paintingInsideReflection) { p->endTransparencyLayer(); |