Skip to content

Commit 8a1585e

Browse files
committed
Sticky elements at the edge of the viewport can disappear when rubber band scrolling.
https://bugs.webkit.org/show_bug.cgi?id=298709 <rdar://problem/160385933> Reviewed by Simon Fraser. During rubber-banding the WebContent side layers don't get scrolled (only the UI-side does), but the visible content rect that we use to compute layer visible rects does. If a sticky layer ends up outside this rect (which doesn't account for the 'stuck'-ness), then we detach the backing store. Update the existing RenderLayerBacking::updateAllowsBackingStoreDetaching to account for sticky, as well as the existing handling of fixed. Test: fast/scrolling/ios/sticky-during-rubberband-offscreen.html * LayoutTests/fast/scrolling/ios/sticky-during-rubberband-offscreen-expected.txt: Added. * LayoutTests/fast/scrolling/ios/sticky-during-rubberband-offscreen.html: Added. * Source/WebCore/rendering/RenderLayer.h: * Source/WebCore/rendering/RenderLayerBacking.cpp: (WebCore::RenderLayerBacking::updateAllowsBackingStoreDetaching): * Source/WebCore/rendering/RenderLayerCompositor.cpp: (WebCore::RenderLayerCompositor::allowBackingStoreDetachingForFixedPosition): (WebCore::RenderLayerCompositor::computeCompositingRequirements): Canonical link: https://commits.webkit.org/300544@main
1 parent 82afbdc commit 8a1585e

File tree

5 files changed

+83
-4
lines changed

5 files changed

+83
-4
lines changed
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
(GraphicsLayer
2+
(anchor 0.00 0.00)
3+
(bounds 800.00 600.00)
4+
(backingStoreAttached 1)
5+
(children 1
6+
(GraphicsLayer
7+
(bounds 800.00 600.00)
8+
(contentsOpaque 1)
9+
(backingStoreAttached 1)
10+
(children 1
11+
(GraphicsLayer
12+
(position 1.00 0.00)
13+
(approximate position 1.00 0.00)
14+
(preserves3D 1)
15+
(backingStoreAttached 0)
16+
(children 1
17+
(GraphicsLayer
18+
(bounds 640.00 20.00)
19+
(contentsOpaque 1)
20+
(backingStoreAttached 1)
21+
)
22+
)
23+
)
24+
)
25+
)
26+
)
27+
)
28+
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<!DOCTYPE html>
2+
3+
<html>
4+
<head>
5+
<style>
6+
body {
7+
margin: 0;
8+
}
9+
10+
.sticky-container {
11+
border: 1px solid black;
12+
height: 400px;
13+
width: 80%;
14+
margin-top: -10px;
15+
}
16+
17+
.sticky {
18+
position: sticky;
19+
top: 0px;
20+
height: 20px;
21+
width: 100%;
22+
background-color: green;
23+
}
24+
</style>
25+
<script src="../../../resources/ui-helper.js"></script>
26+
<script>
27+
if (window.testRunner) {
28+
testRunner.dumpAsText();
29+
testRunner.waitUntilDone();
30+
}
31+
window.addEventListener('load', async () => {
32+
await UIHelper.immediateScrollTo(0, 40, true);
33+
await UIHelper.ensurePresentationUpdate();
34+
var out = document.getElementById('out');
35+
out.innerText = internals.layerTreeAsText(document, internals.LAYER_TREE_INCLUDES_BACKING_STORE_ATTACHED);
36+
if (window.testRunner)
37+
testRunner.notifyDone();
38+
}, false);
39+
</script>
40+
</head>
41+
<body>
42+
43+
<div class="sticky-container">
44+
<div class="sticky"></div>
45+
</div>
46+
<pre id="out"></pre>
47+
48+
</body>
49+
</html>

Source/WebCore/rendering/RenderLayer.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -566,6 +566,8 @@ class RenderLayer final : public CanMakeSingleThreadWeakPtr<RenderLayer>, public
566566
void setBehavesAsFixed(bool);
567567
bool behavesAsFixed() const { return m_behavesAsFixed; }
568568

569+
bool behavesAsSticky() const { return m_hasStickyAncestor || renderer().isStickilyPositioned(); }
570+
569571
struct PaintedContentRequest {
570572
PaintedContentRequest() = default;
571573
PaintedContentRequest(const RenderLayer& owningLayer);

Source/WebCore/rendering/RenderLayerBacking.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1087,7 +1087,7 @@ void RenderLayerBacking::updateAllowsBackingStoreDetaching(bool allowDetachingFo
10871087
m_scrolledContentsLayer->setAllowsBackingStoreDetaching(allowDetaching);
10881088
};
10891089

1090-
if (!m_owningLayer.behavesAsFixed()) {
1090+
if (!m_owningLayer.behavesAsFixed() && !m_owningLayer.behavesAsSticky()) {
10911091
setAllowsBackingStoreDetaching(true);
10921092
return;
10931093
}

Source/WebCore/rendering/RenderLayerCompositor.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1241,7 +1241,7 @@ static bool canSkipComputeCompositingRequirementsForSubtree(const RenderLayer& l
12411241

12421242
bool RenderLayerCompositor::allowBackingStoreDetachingForFixedPosition(RenderLayer& layer, const LayoutRect& absoluteBounds)
12431243
{
1244-
ASSERT_UNUSED(layer, layer.behavesAsFixed());
1244+
ASSERT_UNUSED(layer, layer.behavesAsFixed() || layer.behavesAsSticky());
12451245

12461246
// We'll allow detaching if the layer is outside the layout viewport. Fixed layers inside
12471247
// the layout viewport can be revealed by async scrolling, so we want to pin their backing store.
@@ -1387,7 +1387,7 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* ancestor
13871387
layerWillComposite();
13881388
currentState.subtreeIsCompositing = true;
13891389
becameCompositedAfterDescendantTraversal = true;
1390-
if (layer.behavesAsFixed())
1390+
if (layer.behavesAsFixed() || layer.behavesAsSticky())
13911391
allowsBackingStoreDetachingForFixed = allowBackingStoreDetachingForFixedPosition(layer, layerExtent.bounds);
13921392
};
13931393

@@ -1397,7 +1397,7 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* ancestor
13971397
computeExtent(overlapMap, layer, layerExtent);
13981398
currentState.ancestorHasTransformAnimation |= layerExtent.hasTransformAnimation;
13991399

1400-
if (!allowsBackingStoreDetachingForFixed && layer.behavesAsFixed())
1400+
if (!allowsBackingStoreDetachingForFixed && (layer.behavesAsFixed() || layer.behavesAsSticky()))
14011401
currentState.ancestorAllowsBackingStoreDetachingForFixed = allowsBackingStoreDetachingForFixed = allowBackingStoreDetachingForFixedPosition(layer, layerExtent.bounds);
14021402

14031403
// Too hard to compute animated bounds if both us and some ancestor is animating transform.

0 commit comments

Comments
 (0)