Diff
Modified: trunk/LayoutTests/ChangeLog (248603 => 248604)
--- trunk/LayoutTests/ChangeLog 2019-08-13 18:54:32 UTC (rev 248603)
+++ trunk/LayoutTests/ChangeLog 2019-08-13 19:26:22 UTC (rev 248604)
@@ -1,3 +1,14 @@
+2019-08-13 Antti Koivisto <an...@apple.com>
+
+ Event regions collection should take clipping into account
+ https://bugs.webkit.org/show_bug.cgi?id=200668
+ <rdar://problem/53826561>
+
+ Reviewed by Simon Fraser.
+
+ * pointerevents/ios/touch-action-region-clip-and-transform-expected.txt: Added.
+ * pointerevents/ios/touch-action-region-clip-and-transform.html: Added.
+
2019-08-13 Devin Rousso <drou...@apple.com>
Web Inspector: Styles: show @supports CSS groupings
Added: trunk/LayoutTests/pointerevents/ios/touch-action-region-clip-and-transform-expected.txt (0 => 248604)
--- trunk/LayoutTests/pointerevents/ios/touch-action-region-clip-and-transform-expected.txt (rev 0)
+++ trunk/LayoutTests/pointerevents/ios/touch-action-region-clip-and-transform-expected.txt 2019-08-13 19:26:22 UTC (rev 248604)
@@ -0,0 +1,101 @@
+(GraphicsLayer
+ (anchor 0.00 0.00)
+ (bounds 800.00 2408.00)
+ (children 1
+ (GraphicsLayer
+ (bounds 800.00 2408.00)
+ (contentsOpaque 1)
+ (event region
+ (rect (0,0) width=800 height=2408)
+ )
+ (children 6
+ (GraphicsLayer
+ (position 8.00 8.00)
+ (bounds 350.00 350.00)
+ (drawsContent 1)
+ (event region
+ (rect (0,0) width=200 height=200)
+ (touch-action
+ (none
+ (rect (150,150) width=50 height=50)
+ )
+ )
+ )
+ )
+ (GraphicsLayer
+ (position 8.00 408.00)
+ (bounds 350.00 350.00)
+ (drawsContent 1)
+ (event region
+ (rect (0,0) width=200 height=200)
+ (touch-action
+ (none
+ (rect (150,150) width=50 height=50)
+ )
+ )
+ )
+ )
+ (GraphicsLayer
+ (position 8.00 808.00)
+ (bounds 350.00 350.00)
+ (drawsContent 1)
+ (event region
+ (rect (0,0) width=200 height=200)
+ (touch-action
+ (none
+ (rect (150,150) width=50 height=50)
+ )
+ )
+ )
+ )
+ (GraphicsLayer
+ (position 8.00 1208.00)
+ (bounds 350.00 350.00)
+ (drawsContent 1)
+ (event region
+ (rect (0,0) width=200 height=150)
+ (rect (0,150) width=350 height=50)
+ (rect (150,200) width=200 height=150)
+ (touch-action
+ (none
+ (rect (150,150) width=50 height=50)
+ )
+ )
+ )
+ )
+ (GraphicsLayer
+ (position 8.00 1608.00)
+ (bounds 350.00 350.00)
+ (drawsContent 1)
+ (event region
+ (rect (0,0) width=200 height=150)
+ (rect (0,150) width=350 height=50)
+ (rect (150,200) width=200 height=150)
+ (touch-action
+ (none
+ (rect (150,150) width=50 height=50)
+ )
+ )
+ )
+ )
+ (GraphicsLayer
+ (position 8.00 2008.00)
+ (bounds 200.00 200.00)
+ (contentsOpaque 1)
+ (drawsContent 1)
+ (event region
+ (rect (0,0) width=200 height=150)
+ (rect (0,150) width=350 height=50)
+ (rect (150,200) width=200 height=150)
+ (touch-action
+ (none
+ (rect (150,150) width=50 height=50)
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+)
+
Added: trunk/LayoutTests/pointerevents/ios/touch-action-region-clip-and-transform.html (0 => 248604)
--- trunk/LayoutTests/pointerevents/ios/touch-action-region-clip-and-transform.html (rev 0)
+++ trunk/LayoutTests/pointerevents/ios/touch-action-region-clip-and-transform.html 2019-08-13 19:26:22 UTC (rev 248604)
@@ -0,0 +1,52 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ internal:AsyncOverflowScrollingEnabled=true ] -->
+<html>
+<style>
+.root { position:relative; width:200px; height:200px; will-change:transform; background:green; margin-bottom:200px; }
+.container { width:200px; height:200px; background:red; }
+.larger { width:300px; height:300px; }
+.relative { position:relative }
+.none { width:100px; height:100px; background:blue; touch-action: none; }
+.clip { overflow:hidden; }
+.transform { transform:translate(150px, 150px); }
+.negtransform { transform:translate(-50px, -50px); }
+</style>
+<body>
+<div class="root">
+ <div class="container clip">
+ <div class="none transform"></div>
+ </div>
+</div>
+<div class="root">
+ <div class="container relative clip">
+ <div class="none transform"></div>
+ </div>
+</div>
+<div class="root">
+ <div class="container relative clip">
+ <div class="none transform relative"></div>
+ </div>
+</div>
+<div class="root">
+ <div class="container clip transform">
+ <div class="none negtransform"></div>
+ </div>
+</div>
+<div class="root">
+ <div class="container relative clip transform">
+ <div class="none negtransform"></div>
+ </div>
+</div>
+<div class="root clip">
+ <div class="container relative clip transform">
+ <div class="none negtransform"></div>
+ </div>
+</div>
+<pre id="results"></pre>
+<script>
+if (window.testRunner)
+ testRunner.dumpAsText();
+if (window.internals)
+ results.innerText = internals.layerTreeAsText(document, internals.LAYER_TREE_INCLUDES_EVENT_REGION);
+</script>
+</body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (248603 => 248604)
--- trunk/Source/WebCore/ChangeLog 2019-08-13 18:54:32 UTC (rev 248603)
+++ trunk/Source/WebCore/ChangeLog 2019-08-13 19:26:22 UTC (rev 248604)
@@ -1,3 +1,37 @@
+2019-08-13 Antti Koivisto <an...@apple.com>
+
+ Event region collection should take clipping into account
+ https://bugs.webkit.org/show_bug.cgi?id=200668
+ <rdar://problem/53826561>
+
+ Reviewed by Simon Fraser.
+
+ Test: pointerevents/ios/touch-action-region-clip-and-transform.html
+
+ * rendering/EventRegion.cpp:
+ (WebCore::EventRegionContext::pushClip):
+ (WebCore::EventRegionContext::popClip):
+
+ Maintain clip rect stack.
+
+ (WebCore::EventRegionContext::unite):
+
+ Apply both transforms and clipping.
+
+ * rendering/EventRegion.h:
+ * rendering/RenderBlock.cpp:
+ * rendering/RenderBox.cpp:
+ (WebCore::RenderBox::pushContentsClip):
+ (WebCore::RenderBox::popContentsClip):
+
+ Update clip for non-self-painting layers.
+
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::clipToRect):
+ (WebCore::RenderLayer::restoreClip):
+
+ Update clip for self-painting layers.
+
2019-08-13 Devin Rousso <drou...@apple.com>
Web Inspector: Styles: show @supports CSS groupings
Modified: trunk/Source/WebCore/rendering/EventRegion.cpp (248603 => 248604)
--- trunk/Source/WebCore/rendering/EventRegion.cpp 2019-08-13 18:54:32 UTC (rev 248603)
+++ trunk/Source/WebCore/rendering/EventRegion.cpp 2019-08-13 19:26:22 UTC (rev 248604)
@@ -45,15 +45,45 @@
void EventRegionContext::popTransform()
{
+ if (m_transformStack.isEmpty()) {
+ ASSERT_NOT_REACHED();
+ return;
+ }
m_transformStack.removeLast();
}
+void EventRegionContext::pushClip(const IntRect& clipRect)
+{
+ auto transformedClip = m_transformStack.isEmpty() ? clipRect : m_transformStack.last().mapRect(clipRect);
+
+ if (m_clipStack.isEmpty())
+ m_clipStack.append(transformedClip);
+ else
+ m_clipStack.append(intersection(m_clipStack.last(), transformedClip));
+}
+
+void EventRegionContext::popClip()
+{
+ if (m_clipStack.isEmpty()) {
+ ASSERT_NOT_REACHED();
+ return;
+ }
+ m_clipStack.removeLast();
+}
+
void EventRegionContext::unite(const Region& region, const RenderStyle& style)
{
- if (m_transformStack.isEmpty())
+ if (m_transformStack.isEmpty() && m_clipStack.isEmpty()) {
m_eventRegion.unite(region, style);
- else
- m_eventRegion.unite(m_transformStack.last().mapRegion(region), style);
+ return;
+ }
+
+ auto transformedAndClippedRegion = m_transformStack.isEmpty() ? region : m_transformStack.last().mapRegion(region);
+
+ if (!m_clipStack.isEmpty())
+ transformedAndClippedRegion.intersect(m_clipStack.last());
+
+ m_eventRegion.unite(transformedAndClippedRegion, style);
}
bool EventRegionContext::contains(const IntRect& rect) const
Modified: trunk/Source/WebCore/rendering/EventRegion.h (248603 => 248604)
--- trunk/Source/WebCore/rendering/EventRegion.h 2019-08-13 18:54:32 UTC (rev 248603)
+++ trunk/Source/WebCore/rendering/EventRegion.h 2019-08-13 19:26:22 UTC (rev 248604)
@@ -43,6 +43,9 @@
void pushTransform(const AffineTransform&);
void popTransform();
+ void pushClip(const IntRect&);
+ void popClip();
+
void unite(const Region&, const RenderStyle&);
bool contains(const IntRect&) const;
@@ -49,6 +52,7 @@
private:
EventRegion& m_eventRegion;
Vector<AffineTransform> m_transformStack;
+ Vector<IntRect> m_clipStack;
};
class EventRegion {
Modified: trunk/Source/WebCore/rendering/RenderBox.cpp (248603 => 248604)
--- trunk/Source/WebCore/rendering/RenderBox.cpp 2019-08-13 18:54:32 UTC (rev 248603)
+++ trunk/Source/WebCore/rendering/RenderBox.cpp 2019-08-13 19:26:22 UTC (rev 248604)
@@ -1804,6 +1804,10 @@
if (style().hasBorderRadius())
paintInfo.context().clipRoundedRect(style().getRoundedInnerBorderFor(LayoutRect(accumulatedOffset, size())).pixelSnappedRoundedRectForPainting(deviceScaleFactor));
paintInfo.context().clip(clipRect);
+
+ if (paintInfo.phase == PaintPhase::EventRegion)
+ paintInfo.eventRegionContext->pushClip(enclosingIntRect(clipRect));
+
return true;
}
@@ -1811,6 +1815,9 @@
{
ASSERT(hasControlClip() || (hasOverflowClip() && !layer()->isSelfPaintingLayer()));
+ if (paintInfo.phase == PaintPhase::EventRegion)
+ paintInfo.eventRegionContext->popClip();
+
paintInfo.context().restore();
if (originalPhase == PaintPhase::Outline) {
paintInfo.phase = PaintPhase::SelfOutline;
Modified: trunk/Source/WebCore/rendering/RenderLayer.cpp (248603 => 248604)
--- trunk/Source/WebCore/rendering/RenderLayer.cpp 2019-08-13 18:54:32 UTC (rev 248603)
+++ trunk/Source/WebCore/rendering/RenderLayer.cpp 2019-08-13 19:26:22 UTC (rev 248604)
@@ -4010,7 +4010,11 @@
if (needsClipping) {
LayoutRect adjustedClipRect = clipRect.rect();
adjustedClipRect.move(paintingInfo.subpixelOffset);
- context.clip(snapRectToDevicePixels(adjustedClipRect, deviceScaleFactor));
+ auto snappedClipRect = snapRectToDevicePixels(adjustedClipRect, deviceScaleFactor);
+ context.clip(snappedClipRect);
+
+ if (paintingInfo.eventRegionContext)
+ paintingInfo.eventRegionContext->pushClip(enclosingIntRect(snappedClipRect));
}
if (clipRect.affectedByRadius()) {
@@ -4036,8 +4040,12 @@
void RenderLayer::restoreClip(GraphicsContext& context, const LayerPaintingInfo& paintingInfo, const ClipRect& clipRect)
{
- if ((!clipRect.isInfinite() && clipRect.rect() != paintingInfo.paintDirtyRect) || clipRect.affectedByRadius())
+ if ((!clipRect.isInfinite() && clipRect.rect() != paintingInfo.paintDirtyRect) || clipRect.affectedByRadius()) {
context.restore();
+
+ if (paintingInfo.eventRegionContext)
+ paintingInfo.eventRegionContext->popClip();
+ }
}
static void performOverlapTests(OverlapTestRequestMap& overlapTestRequests, const RenderLayer* rootLayer, const RenderLayer* layer)