[iOS] position:fixed inside touch-scrollable overflow is mispositioned
authorsimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 30 Jan 2017 22:51:52 +0000 (22:51 +0000)
committersimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 30 Jan 2017 22:51:52 +0000 (22:51 +0000)
https://bugs.webkit.org/show_bug.cgi?id=167604
Source/WebCore:

rdar://problem/29500273

Reviewed by Zalan Bujtas.

For layers inside touch-scrollable overflow, RenderLayerBacking::computeParentGraphicsLayerRect() needs
to account for the offset from the ancestor compositing layer's origin, to handle scrollable elements with
box-shadow, for example.

Also make the compositing log output a little easier to read.

Test: compositing/scrolling/fixed-inside-scroll.html

* rendering/RenderLayerBacking.cpp:
(WebCore::RenderLayerBacking::computeParentGraphicsLayerRect):
* rendering/RenderLayerCompositor.cpp:
(WebCore::RenderLayerCompositor::logLayerInfo):

Source/WebKit2:

rdar://problem/29500273

Reviewed by Zalan Bujtas.

Make sure we tell m_webPageProxy.computeCustomFixedPositionRect() when visual viewports are enabled.

* UIProcess/ios/RemoteScrollingCoordinatorProxyIOS.mm:
(WebKit::RemoteScrollingCoordinatorProxy::customFixedPositionRect):

LayoutTests:

Reviewed by Zalan Bujtas.

* compositing/scrolling/fixed-inside-scroll-expected.html: Added.
* compositing/scrolling/fixed-inside-scroll.html: Added.

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

LayoutTests/ChangeLog
LayoutTests/compositing/scrolling/fixed-inside-scroll-expected.html [new file with mode: 0644]
LayoutTests/compositing/scrolling/fixed-inside-scroll.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/rendering/RenderLayerBacking.cpp
Source/WebCore/rendering/RenderLayerCompositor.cpp
Source/WebKit2/ChangeLog
Source/WebKit2/UIProcess/ios/RemoteScrollingCoordinatorProxyIOS.mm

index a9f3566..62dbc9d 100644 (file)
@@ -1,3 +1,13 @@
+2017-01-30  Simon Fraser  <simon.fraser@apple.com>
+
+        [iOS] position:fixed inside touch-scrollable overflow is mispositioned
+        https://bugs.webkit.org/show_bug.cgi?id=167604
+
+        Reviewed by Zalan Bujtas.
+
+        * compositing/scrolling/fixed-inside-scroll-expected.html: Added.
+        * compositing/scrolling/fixed-inside-scroll.html: Added.
+
 2017-01-30  Matt Baker  <mattbaker@apple.com>
 
         Web Inspector: Need some limit on Async Call Stacks for async loops (rAF loops)
diff --git a/LayoutTests/compositing/scrolling/fixed-inside-scroll-expected.html b/LayoutTests/compositing/scrolling/fixed-inside-scroll-expected.html
new file mode 100644 (file)
index 0000000..7c0c17c
--- /dev/null
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+  <style>
+    html {
+      -webkit-overflow-scrolling: touch;
+    }
+    
+    .scroller {
+        height: 500px;
+        width: 300px;
+        margin: 50px;
+        border: 25px solid gray;
+        padding: 10px;
+        overflow: scroll;
+        box-shadow: 0 0 30px black;
+    }
+    
+    .contents {
+        width: 400px;
+        height: 2000px;
+    }
+
+    .fixed {
+        position: absolute;
+        background-color: green;
+        left: 70px;
+        top: 70px;
+        height: 200px;
+        width: 200px;
+    }
+    
+    .indicator {
+        position: absolute;
+        left: 70px;
+        top: 70px;
+        height: 200px;
+        width: 200px;
+        background-color: red;
+    }
+  </style>
+</head>
+<body>
+    <div class="indicator"></div>
+    <div id="scroller" class="scroller">
+        <div class="contents">
+            <div class="fixed box"></div>
+        </div>
+    </div>
+</body>
+</html>
diff --git a/LayoutTests/compositing/scrolling/fixed-inside-scroll.html b/LayoutTests/compositing/scrolling/fixed-inside-scroll.html
new file mode 100644 (file)
index 0000000..fd04d4b
--- /dev/null
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+  <style>
+    html {
+      -webkit-overflow-scrolling: touch;
+    }
+    
+    .scroller {
+        height: 500px;
+        width: 300px;
+        margin: 50px;
+        border: 25px solid gray;
+        padding: 10px;
+        overflow: scroll;
+        box-shadow: 0 0 30px black;
+    }
+    
+    .contents {
+        width: 400px;
+        height: 2000px;
+    }
+
+    .fixed {
+        position: fixed;
+        background-color: green;
+        left: 70px;
+        top: 70px;
+        height: 200px;
+        width: 200px;
+    }
+    
+    .indicator {
+        position: absolute;
+        left: 70px;
+        top: 70px;
+        height: 200px;
+        width: 200px;
+        background-color: red;
+    }
+  </style>
+</head>
+<body>
+    <div class="indicator"></div>
+    <div id="scroller" class="scroller">
+        <div class="contents">
+            <div class="fixed box"></div>
+        </div>
+    </div>
+</body>
+</html>
index edfa03d..9632c30 100644 (file)
@@ -1,3 +1,24 @@
+2017-01-30  Simon Fraser  <simon.fraser@apple.com>
+
+        [iOS] position:fixed inside touch-scrollable overflow is mispositioned
+        https://bugs.webkit.org/show_bug.cgi?id=167604
+        rdar://problem/29500273
+
+        Reviewed by Zalan Bujtas.
+        
+        For layers inside touch-scrollable overflow, RenderLayerBacking::computeParentGraphicsLayerRect() needs
+        to account for the offset from the ancestor compositing layer's origin, to handle scrollable elements with
+        box-shadow, for example.
+        
+        Also make the compositing log output a little easier to read.
+
+        Test: compositing/scrolling/fixed-inside-scroll.html
+
+        * rendering/RenderLayerBacking.cpp:
+        (WebCore::RenderLayerBacking::computeParentGraphicsLayerRect):
+        * rendering/RenderLayerCompositor.cpp:
+        (WebCore::RenderLayerCompositor::logLayerInfo):
+
 2017-01-30  Jer Noble  <jer.noble@apple.com>
 
         NULL-deref crash at PlatformMediaSession::endInterruption
