box-shadow causes overlay scrollbars to be in the wrong position when element is...
authorsimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 8 Sep 2012 00:48:40 +0000 (00:48 +0000)
committersimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 8 Sep 2012 00:48:40 +0000 (00:48 +0000)
https://bugs.webkit.org/show_bug.cgi?id=85647

Reviewed by James Robinson.

Test overlay scrollbars in composited layers.

* ManualTests/scrollbars/scrollbars-in-composited-layers.html: Added.

Source/WebCore:

The code that positioned the GraphicsLayers for scrollbars failed to take
into account any offset between the origin of the compositing layer,
and the renderer. This caused scrollbar layers to be misplaced or hidden
on layers with, for example, box-shadows.

Also moved the code that positions the scrollbar layers into RendderLayerBacking,
since this is where all the rest of the GraphicsLayer-positioning code lives.

Renamed an "offsetFromLayer" param to "offsetFromRoot" which is more accurate.

Manual test, since overlay scrollbars are not enabled in DRT/WTR:
    ManualTests/scrollbars/scrollbars-in-composited-layers.html

* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::positionOverflowControls):
* rendering/RenderLayerBacking.cpp:
(WebCore::RenderLayerBacking::positionOverflowControlsLayers):
* rendering/RenderLayerBacking.h:
(RenderLayerBacking):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@127943 268f45cc-cd09-0410-ab3c-d52691b4dbfc

ChangeLog
ManualTests/scrollbars/scrollbars-in-composited-layers.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/rendering/RenderLayer.cpp
Source/WebCore/rendering/RenderLayerBacking.cpp
Source/WebCore/rendering/RenderLayerBacking.h

index a9e1924afd361bdbbcb5e9f76ba8afdd62f4da29..3fba05ab3858cc05a65debbca2a7f3bd37069c38 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2012-09-07  Simon Fraser  <simon.fraser@apple.com>
+
+        box-shadow causes overlay scrollbars to be in the wrong position when element is composited
+        https://bugs.webkit.org/show_bug.cgi?id=85647
+
+        Reviewed by James Robinson.
+
+        Test overlay scrollbars in composited layers.
+
+        * ManualTests/scrollbars/scrollbars-in-composited-layers.html: Added.
+
 2012-09-07  Martin Robinson  <mrobinson@igalia.com>
 
         [GTK] Move user agent helpers to WebCore
diff --git a/ManualTests/scrollbars/scrollbars-in-composited-layers.html b/ManualTests/scrollbars/scrollbars-in-composited-layers.html
new file mode 100644 (file)
index 0000000..b45d835
--- /dev/null
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+    <style>
+    .scroll {
+        width: 200px;
+        height: 200px;
+        border: 1px solid black;
+        margin: 15px;
+        padding: 5px;
+        overflow-y: scroll;
+        -webkit-transform: translateZ(0);
+        box-shadow: 0 0 15px black;
+    }
+
+    .rotated {
+        -webkit-transform: rotate3d(0, 0, 1, 45deg);
+    }
+    .scroll > div {
+        background-color: silver;
+        width: 500px;
+        height: 1000px;
+    }
+    </style>
+</head>
+<body>
+
+    <p>Overlay scrollbars (on Mac) should show in the correct place when scrolling.</p>
+    <div class="scroll">
+        <div></div>
+    </div>
+
+    <p>Overlay scrollbars (on Mac) should show in the correct place when scrolling, and the resize corner should show in the correct place.</p>
+    <div class="scroll" style="resize: both; overflow:hiddens">
+        <div></div>
+    </div>
+
+    <p>Overlay scrollbars (on Mac) should show in the correct place when scrolling, and the resize corner should show in the correct place.</p>
+    <div class="rotated scroll" style="resize: both; overflow:hiddens">
+        <div></div>
+    </div>
+
+</body>
+</html>
index 53beb6ed981245073daa735ba31509d332b40296..e4f078d0f81ddd723bbfef8b2fdfc792bec4f298 100644 (file)
@@ -1,3 +1,30 @@
+2012-09-07  Simon Fraser  <simon.fraser@apple.com>
+
+        box-shadow causes overlay scrollbars to be in the wrong position when element is composited
+        https://bugs.webkit.org/show_bug.cgi?id=85647
+
+        Reviewed by James Robinson.
+
+        The code that positioned the GraphicsLayers for scrollbars failed to take
+        into account any offset between the origin of the compositing layer,
+        and the renderer. This caused scrollbar layers to be misplaced or hidden
+        on layers with, for example, box-shadows.
+        
+        Also moved the code that positions the scrollbar layers into RendderLayerBacking,
+        since this is where all the rest of the GraphicsLayer-positioning code lives.
+        
+        Renamed an "offsetFromLayer" param to "offsetFromRoot" which is more accurate.
+
+        Manual test, since overlay scrollbars are not enabled in DRT/WTR:
+            ManualTests/scrollbars/scrollbars-in-composited-layers.html
+
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::positionOverflowControls):
+        * rendering/RenderLayerBacking.cpp:
+        (WebCore::RenderLayerBacking::positionOverflowControlsLayers):
+        * rendering/RenderLayerBacking.h:
+        (RenderLayerBacking):
+
 2012-09-07  David Reveman  <reveman@chromium.org>
 
         [Chromium] Multiple commits without invalidation allowed per redraw.
