REGRESSION (r155660): box-shadow causes overlay scrollbars to be in the wrong position when element is composited (85647)
https://bugs.webkit.org/show_bug.cgi?id=124090
Source/WebCore:
Reviewed by Beth Dakin.
After r155660 we did fewer layouts, so were left with overlay scrollbars in the
wrong locations because nothing would update them after RenderLayerBacking
computed a new offsetFromRenderer.
First part of the fix is to wean positionOverflowControlsLayers() off of
an absolute offset from the root. Do this by not using Widget::frameRect()
to position the layers, but instead RenderLayer::rectFor{Horizontal|Vertical}Scrollbar
which is what we used to position the scrollbars in the first place.
Second part of the fix is to call positionOverflowControlsLayers() from
RenderLayerBacking::updateGraphicsLayerGeometry() if the offsetFromRenderer
changed.
Test: compositing/overflow/overflow-scrollbar-layer-positions.html
* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::positionOverflowControls):
* rendering/RenderLayerBacking.cpp:
(WebCore::RenderLayerBacking::updateGraphicsLayerGeometry):
(WebCore::RenderLayerBacking::positionOverflowControlsLayers):
* rendering/RenderLayerBacking.h:
LayoutTests:
Reviewed by Beth Dakin.
Test, but it doesn't actually test the fix until we enable overlay scrollbars
in tests (bug 60716).
* compositing/overflow/overflow-scrollbar-layer-positions-expected.txt: Added.
* compositing/overflow/overflow-scrollbar-layer-positions.html: Added.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@159082 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/rendering/RenderLayerBacking.cpp b/Source/WebCore/rendering/RenderLayerBacking.cpp
index 7962365..faab4db 100644
--- a/Source/WebCore/rendering/RenderLayerBacking.cpp
+++ b/Source/WebCore/rendering/RenderLayerBacking.cpp
@@ -697,7 +697,11 @@
m_graphicsLayer->setPosition(FloatPoint(relativeCompositingBounds.location() - graphicsLayerParentLocation));
m_graphicsLayer->setSize(contentsSize);
- m_graphicsLayer->setOffsetFromRenderer(toIntSize(localCompositingBounds.location()));
+ IntSize offsetFromRenderer = toIntSize(localCompositingBounds.location());
+ if (offsetFromRenderer != m_graphicsLayer->offsetFromRenderer()) {
+ m_graphicsLayer->setOffsetFromRenderer(toIntSize(localCompositingBounds.location()));
+ positionOverflowControlsLayers();
+ }
if (!m_isMainFrameRenderViewLayer) {
// For non-root layers, background is always painted by the primary graphics layer.
@@ -1124,35 +1128,36 @@
return horizontalScrollbarLayerChanged || verticalScrollbarLayerChanged || scrollCornerLayerChanged;
}
-void RenderLayerBacking::positionOverflowControlsLayers(const IntSize& offsetFromRoot)
+void RenderLayerBacking::positionOverflowControlsLayers()
{
+ if (!m_owningLayer.hasScrollbars())
+ return;
+
+ const IntRect borderBox = toRenderBox(renderer()).pixelSnappedBorderBoxRect();
+
IntSize offsetFromRenderer = m_graphicsLayer->offsetFromRenderer();
if (GraphicsLayer* layer = layerForHorizontalScrollbar()) {
- Scrollbar* hBar = m_owningLayer.horizontalScrollbar();
- if (hBar) {
- layer->setPosition(hBar->frameRect().location() - offsetFromRoot - offsetFromRenderer);
- layer->setSize(hBar->frameRect().size());
- if (layer->hasContentsLayer()) {
- IntRect barRect = IntRect(IntPoint(), hBar->frameRect().size());
- layer->setContentsRect(barRect);
- layer->setContentsClippingRect(barRect);
- }
+ IntRect hBarRect = m_owningLayer.rectForHorizontalScrollbar(borderBox);
+ layer->setPosition(hBarRect.location() - offsetFromRenderer);
+ layer->setSize(hBarRect.size());
+ if (layer->hasContentsLayer()) {
+ IntRect barRect = IntRect(IntPoint(), hBarRect.size());
+ layer->setContentsRect(barRect);
+ layer->setContentsClippingRect(barRect);
}
- layer->setDrawsContent(hBar && !layer->hasContentsLayer());
+ layer->setDrawsContent(m_owningLayer.horizontalScrollbar() && !layer->hasContentsLayer());
}
if (GraphicsLayer* layer = layerForVerticalScrollbar()) {
- Scrollbar* vBar = m_owningLayer.verticalScrollbar();
- if (vBar) {
- layer->setPosition(vBar->frameRect().location() - offsetFromRoot - offsetFromRenderer);
- layer->setSize(vBar->frameRect().size());
- if (layer->hasContentsLayer()) {
- IntRect barRect = IntRect(IntPoint(), vBar->frameRect().size());
- layer->setContentsRect(barRect);
- layer->setContentsClippingRect(barRect);
- }
+ IntRect vBarRect = m_owningLayer.rectForVerticalScrollbar(borderBox);
+ layer->setPosition(vBarRect.location() - offsetFromRenderer);
+ layer->setSize(vBarRect.size());
+ if (layer->hasContentsLayer()) {
+ IntRect barRect = IntRect(IntPoint(), vBarRect.size());
+ layer->setContentsRect(barRect);
+ layer->setContentsClippingRect(barRect);
}
- layer->setDrawsContent(vBar && !layer->hasContentsLayer());
+ layer->setDrawsContent(m_owningLayer.verticalScrollbar() && !layer->hasContentsLayer());
}
if (GraphicsLayer* layer = layerForScrollCorner()) {