index cd20d44..afcfdd7 100644 (file)
@@ -813,12 +813,11 @@ LayoutRect RenderLayerBacking::computeParentGraphicsLayerRect(RenderLayer* compo
 
 #if PLATFORM(IOS)
     if (compositedAncestor->hasTouchScrollableOverflow()) {
+        LayoutRect ancestorCompositedBounds = ancestorBackingLayer->compositedBounds();
         auto& renderBox = downcast<RenderBox>(compositedAncestor->renderer());
-        LayoutRect paddingBox(renderBox.borderLeft(), renderBox.borderTop(),
-            renderBox.width() - renderBox.borderLeft() - renderBox.borderRight(),
-            renderBox.height() - renderBox.borderTop() - renderBox.borderBottom());
+        LayoutRect paddingBox(renderBox.borderLeft(), renderBox.borderTop(), renderBox.width() - renderBox.borderLeft() - renderBox.borderRight(), renderBox.height() - renderBox.borderTop() - renderBox.borderBottom());
         ScrollOffset scrollOffset = compositedAncestor->scrollOffset();
-        parentGraphicsLayerRect = LayoutRect((paddingBox.location() - toLayoutSize(scrollOffset)), paddingBox.size());
+        parentGraphicsLayerRect = LayoutRect((paddingBox.location() - toLayoutSize(ancestorCompositedBounds.location()) - toLayoutSize(scrollOffset)), paddingBox.size());
     }
 #else
     if (compositedAncestor->needsCompositedScrolling()) {
index e40594f..e2fe115 100644 (file)
@@ -809,7 +809,7 @@ void RenderLayerCompositor::logLayerInfo(const RenderLayer& layer, int depth)
     absoluteBounds.move(layer.offsetFromAncestor(m_renderView.layer()));
     
     StringBuilder logString;
-    logString.append(String::format("%*p (%.6f,%.6f-%.6f,%.6f) %.2fKB", 12 + depth * 2, &layer,
+    logString.append(String::format("%*p (%.3f,%.3f-%.3f,%.3f) %.2fKB", 12 + depth * 2, &layer,
         absoluteBounds.x().toFloat(), absoluteBounds.y().toFloat(), absoluteBounds.maxX().toFloat(), absoluteBounds.maxY().toFloat(),
         backing->backingStoreMemoryEstimate() / 1024));
     
index 85da650..045432e 100644 (file)
@@ -1,5 +1,18 @@
 2017-01-30  Simon Fraser  <simon.fraser@apple.com>
 
+        [iOS] position:fixed inside touch-scrollable overflow is mispositioned
+        https://bugs.webkit.org/show_bug.cgi?id=167604
+        rdar://problem/29500273
+
+        Reviewed by Zalan Bujtas.
+
+        Make sure we tell m_webPageProxy.computeCustomFixedPositionRect() when visual viewports are enabled.
+
+        * UIProcess/ios/RemoteScrollingCoordinatorProxyIOS.mm:
+        (WebKit::RemoteScrollingCoordinatorProxy::customFixedPositionRect):
+
+2017-01-30  Simon Fraser  <simon.fraser@apple.com>
+
         Fixed elements should not rubber-band in WK2, nor remain at negative offsets
         https://bugs.webkit.org/show_bug.cgi?id=167484
         rdar://problem/29453068
index dcaa47e..db92f13 100644 (file)
@@ -95,7 +95,8 @@ void RemoteScrollingCoordinatorProxy::connectStateNodeLayers(ScrollingStateTree&
 
 FloatRect RemoteScrollingCoordinatorProxy::customFixedPositionRect() const
 {
-    return m_webPageProxy.computeCustomFixedPositionRect(m_webPageProxy.unobscuredContentRect(), m_webPageProxy.unobscuredContentRectRespectingInputViewBounds(), m_webPageProxy.customFixedPositionRect(), m_webPageProxy.displayedContentScale());
+    return m_webPageProxy.computeCustomFixedPositionRect(m_webPageProxy.unobscuredContentRect(), m_webPageProxy.unobscuredContentRectRespectingInputViewBounds(), m_webPageProxy.customFixedPositionRect(),
+        m_webPageProxy.displayedContentScale(), WebPageProxy::UnobscuredRectConstraint::Unconstrained, visualViewportEnabled());
 }
 
 void RemoteScrollingCoordinatorProxy::scrollingTreeNodeWillStartPanGesture()