Diff
Modified: trunk/LayoutTests/ChangeLog (243133 => 243134)
--- trunk/LayoutTests/ChangeLog 2019-03-19 08:31:05 UTC (rev 243133)
+++ trunk/LayoutTests/ChangeLog 2019-03-19 11:07:42 UTC (rev 243134)
@@ -1,3 +1,26 @@
+2019-03-19 Antti Koivisto <[email protected]>
+
+ Layer with no backing store should still hit-test over a scroller
+ https://bugs.webkit.org/show_bug.cgi?id=195378
+ <rdar://problem/48652078>
+
+ Reviewed by Simon Fraser.
+
+ Reorganize the tests a bit and add some new ones.
+
+ * fast/scrolling/ios/overflow-scroll-overlap-2-expected.txt:
+ * fast/scrolling/ios/overflow-scroll-overlap-2.html:
+ * fast/scrolling/ios/overflow-scroll-overlap-3-expected.txt: Added.
+ * fast/scrolling/ios/overflow-scroll-overlap-3.html: Added.
+ * fast/scrolling/ios/overflow-scroll-overlap-4-expected.txt: Added.
+ * fast/scrolling/ios/overflow-scroll-overlap-4.html: Added.
+ * fast/scrolling/ios/overflow-scroll-overlap.html:
+ * fast/scrolling/resources/overflow-scroll-overlap.js: Added.
+ (sleep):
+ (async.runTest):
+ (logScroll):
+ (outputCase):
+
2019-03-18 Commit Queue <[email protected]>
Unreviewed, rolling out r243092 and r243096.
Modified: trunk/LayoutTests/fast/scrolling/ios/overflow-scroll-overlap-2-expected.txt (243133 => 243134)
--- trunk/LayoutTests/fast/scrolling/ios/overflow-scroll-overlap-2-expected.txt 2019-03-19 08:31:05 UTC (rev 243133)
+++ trunk/LayoutTests/fast/scrolling/ios/overflow-scroll-overlap-2-expected.txt 2019-03-19 11:07:42 UTC (rev 243134)
@@ -1,9 +1,8 @@
Test that scrollable areas with non-trivial overlap are correctly targeted.
-case 1:
-case 2: Scrollable 2
+case 1: Scrollable 1
+case 2:
case 3: Scrollable 3
case 4: Scrollable 4
-case 5: Scrollable 5
-case 6:
+case 5:
Modified: trunk/LayoutTests/fast/scrolling/ios/overflow-scroll-overlap-2.html (243133 => 243134)
--- trunk/LayoutTests/fast/scrolling/ios/overflow-scroll-overlap-2.html 2019-03-19 08:31:05 UTC (rev 243133)
+++ trunk/LayoutTests/fast/scrolling/ios/overflow-scroll-overlap-2.html 2019-03-19 11:07:42 UTC (rev 243134)
@@ -33,6 +33,14 @@
height: 100px;
background: red;
}
+.overlapping-empty {
+ position:absolute;
+ left: 25px;
+ top: 25px;
+ width: 100px;
+ height: 100px;
+ background: blue;
+}
.clip {
position:absolute;
width: 100px;
@@ -49,85 +57,7 @@
}
</style>
<script src=""
-<script type="text/_javascript_">
-if (window.testRunner) {
- testRunner.dumpAsText();
- testRunner.waitUntilDone();
- internals.settings.setAsyncFrameScrollingEnabled(true);
- internals.settings.setAsyncOverflowScrollingEnabled(true);
-}
-
-function sleep(delay)
-{
- return new Promise((resolve) => { setTimeout(resolve, delay); });
-}
-
-async function runTest() {
- for (const scrollable of document.querySelectorAll('.overflowscroll')) {
- scrollable.addEventListener('scroll', function(e) {
- logScroll(e.target);
- });
- }
-
- {
- let i = 0;
- for (const scrollcontent of document.querySelectorAll('.scrollcontent'))
- scrollcontent.innerText = "Scrollable " + ++i;
- }
- {
- let i = 0;
- for (const overlapping of document.querySelectorAll('.overlapping'))
- overlapping.insertBefore(document.createTextNode("Overlapping " + ++i), overlapping.firstChild);
- }
-
-
- if (!window.testRunner || !testRunner.runUIScript)
- return;
-
- for (const testcase of document.querySelectorAll('.case'))
- testcase.style.display = 'none';
-
- {
- let i = 0;
- for (const testcase of document.querySelectorAll('.case')) {
- ++i;
- testcase.style.display = 'inline-block';
-
- const target = testcase.querySelector('.target');
- const rect = target.getBoundingClientRect();
- const centerX = (rect.left + rect.right) / 2;
- const centerY = (rect.top + rect.bottom) / 2;
- await touchAndDragFromPointToPoint(centerX, centerY, centerX, centerY - 30);
- await liftUpAtPoint(centerX, centerY - 30);
- await sleep(500);
-
- testcase.style.display = 'none';
- outputCase(i);
- }
- }
-
- for (const testcase of document.querySelectorAll('.case'))
- testcase.style.display = 'none';
-
- testRunner.notifyDone();
-}
-
-const scrolledElements = new Set();
-
-function logScroll(element) {
- if (scrolledElements.has(element))
- return;
- scrolledElements.add(element);
-}
-
-function outputCase(i) {
- log.innerText += "case " + i + ": ";
- for (const scrolled of scrolledElements)
- log.innerText += scrolled.getElementsByClassName("scrollcontent")[0].innerText + " ";
- log.innerText += "\n";
- scrolledElements.clear();
-}
-</script>
+<script src=""
</head>
<body _onload_="runTest()">
<p>
@@ -137,8 +67,7 @@
<div class="overflowscroll target">
<div class="scrollcontent"></div>
</div>
- <div class="overlapping" style="left: 80px">
- <div class="overlapping" style="left: -40px; top: -30px"></div>
+ <div class="overlapping" style="visibility:hidden">
</div>
</div>
@@ -146,7 +75,7 @@
<div class="overflowscroll target">
<div class="scrollcontent"></div>
</div>
- <div class="overlapping" style="box-shadow: 0px 0px 32px 32px blue; left: 60px; top: 60px">
+ <div class="overlapping-empty" style="background-color:transparent">
</div>
</div>
@@ -154,7 +83,7 @@
<div class="overflowscroll target">
<div class="scrollcontent"></div>
</div>
- <div class="overlapping" style="pointer-events:none">
+ <div class="overlapping" style="box-shadow: 0px 0px 32px 32px blue; left: 60px; top: 60px">
</div>
</div>
@@ -162,8 +91,7 @@
<div class="overflowscroll target">
<div class="scrollcontent"></div>
</div>
- <div class="overlapping" style="top:-60px">
- Text text text text text text text text text text text text text text text text text text text text text text
+ <div class="overlapping" style="pointer-events:none">
</div>
</div>
@@ -171,15 +99,6 @@
<div class="overflowscroll target">
<div class="scrollcontent"></div>
</div>
- <div class="overlapping" style="top:-60px; padding-left:40px">
- Text text text text text text text text text text text text text text text text text text text text text text
- </div>
-</div>
-
-<div class="case">
- <div class="overflowscroll target">
- <div class="scrollcontent"></div>
- </div>
<div class="overlapping" style="top:40px; left:40px; border-radius:50px; line-height:100px">
</div>
</div>
Added: trunk/LayoutTests/fast/scrolling/ios/overflow-scroll-overlap-3-expected.txt (0 => 243134)
--- trunk/LayoutTests/fast/scrolling/ios/overflow-scroll-overlap-3-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/scrolling/ios/overflow-scroll-overlap-3-expected.txt 2019-03-19 11:07:42 UTC (rev 243134)
@@ -0,0 +1,5 @@
+Test that scrollable areas with text overlap are correctly targeted.
+
+case 1: Scrollable 1
+case 2: Scrollable 2
+
Added: trunk/LayoutTests/fast/scrolling/ios/overflow-scroll-overlap-3.html (0 => 243134)
--- trunk/LayoutTests/fast/scrolling/ios/overflow-scroll-overlap-3.html (rev 0)
+++ trunk/LayoutTests/fast/scrolling/ios/overflow-scroll-overlap-3.html 2019-03-19 11:07:42 UTC (rev 243134)
@@ -0,0 +1,80 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<style>
+body {
+ touch-action: none;
+}
+.case {
+ width: 200px;
+ height: 200px;
+ display: inline-block;
+ position: relative;
+}
+.scrollcontent {
+ width: 500px;
+ height: 500px;
+ background: green;
+}
+
+.overflowscroll {
+ overflow: scroll;
+ height: 100px;
+ width: 100px;
+ position: absolute;
+ border: 2px solid black;
+}
+.overlapping {
+ position:absolute;
+ left: 25px;
+ top: 25px;
+ width: 100px;
+ height: 100px;
+ background: red;
+}
+.clip {
+ position:absolute;
+ width: 100px;
+ height: 100px;
+ overflow:hidden;
+}
+.large {
+ width: 3000px;
+ height: 150px;
+}
+#log {
+ position:relative;
+ white-space: pre;
+}
+</style>
+<script src=""
+<script src=""
+</head>
+<body _onload_="runTest()">
+<p>
+Test that scrollable areas with text overlap are correctly targeted.
+</p>
+
+<div class="case">
+ <div class="overflowscroll target">
+ <div class="scrollcontent"></div>
+ </div>
+ <div class="overlapping" style="top:-60px">
+ Text text text text text text text text text text text text text text text text text text text text text text
+ </div>
+</div>
+
+<div class="case">
+ <div class="overflowscroll target">
+ <div class="scrollcontent"></div>
+ </div>
+ <div class="overlapping" style="top:-60px; padding-left:40px">
+ Text text text text text text text text text text text text text text text text text text text text text text
+ </div>
+</div>
+
+<div id=log></div>
+
+</body>
+</html>
Added: trunk/LayoutTests/fast/scrolling/ios/overflow-scroll-overlap-4-expected.txt (0 => 243134)
--- trunk/LayoutTests/fast/scrolling/ios/overflow-scroll-overlap-4-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/scrolling/ios/overflow-scroll-overlap-4-expected.txt 2019-03-19 11:07:42 UTC (rev 243134)
@@ -0,0 +1,9 @@
+Test that scrollable areas with overflowing overlap are correctly targeted.
+
+case 1:
+case 2:
+case 3:
+case 4:
+case 5:
+case 6: Scrollable 6
+
Added: trunk/LayoutTests/fast/scrolling/ios/overflow-scroll-overlap-4.html (0 => 243134)
--- trunk/LayoutTests/fast/scrolling/ios/overflow-scroll-overlap-4.html (rev 0)
+++ trunk/LayoutTests/fast/scrolling/ios/overflow-scroll-overlap-4.html 2019-03-19 11:07:42 UTC (rev 243134)
@@ -0,0 +1,116 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<style>
+body {
+ touch-action: none;
+}
+.case {
+ width: 200px;
+ height: 200px;
+ display: inline-block;
+ position: relative;
+}
+.scrollcontent {
+ width: 500px;
+ height: 500px;
+ background: green;
+}
+
+.overflowscroll {
+ overflow: scroll;
+ height: 100px;
+ width: 100px;
+ position: absolute;
+ border: 2px solid black;
+}
+.overlapping {
+ position:absolute;
+ left: 25px;
+ top: 25px;
+ width: 100px;
+ height: 100px;
+ background: red;
+}
+.clip {
+ position:absolute;
+ width: 100px;
+ height: 100px;
+ overflow:hidden;
+}
+.large {
+ width: 3000px;
+ height: 150px;
+}
+#log {
+ position:relative;
+ white-space: pre;
+}
+</style>
+<script src=""
+<script src=""
+</head>
+<body _onload_="runTest()">
+<p>
+Test that scrollable areas with overflowing overlap are correctly targeted.
+</p>
+
+<div class="case">
+ <div class="overflowscroll target">
+ <div class="scrollcontent"></div>
+ </div>
+ <div class="overlapping" style="left: 80px">
+ <div class="overlapping" style="left: -40px; top: -30px"></div>
+ </div>
+</div>
+
+<div class="case">
+ <div class="overflowscroll target">
+ <div class="scrollcontent"></div>
+ </div>
+ <div class="overlapping" style="left: 80px; z-index:0">
+ <div class="overlapping" style="left: -40px; top: -30px"></div>
+ </div>
+</div>
+
+<div class="case">
+ <div class="overflowscroll target">
+ <div class="scrollcontent"></div>
+ </div>
+ <div class="overlapping" style="left: 80px; top: 90px; z-index:0">
+ <div class="overlapping" style="left: -40px; top: -120px"></div>
+ </div>
+</div>
+
+<div class="case">
+ <div class="overflowscroll target">
+ <div class="scrollcontent"></div>
+ </div>
+ <div class="overlapping" style="left: 80px; top: 90px; z-index:0">
+ <div class="overlapping" style="left: -40px; top: -120px; z-index:-1"></div>
+ </div>
+</div>
+
+<div class="case">
+ <div class="overflowscroll target">
+ <div class="scrollcontent"></div>
+ </div>
+ <div class="overlapping" style="left: 80px; top: 90px; z-index:0">
+ <div class="overlapping" style="left: -40px; top: -120px; z-index:1"></div>
+ </div>
+</div>
+
+<div class="case">
+ <div class="overflowscroll target">
+ <div class="scrollcontent"></div>
+ </div>
+ <div class="overlapping" style="left: 80px; top: 60px; z-index:0">
+ <div class="overlapping" style="left: -40px; top: -120px"></div>
+ </div>
+</div>
+
+<div id=log></div>
+
+</body>
+</html>
Modified: trunk/LayoutTests/fast/scrolling/ios/overflow-scroll-overlap.html (243133 => 243134)
--- trunk/LayoutTests/fast/scrolling/ios/overflow-scroll-overlap.html 2019-03-19 08:31:05 UTC (rev 243133)
+++ trunk/LayoutTests/fast/scrolling/ios/overflow-scroll-overlap.html 2019-03-19 11:07:42 UTC (rev 243134)
@@ -49,85 +49,7 @@
}
</style>
<script src=""
-<script type="text/_javascript_">
-if (window.testRunner) {
- testRunner.dumpAsText();
- testRunner.waitUntilDone();
- internals.settings.setAsyncFrameScrollingEnabled(true);
- internals.settings.setAsyncOverflowScrollingEnabled(true);
-}
-
-function sleep(delay)
-{
- return new Promise((resolve) => { setTimeout(resolve, delay); });
-}
-
-async function runTest() {
- for (const scrollable of document.querySelectorAll('.overflowscroll')) {
- scrollable.addEventListener('scroll', function(e) {
- logScroll(e.target);
- });
- }
-
- {
- let i = 0;
- for (const scrollcontent of document.querySelectorAll('.scrollcontent'))
- scrollcontent.innerText = "Scrollable " + ++i;
- }
- {
- let i = 0;
- for (const overlapping of document.querySelectorAll('.overlapping'))
- overlapping.innerText = "Overlapping " + ++i;
- }
-
-
- if (!window.testRunner || !testRunner.runUIScript)
- return;
-
- for (const testcase of document.querySelectorAll('.case'))
- testcase.style.display = 'none';
-
- {
- let i = 0;
- for (const testcase of document.querySelectorAll('.case')) {
- ++i;
- testcase.style.display = 'inline-block';
-
- const target = testcase.querySelector('.target');
- const rect = target.getBoundingClientRect();
- const centerX = (rect.left + rect.right) / 2;
- const centerY = (rect.top + rect.bottom) / 2;
- await touchAndDragFromPointToPoint(centerX, centerY, centerX, centerY - 30);
- await liftUpAtPoint(centerX, centerY - 30);
- await sleep(500);
-
- testcase.style.display = 'none';
- outputCase(i);
- }
- }
-
- for (const testcase of document.querySelectorAll('.case'))
- testcase.style.display = 'none';
-
- testRunner.notifyDone();
-}
-
-const scrolledElements = new Set();
-
-function logScroll(element) {
- if (scrolledElements.has(element))
- return;
- scrolledElements.add(element);
-}
-
-function outputCase(i) {
- log.innerText += "case " + i + ": ";
- for (const scrolled of scrolledElements)
- log.innerText += scrolled.getElementsByClassName("scrollcontent")[0].innerText + " ";
- log.innerText += "\n";
- scrolledElements.clear();
-}
-</script>
+<script src=""
</head>
<body _onload_="runTest()">
<p>
Added: trunk/LayoutTests/fast/scrolling/resources/overflow-scroll-overlap.js (0 => 243134)
--- trunk/LayoutTests/fast/scrolling/resources/overflow-scroll-overlap.js (rev 0)
+++ trunk/LayoutTests/fast/scrolling/resources/overflow-scroll-overlap.js 2019-03-19 11:07:42 UTC (rev 243134)
@@ -0,0 +1,78 @@
+
+if (window.testRunner) {
+ testRunner.dumpAsText();
+ testRunner.waitUntilDone();
+ internals.settings.setAsyncFrameScrollingEnabled(true);
+ internals.settings.setAsyncOverflowScrollingEnabled(true);
+}
+
+function sleep(delay)
+{
+ return new Promise((resolve) => { setTimeout(resolve, delay); });
+}
+
+async function runTest() {
+ for (const scrollable of document.querySelectorAll('.overflowscroll')) {
+ scrollable.addEventListener('scroll', function(e) {
+ logScroll(e.target);
+ });
+ }
+
+ {
+ let i = 0;
+ for (const scrollcontent of document.querySelectorAll('.scrollcontent'))
+ scrollcontent.innerText = "Scrollable " + ++i;
+ }
+ {
+ let i = 0;
+ for (const overlapping of document.querySelectorAll('.overlapping'))
+ overlapping.insertBefore(document.createTextNode("Overlapping " + ++i), overlapping.firstChild);
+ }
+
+
+ if (!window.testRunner || !testRunner.runUIScript)
+ return;
+
+ for (const testcase of document.querySelectorAll('.case'))
+ testcase.style.display = 'none';
+
+ {
+ let i = 0;
+ for (const testcase of document.querySelectorAll('.case')) {
+ ++i;
+ testcase.style.display = 'inline-block';
+
+ const target = testcase.querySelector('.target');
+ const rect = target.getBoundingClientRect();
+ const centerX = (rect.left + rect.right) / 2;
+ const centerY = (rect.top + rect.bottom) / 2;
+ await touchAndDragFromPointToPoint(centerX, centerY, centerX, centerY - 30);
+ await liftUpAtPoint(centerX, centerY - 30);
+ await sleep(500);
+
+ testcase.style.display = 'none';
+ outputCase(i);
+ }
+ }
+
+ for (const testcase of document.querySelectorAll('.case'))
+ testcase.style.display = 'none';
+
+ testRunner.notifyDone();
+}
+
+const scrolledElements = new Set();
+
+function logScroll(element) {
+ if (scrolledElements.has(element))
+ return;
+ scrolledElements.add(element);
+}
+
+function outputCase(i) {
+ log.innerText += "case " + i + ": ";
+ for (const scrolled of scrolledElements)
+ log.innerText += scrolled.getElementsByClassName("scrollcontent")[0].innerText + " ";
+ log.innerText += "\n";
+ scrolledElements.clear();
+}
Modified: trunk/Source/WebCore/ChangeLog (243133 => 243134)
--- trunk/Source/WebCore/ChangeLog 2019-03-19 08:31:05 UTC (rev 243133)
+++ trunk/Source/WebCore/ChangeLog 2019-03-19 11:07:42 UTC (rev 243134)
@@ -1,3 +1,48 @@
+2019-03-19 Antti Koivisto <[email protected]>
+
+ Layer with no backing store should still hit-test over a scroller
+ https://bugs.webkit.org/show_bug.cgi?id=195378
+ <rdar://problem/48652078>
+
+ Reviewed by Simon Fraser.
+
+ Tests: fast/scrolling/ios/overflow-scroll-overlap-3.html
+ fast/scrolling/ios/overflow-scroll-overlap-4.html
+
+ Move collecting event region from paint to compositing update time.
+ This solves a number of problems including regions for non-painting layers.
+
+ * platform/graphics/GraphicsLayer.h:
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::paintObject):
+
+ Use the existing visibleToHitTesting() helper.
+
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::paintLayerContents):
+
+ Use flag for event region collecting, don't paint content.
+
+ (WebCore::RenderLayer::paintList):
+
+ We can bail out immediately if there is no overflow.
+
+ (WebCore::RenderLayer::paintForegroundForFragments):
+ (WebCore::RenderLayer::paintForegroundForFragmentsWithPhase):
+ (WebCore::RenderLayer::collectEventRegionForFragments):
+
+ Move to a separate function.
+
+ * rendering/RenderLayer.h:
+ * rendering/RenderLayerBacking.cpp:
+ (WebCore::RenderLayerBacking::updateConfiguration):
+
+ Update event region on backing configuration update. This is called after anything interesting changes on a sublayer.
+
+ (WebCore::RenderLayerBacking::updateEventRegion):
+ (WebCore::RenderLayerBacking::paintIntoLayer):
+ * rendering/RenderLayerBacking.h:
+
2019-03-18 Alex Christensen <[email protected]>
Make WTFLogChannelState and WTFLogLevel enum classes
Modified: trunk/Source/WebCore/platform/graphics/GraphicsLayer.h (243133 => 243134)
--- trunk/Source/WebCore/platform/graphics/GraphicsLayer.h 2019-03-19 08:31:05 UTC (rev 243133)
+++ trunk/Source/WebCore/platform/graphics/GraphicsLayer.h 2019-03-19 11:07:42 UTC (rev 243134)
@@ -453,7 +453,6 @@
WindRule shapeLayerWindRule() const;
virtual void setShapeLayerWindRule(WindRule);
- // Non-null if the event sensitive region of the layer differs from the layer bounds.
const Region& eventRegion() const { return m_eventRegion; }
virtual void setEventRegion(Region&&);
Modified: trunk/Source/WebCore/rendering/RenderBlock.cpp (243133 => 243134)
--- trunk/Source/WebCore/rendering/RenderBlock.cpp 2019-03-19 08:31:05 UTC (rev 243133)
+++ trunk/Source/WebCore/rendering/RenderBlock.cpp 2019-03-19 11:07:42 UTC (rev 243134)
@@ -1243,7 +1243,7 @@
if (paintPhase == PaintPhase::EventRegion) {
// FIXME: Handle inlines, lineboxes, SVG too.
// FIXME: Transforms?
- if (style().pointerEvents() != PointerEvents::None)
+ if (visibleToHitTesting())
paintInfo.eventRegion->unite(enclosingIntRect(LayoutRect(paintOffset, size())));
// No need to check descendants if we don't have overflow.
Modified: trunk/Source/WebCore/rendering/RenderLayer.cpp (243133 => 243134)
--- trunk/Source/WebCore/rendering/RenderLayer.cpp 2019-03-19 08:31:05 UTC (rev 243133)
+++ trunk/Source/WebCore/rendering/RenderLayer.cpp 2019-03-19 11:07:42 UTC (rev 243134)
@@ -4243,6 +4243,7 @@
bool isPaintingCompositedForeground = paintFlags.contains(PaintLayerPaintingCompositingForegroundPhase);
bool isPaintingCompositedBackground = paintFlags.contains(PaintLayerPaintingCompositingBackgroundPhase);
bool isPaintingOverflowContents = paintFlags.contains(PaintLayerPaintingOverflowContents);
+ bool isCollectingEventRegion = paintFlags.contains(PaintLayerCollectingEventRegion);
// Outline always needs to be painted even if we have no visible content. Also,
// the outline is painted in the background phase during composited scrolling.
// If it were painted in the foreground phase, it would move with the scrolled
@@ -4249,10 +4250,10 @@
// content. When not composited scrolling, the outline is painted in the
// foreground phase. Since scrolled contents are moved by repainting in this
// case, the outline won't get 'dragged along'.
- bool shouldPaintOutline = isSelfPaintingLayer && !isPaintingOverlayScrollbars
+ bool shouldPaintOutline = isSelfPaintingLayer && !isPaintingOverlayScrollbars && !isCollectingEventRegion
&& ((isPaintingScrollingContent && isPaintingCompositedBackground)
|| (!isPaintingScrollingContent && isPaintingCompositedForeground));
- bool shouldPaintContent = m_hasVisibleContent && isSelfPaintingLayer && !isPaintingOverlayScrollbars;
+ bool shouldPaintContent = m_hasVisibleContent && isSelfPaintingLayer && !isPaintingOverlayScrollbars && !isCollectingEventRegion;
if (localPaintFlags & PaintLayerPaintingRootBackgroundOnly && !renderer().isRenderView() && !renderer().isDocumentElementRenderer())
return;
@@ -4323,7 +4324,7 @@
paintBehavior.add(PaintBehavior::ExcludeSelection);
LayoutRect paintDirtyRect = localPaintingInfo.paintDirtyRect;
- if (shouldPaintContent || shouldPaintOutline || isPaintingOverlayScrollbars) {
+ if (shouldPaintContent || shouldPaintOutline || isPaintingOverlayScrollbars || isCollectingEventRegion) {
// Collect the fragments. This will compute the clip rectangles and paint offsets for each layer fragment, as well as whether or not the content of each
// fragment should paint. If the parent's filter dictates full repaint to ensure proper filter effect,
// use the overflow clip as dirty rect, instead of no clipping. It maintains proper clipping for overflow::scroll.
@@ -4357,6 +4358,9 @@
}
}
+ if (isCollectingEventRegion)
+ collectEventRegionForFragments(layerFragments, currentContext, localPaintingInfo);
+
if (shouldPaintOutline)
paintOutlineForFragments(layerFragments, currentContext, localPaintingInfo, paintBehavior, subtreePaintRootForRenderer);
@@ -4464,6 +4468,9 @@
if (!hasSelfPaintingLayerDescendant())
return;
+ if (paintFlags.contains(PaintLayerCollectingEventRegion) && renderBox() && !renderBox()->hasRenderOverflow())
+ return;
+
#if !ASSERT_DISABLED
LayerListMutationDetector mutationChecker(*this);
#endif
@@ -4746,8 +4753,6 @@
paintForegroundForFragmentsWithPhase(PaintPhase::Float, layerFragments, context, localPaintingInfo, localPaintBehavior, subtreePaintRootForRenderer);
paintForegroundForFragmentsWithPhase(PaintPhase::Foreground, layerFragments, context, localPaintingInfo, localPaintBehavior, subtreePaintRootForRenderer);
paintForegroundForFragmentsWithPhase(PaintPhase::ChildOutlines, layerFragments, context, localPaintingInfo, localPaintBehavior, subtreePaintRootForRenderer);
- if (localPaintingInfo.eventRegion)
- paintForegroundForFragmentsWithPhase(PaintPhase::EventRegion, layerFragments, context, localPaintingInfo, localPaintBehavior, subtreePaintRootForRenderer);
}
if (shouldClip)
@@ -4769,8 +4774,6 @@
PaintInfo paintInfo(context, fragment.foregroundRect.rect(), phase, paintBehavior, subtreePaintRootForRenderer, nullptr, nullptr, &localPaintingInfo.rootLayer->renderer(), this, localPaintingInfo.requireSecurityOriginAccessForWidgets);
if (phase == PaintPhase::Foreground)
paintInfo.overlapTestRequests = localPaintingInfo.overlapTestRequests;
- if (phase == PaintPhase::EventRegion)
- paintInfo.eventRegion = localPaintingInfo.eventRegion;
renderer().paint(paintInfo, toLayoutPoint(fragment.layerBounds.location() - renderBoxLocation() + localPaintingInfo.subpixelOffset));
if (shouldClip)
@@ -4843,6 +4846,17 @@
}
}
+void RenderLayer::collectEventRegionForFragments(const LayerFragments& layerFragments, GraphicsContext& context, const LayerPaintingInfo& localPaintingInfo)
+{
+ ASSERT(localPaintingInfo.eventRegion);
+
+ for (const auto& fragment : layerFragments) {
+ PaintInfo paintInfo(context, fragment.foregroundRect.rect(), PaintPhase::EventRegion, { });
+ paintInfo.eventRegion = localPaintingInfo.eventRegion;
+ renderer().paint(paintInfo, toLayoutPoint(fragment.layerBounds.location() - renderBoxLocation() + localPaintingInfo.subpixelOffset));
+ }
+}
+
bool RenderLayer::hitTest(const HitTestRequest& request, HitTestResult& result)
{
return hitTest(request, result.hitTestLocation(), result);
Modified: trunk/Source/WebCore/rendering/RenderLayer.h (243133 => 243134)
--- trunk/Source/WebCore/rendering/RenderLayer.h 2019-03-19 08:31:05 UTC (rev 243133)
+++ trunk/Source/WebCore/rendering/RenderLayer.h 2019-03-19 11:07:42 UTC (rev 243134)
@@ -641,8 +641,9 @@
PaintLayerPaintingRootBackgroundOnly = 1 << 11,
PaintLayerPaintingSkipRootBackground = 1 << 12,
PaintLayerPaintingChildClippingMaskPhase = 1 << 13,
+ PaintLayerCollectingEventRegion = 1 << 14,
};
- static constexpr OptionSet<PaintLayerFlag> paintLayerPaintingCompositingAllPhasesFlags() { return { PaintLayerPaintingCompositingBackgroundPhase, PaintLayerPaintingCompositingForegroundPhase }; }
+ static constexpr OptionSet<PaintLayerFlag> paintLayerPaintingCompositingAllPhasesFlags() { return { PaintLayerPaintingCompositingBackgroundPhase, PaintLayerPaintingCompositingForegroundPhase }; }
enum class SecurityOriginPaintPolicy { AnyOrigin, AccessibleOriginOnly };
@@ -984,6 +985,7 @@
void paintMaskForFragments(const LayerFragments&, GraphicsContext&, const LayerPaintingInfo&, OptionSet<PaintBehavior>, RenderObject* paintingRootForRenderer);
void paintChildClippingMaskForFragments(const LayerFragments&, GraphicsContext&, const LayerPaintingInfo&, OptionSet<PaintBehavior>, RenderObject* paintingRootForRenderer);
void paintTransformedLayerIntoFragments(GraphicsContext&, const LayerPaintingInfo&, OptionSet<PaintLayerFlag>);
+ void collectEventRegionForFragments(const LayerFragments&, GraphicsContext&, const LayerPaintingInfo&);
RenderLayer* transparentPaintingAncestor();
void beginTransparencyLayers(GraphicsContext&, const LayerPaintingInfo&, const LayoutRect& dirtyRect);
Modified: trunk/Source/WebCore/rendering/RenderLayerBacking.cpp (243133 => 243134)
--- trunk/Source/WebCore/rendering/RenderLayerBacking.cpp 2019-03-19 08:31:05 UTC (rev 243133)
+++ trunk/Source/WebCore/rendering/RenderLayerBacking.cpp 2019-03-19 11:07:42 UTC (rev 243134)
@@ -765,6 +765,8 @@
if (!m_owningLayer.isRenderViewLayer()) {
bool didUpdateContentsRect = false;
updateDirectlyCompositedBoxDecorations(contentsInfo, didUpdateContentsRect);
+
+ updateEventRegion();
} else
updateRootLayerConfiguration();
@@ -1431,6 +1433,27 @@
m_backgroundLayer->setDrawsContent(m_backgroundLayerPaintsFixedRootBackground ? hasPaintedContent : contentsInfo.paintsBoxDecorations());
}
+void RenderLayerBacking::updateEventRegion()
+{
+#if PLATFORM(IOS_FAMILY)
+ if (paintsIntoCompositedAncestor())
+ return;
+
+ GraphicsContext nullContext(nullptr);
+ RenderLayer::LayerPaintingInfo paintingInfo(&m_owningLayer, compositedBounds(), { }, LayoutSize());
+
+ Region eventRegion;
+ paintingInfo.eventRegion = &eventRegion;
+
+ auto paintFlags = RenderLayer::paintLayerPaintingCompositingAllPhasesFlags() | RenderLayer::PaintLayerCollectingEventRegion;
+ m_owningLayer.paintLayerContents(nullContext, paintingInfo, paintFlags);
+
+ eventRegion.translate(roundedIntSize(contentOffsetInCompositingLayer()));
+
+ m_graphicsLayer->setEventRegion(WTFMove(eventRegion));
+#endif
+}
+
// Return true if the layer changed.
bool RenderLayerBacking::updateAncestorClippingLayer(bool needsAncestorClip)
{
@@ -2586,19 +2609,8 @@
RenderLayer::LayerPaintingInfo paintingInfo(&m_owningLayer, paintDirtyRect, paintBehavior, -m_subpixelOffsetFromRenderer);
-#if PLATFORM(IOS_FAMILY)
- Region eventRegion;
- paintingInfo.eventRegion = &eventRegion;
-#endif
-
m_owningLayer.paintLayerContents(context, paintingInfo, paintFlags);
-#if PLATFORM(IOS_FAMILY)
- paintingInfo.eventRegion = nullptr;
- eventRegion.translate(roundedIntSize(contentOffsetInCompositingLayer()));
- m_graphicsLayer->setEventRegion(WTFMove(eventRegion));
-#endif
-
if (m_owningLayer.containsDirtyOverlayScrollbars())
m_owningLayer.paintLayerContents(context, paintingInfo, paintFlags | RenderLayer::PaintLayerPaintingOverlayScrollbars);
Modified: trunk/Source/WebCore/rendering/RenderLayerBacking.h (243133 => 243134)
--- trunk/Source/WebCore/rendering/RenderLayerBacking.h 2019-03-19 08:31:05 UTC (rev 243133)
+++ trunk/Source/WebCore/rendering/RenderLayerBacking.h 2019-03-19 11:07:42 UTC (rev 243134)
@@ -352,6 +352,7 @@
bool paintsContent(RenderLayer::PaintedContentRequest&) const;
void updateDrawsContent(PaintedContentsInfo&);
+ void updateEventRegion();
// Returns true if this compositing layer has no visible content.
bool isSimpleContainerCompositingLayer(PaintedContentsInfo&) const;
Modified: trunk/Source/WebKit/ChangeLog (243133 => 243134)
--- trunk/Source/WebKit/ChangeLog 2019-03-19 08:31:05 UTC (rev 243133)
+++ trunk/Source/WebKit/ChangeLog 2019-03-19 11:07:42 UTC (rev 243134)
@@ -1,3 +1,19 @@
+2019-03-19 Antti Koivisto <[email protected]>
+
+ Layer with no backing store should still hit-test over a scroller
+ https://bugs.webkit.org/show_bug.cgi?id=195378
+ <rdar://problem/48652078>
+
+ Reviewed by Simon Fraser.
+
+ * UIProcess/RemoteLayerTree/ios/RemoteLayerTreeHostIOS.mm:
+ (WebKit::RemoteLayerTreeHost::makeNode):
+ * UIProcess/RemoteLayerTree/ios/RemoteLayerTreeViews.h:
+ * UIProcess/RemoteLayerTree/ios/RemoteLayerTreeViews.mm:
+ (WebKit::collectDescendantViewsAtPoint):
+
+ No need for special WKTiledBackingView, tiled views now have correct event regions.
+
2019-03-18 Alex Christensen <[email protected]>
Make WTFLogChannelState and WTFLogLevel enum classes
Modified: trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/RemoteLayerTreeHostIOS.mm (243133 => 243134)
--- trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/RemoteLayerTreeHostIOS.mm 2019-03-19 08:31:05 UTC (rev 243133)
+++ trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/RemoteLayerTreeHostIOS.mm 2019-03-19 11:07:42 UTC (rev 243134)
@@ -72,11 +72,9 @@
case PlatformCALayer::LayerTypeWebLayer:
case PlatformCALayer::LayerTypeRootLayer:
case PlatformCALayer::LayerTypeSimpleLayer:
- return makeAdoptingView([[WKCompositingView alloc] init]);
-
case PlatformCALayer::LayerTypeTiledBackingLayer:
case PlatformCALayer::LayerTypePageTiledBackingLayer:
- return makeAdoptingView([[WKTiledBackingView alloc] init]);
+ return makeAdoptingView([[WKCompositingView alloc] init]);
case PlatformCALayer::LayerTypeTiledBackingTileLayer:
return RemoteLayerTreeNode::createWithPlainLayer(properties.layerID);
Modified: trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/RemoteLayerTreeViews.h (243133 => 243134)
--- trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/RemoteLayerTreeViews.h 2019-03-19 08:31:05 UTC (rev 243133)
+++ trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/RemoteLayerTreeViews.h 2019-03-19 11:07:42 UTC (rev 243134)
@@ -40,9 +40,6 @@
@interface WKCompositingView : UIView
@end
-@interface WKTiledBackingView : WKCompositingView
-@end
-
@interface WKTransformView : WKCompositingView
@end
Modified: trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/RemoteLayerTreeViews.mm (243133 => 243134)
--- trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/RemoteLayerTreeViews.mm 2019-03-19 08:31:05 UTC (rev 243133)
+++ trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/RemoteLayerTreeViews.mm 2019-03-19 11:07:42 UTC (rev 243134)
@@ -49,8 +49,6 @@
auto handlesEvent = [&] {
if (![view pointInside:subviewPoint withEvent:event])
return false;
- if ([view isKindOfClass:[WKTiledBackingView class]])
- return true;
if (![view isKindOfClass:[WKCompositingView class]])
return true;
auto* node = RemoteLayerTreeNode::forCALayer(view.layer);
@@ -115,9 +113,6 @@
@end
-@implementation WKTiledBackingView
-@end
-
@implementation WKTransformView
+ (Class)layerClass