index 600be7b07a72a0a88ed932988a3d615c9db8cd35..271999385c91060fc83a50b868424752bf702a42 100644 (file)
@@ -2430,7 +2430,7 @@ bool RenderLayer::hasOverflowControls() const
     return m_hBar || m_vBar || m_scrollCorner || renderer()->style()->resize() != RESIZE_NONE;
 }
 
-void RenderLayer::positionOverflowControls(const IntSize& offsetFromLayer)
+void RenderLayer::positionOverflowControls(const IntSize& offsetFromRoot)
 {
     if (!m_hBar && !m_vBar && (!renderer()->hasOverflowClip() || renderer()->style()->resize() == RESIZE_NONE))
         return;
@@ -2441,7 +2441,7 @@ void RenderLayer::positionOverflowControls(const IntSize& offsetFromLayer)
 
     const IntRect borderBox = box->pixelSnappedBorderBoxRect();
     const IntRect& scrollCorner = scrollCornerRect();
-    IntRect absBounds(borderBox.location() + offsetFromLayer, borderBox.size());
+    IntRect absBounds(borderBox.location() + offsetFromRoot, borderBox.size());
     if (m_vBar)
         m_vBar->setFrameRect(IntRect(verticalScrollbarStart(absBounds.x(), absBounds.maxX()),
                                      absBounds.y() + box->borderTop(),
@@ -2454,34 +2454,15 @@ void RenderLayer::positionOverflowControls(const IntSize& offsetFromLayer)
                                      absBounds.width() - (box->borderLeft() + box->borderRight()) - scrollCorner.width(),
                                      m_hBar->height()));
 
-#if USE(ACCELERATED_COMPOSITING)
-    if (GraphicsLayer* layer = layerForHorizontalScrollbar()) {
-        if (m_hBar) {
-            layer->setPosition(m_hBar->frameRect().location() - offsetFromLayer);
-            layer->setSize(m_hBar->frameRect().size());
-        }
-        layer->setDrawsContent(m_hBar);
-    }
-    if (GraphicsLayer* layer = layerForVerticalScrollbar()) {
-        if (m_vBar) {
-            layer->setPosition(m_vBar->frameRect().location() - offsetFromLayer);
-            layer->setSize(m_vBar->frameRect().size());
-        }
-        layer->setDrawsContent(m_vBar);
-    }
-
-    if (GraphicsLayer* layer = layerForScrollCorner()) {
-        const LayoutRect& scrollCornerAndResizer = scrollCornerAndResizerRect();
-        layer->setPosition(scrollCornerAndResizer.location());
-        layer->setSize(scrollCornerAndResizer.size());
-        layer->setDrawsContent(!scrollCornerAndResizer.isEmpty());
-    }
-#endif
-
     if (m_scrollCorner)
         m_scrollCorner->setFrameRect(scrollCorner);
     if (m_resizer)
         m_resizer->setFrameRect(resizerCornerRect(this, borderBox));
+
+#if USE(ACCELERATED_COMPOSITING)    
+    if (isComposited())
+        backing()->positionOverflowControlsLayers(offsetFromRoot);
+#endif
 }
 
 int RenderLayer::scrollWidth() const
index ac6a47ae89abee6bd14c4cb48899509247233732..26cd50f5056c5540cfc57a0f0eca595d1707583e 100644 (file)
@@ -848,6 +848,35 @@ bool RenderLayerBacking::updateOverflowControlsLayers(bool needsHorizontalScroll
     return layersChanged;
 }
 
+void RenderLayerBacking::positionOverflowControlsLayers(const IntSize& offsetFromRoot)
+{
+    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());
+        }
+        layer->setDrawsContent(hBar);
+    }
+    
+    if (GraphicsLayer* layer = layerForVerticalScrollbar()) {
+        Scrollbar* vBar = m_owningLayer->verticalScrollbar();
+        if (vBar) {
+            layer->setPosition(vBar->frameRect().location() - offsetFromRoot - offsetFromRenderer);
+            layer->setSize(vBar->frameRect().size());
+        }
+        layer->setDrawsContent(vBar);
+    }
+
+    if (GraphicsLayer* layer = layerForScrollCorner()) {
+        const LayoutRect& scrollCornerAndResizer = m_owningLayer->scrollCornerAndResizerRect();
+        layer->setPosition(scrollCornerAndResizer.location() - offsetFromRenderer);
+        layer->setSize(scrollCornerAndResizer.size());
+        layer->setDrawsContent(!scrollCornerAndResizer.isEmpty());
+    }
+}
+
 bool RenderLayerBacking::updateForegroundLayer(bool needsForegroundLayer)
 {
     bool layerChanged = false;
index 82a3faa0def7616f798cf863039ae4cb14ee01eb..0508b52bb2fb6a79ba372e9aa904ccb0b51c5945 100644 (file)
@@ -131,6 +131,7 @@ public:
     void updateCompositedBounds();
     
     void updateAfterWidgetResize();
+    void positionOverflowControlsLayers(const IntSize& offsetFromRoot);
 
     // GraphicsLayerClient interface
     virtual bool shouldUseTileCache(const GraphicsLayer*) const;