Title: [259761] trunk
Revision
259761
Author
[email protected]
Date
2020-04-08 15:38:33 -0700 (Wed, 08 Apr 2020)

Log Message

Should find touch-action elements inside non-composited iframes
https://bugs.webkit.org/show_bug.cgi?id=210041
<rdar://problem/61323558>

Reviewed by Simon Fraser.

Source/WebCore:

Fix up event region code to traverse non-composited iframes that have elements with a non-auto
touch-action. The event region is computed for each composited layer during a compositing layer
update and was retricted to being updated if the layer's associated document may have an element
with a non-auto touch-action. To make this work for non-composited iframes I find its enclosing
compositing layer, set a special bit that it needs an event region update because of the non-
composited child iframe and schedule a compositing layer update. When the update happens, it
checks to see if the special bit is set and if so overrides any restrictions that would have
prevented the event region from being updated. The painting code for widgets is also fixed up to
pass through an EventRegionContext to update during EventRegion painting.

This strategy works well for updating the event region. However debug paint overlays are not
updated (i.e. RenderLayerBacking::paintDebugOverlays() is not called) until the embedding client's
view is repainted. For now, to fix this up I added another a hack, a special bit (RenderView::needsRepaintHackAfterCompositingLayerUpdateForDebugOverlaysOnly())
that is only set if debug overlays are to be shown, to have the compositor repaint the view after
updating compositing layers.

Tests: pointerevents/ios/programmatic-touch-action-none-inside-iframe.html
       pointerevents/ios/touch-action-none-inside-iframe.html
       pointerevents/ios/touch-action-none-inside-nested-iframe.html

* dom/Document.cpp:
(WebCore::Document::invalidateEventRegionsForFrame): Added. Try to invalidate the event region.
This may fail if the document does not have an enclosing compositing layer for repaint (e.g. nested
composited iframes - see test pointerevents/ios/touch-action-none-inside-nested-iframe.html). If
this happens then recursive on our owner element's document. Recursion is used instead of a loop
to future proof this code for out-of-process (OOP) frames, which will likely introduce document proxy objects.
* dom/Document.h:
* page/Frame.cpp:
(WebCore::Frame::invalidateContentEventRegionsIfNeeded): Added. Check if our document has any elements with
a non-auto touch-action. If it does then ask the compositor if the enclosing compositing layer for
repaint's event region must be invalidated - it will only reply true if this is a non-composited iframe.
If it does then forward this invalidation request to the document. The reason I delegate to the document
instead of handling the logic here is to future proof this code for OOP iframes.
* page/Frame.h:
* page/FrameView.cpp:
(WebCore::FrameView::didLayout): Call Frame::invalidateContentEventRegionsIfNeeded(). Also while
I am here take out a ref on the document to ensure it lives through the end of this function, including
through the accessibility's postNotification() code that calls out to the embedding client.

(WebCore::FrameView::paintContents):
* page/FrameView.h:
* platform/ScrollView.cpp:
(WebCore::ScrollView::paint):
* platform/ScrollView.h:
* platform/Scrollbar.cpp:
(WebCore::Scrollbar::paint):
* platform/Scrollbar.h:
* platform/Widget.cpp:
(WebCore::Widget::paint):
* platform/Widget.h:
* platform/gtk/WidgetGtk.cpp:
(WebCore::Widget::paint):
* platform/ios/WidgetIOS.mm:
(WebCore::Widget::paint):
* platform/mac/WidgetMac.mm:
(WebCore::Widget::paint):
* platform/win/WidgetWin.cpp:
(WebCore::Widget::paint):
* rendering/RenderBlock.cpp:
(WebCore::RenderBlock::paintObject):
Pass an EventRegionContext through.

* rendering/RenderElement.cpp:
(WebCore::RenderElement::styleWillChange): Update code now that RendeLayer::invalidateEventRegion()
takes a reason.
* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::paint): Pass the EventRegionContext through. If are passed one then update
paint flags to collect event region.
(WebCore::RenderLayer::invalidateEventRegion): Changed return value from void to bool so as to indicate
to the caller whether the event region was actually invalidated. Also made it take an argument as
to the reason for the invalidation. If invalidation is due to a non-composited iframe then sets some
state and schedule a compositing layer update.

* rendering/RenderLayerBacking.cpp:
(WebCore::RenderLayerBacking::updateEventRegion):
(WebCore::RenderLayerBacking::setContentsNeedDisplay):
(WebCore::RenderLayerBacking::setContentsNeedDisplayInRect):
* rendering/RenderLayerCompositor.cpp:
(WebCore::RenderLayerCompositor::updateCompositingLayers):
Pass an EventRegionContext through

(WebCore::RenderLayerCompositor::viewNeedsToInvalidateEventRegionOfEnclosingCompositingLayerForRepaint const): Added.

* rendering/RenderLayerCompositor.h:
* rendering/RenderScrollbar.cpp:
(WebCore::RenderScrollbar::paint):
* rendering/RenderScrollbar.h:
* rendering/RenderView.h:
Pass an EventRegionContext through.

* rendering/RenderWidget.cpp:
(WebCore::RenderWidget::paintContents): Translate the event region by our content paint offset.
(WebCore::RenderWidget::paint): Update for EventRegion. If painting the event region and the view
needs layout then do what we do now and bail out. Otherwise, proceed to paint the widget's content.
The changes to FrameView::didLayout() above means that for non-composited frames that need an event
region update they already performed a layout. So, these paints will be allowed to descend into
painting of the widget's content.

Source/WebKit:

Pass EventRegionContext through. It is unused as it's not applicable for plugin painting.

* WebProcess/Plugins/PluginView.cpp:
(WebKit::PluginView::paint):
* WebProcess/Plugins/PluginView.h:

Source/WebKitLegacy/win:

Pass EventRegionContext through. It is unused as it's not applicable for plugin painting.

* Plugins/PluginView.h:
* Plugins/PluginViewWin.cpp:
(WebCore::PluginView::paint):

LayoutTests:

Add more tests.

* pointerevents/ios/programmatic-touch-action-none-inside-iframe-expected.txt: Added.
* pointerevents/ios/programmatic-touch-action-none-inside-iframe.html: Added.
* pointerevents/ios/resources/touch-action-none-inside-iframe.html: Added.
* pointerevents/ios/touch-action-none-inside-iframe-expected.txt: Added.
* pointerevents/ios/touch-action-none-inside-iframe.html: Added.
* pointerevents/ios/touch-action-none-inside-nested-iframe-expected.txt: Added.
* pointerevents/ios/touch-action-none-inside-nested-iframe.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (259760 => 259761)


--- trunk/LayoutTests/ChangeLog	2020-04-08 22:15:16 UTC (rev 259760)
+++ trunk/LayoutTests/ChangeLog	2020-04-08 22:38:33 UTC (rev 259761)
@@ -1,3 +1,21 @@
+2020-04-08  Daniel Bates  <[email protected]>
+
+        Should find touch-action elements inside non-composited iframes
+        https://bugs.webkit.org/show_bug.cgi?id=210041
+        <rdar://problem/61323558>
+
+        Reviewed by Simon Fraser.
+
+        Add more tests.
+
+        * pointerevents/ios/programmatic-touch-action-none-inside-iframe-expected.txt: Added.
+        * pointerevents/ios/programmatic-touch-action-none-inside-iframe.html: Added.
+        * pointerevents/ios/resources/touch-action-none-inside-iframe.html: Added.
+        * pointerevents/ios/touch-action-none-inside-iframe-expected.txt: Added.
+        * pointerevents/ios/touch-action-none-inside-iframe.html: Added.
+        * pointerevents/ios/touch-action-none-inside-nested-iframe-expected.txt: Added.
+        * pointerevents/ios/touch-action-none-inside-nested-iframe.html: Added.
+
 2020-04-08  Chris Dumez  <[email protected]>
 
         Unreviewed, unskip http/tests/notifications/event-listener-crash.html

Added: trunk/LayoutTests/pointerevents/ios/programmatic-touch-action-none-inside-iframe-expected.txt (0 => 259761)


--- trunk/LayoutTests/pointerevents/ios/programmatic-touch-action-none-inside-iframe-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/pointerevents/ios/programmatic-touch-action-none-inside-iframe-expected.txt	2020-04-08 22:38:33 UTC (rev 259761)
@@ -0,0 +1,22 @@
+
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 800.00 600.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (contentsOpaque 1)
+      (drawsContent 1)
+      (backgroundColor #FFFFFF)
+      (event region
+        (rect (0,0) width=800 height=600)
+        (touch-action
+          (none          
+            (rect (18,18) width=102 height=102)
+          )
+        )
+      )
+    )
+  )
+)
+

Added: trunk/LayoutTests/pointerevents/ios/programmatic-touch-action-none-inside-iframe.html (0 => 259761)


--- trunk/LayoutTests/pointerevents/ios/programmatic-touch-action-none-inside-iframe.html	                        (rev 0)
+++ trunk/LayoutTests/pointerevents/ios/programmatic-touch-action-none-inside-iframe.html	2020-04-08 22:38:33 UTC (rev 259761)
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+<body>
+<iframe id="testFrame" srcdoc="<div style='width: 100px; height: 100px; border:1px solid black'></div>" _onload_="runTest()"></iframe>
+<pre id="results"></pre>
+<script>
+if (window.testRunner) {
+    testRunner.dumpAsText();
+    testRunner.waitUntilDone();
+}
+
+function runTest()
+{
+    testFrame.contentDocument.querySelector("div").style.touchAction = "none";
+    if (window.internals)
+        results.innerText = internals.layerTreeAsText(document, internals.LAYER_TREE_INCLUDES_EVENT_REGION | internals.LAYER_TREE_INCLUDES_ROOT_LAYER_PROPERTIES);
+    if (window.testRunner)
+        testRunner.notifyDone();
+}
+</script>
+</body>
+</html>

Added: trunk/LayoutTests/pointerevents/ios/resources/touch-action-none-inside-iframe.html (0 => 259761)


--- trunk/LayoutTests/pointerevents/ios/resources/touch-action-none-inside-iframe.html	                        (rev 0)
+++ trunk/LayoutTests/pointerevents/ios/resources/touch-action-none-inside-iframe.html	2020-04-08 22:38:33 UTC (rev 259761)
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<html>
+<body>
+<iframe srcdoc="<div style='touch-action: none; width: 100px; height: 100px; border:1px solid black'></div>" _onload_="window.parent && window.parent.dumpRegion()"></iframe>
+</body>
+</html>

Added: trunk/LayoutTests/pointerevents/ios/touch-action-none-inside-iframe-expected.txt (0 => 259761)


--- trunk/LayoutTests/pointerevents/ios/touch-action-none-inside-iframe-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/pointerevents/ios/touch-action-none-inside-iframe-expected.txt	2020-04-08 22:38:33 UTC (rev 259761)
@@ -0,0 +1,22 @@
+
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 800.00 600.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (contentsOpaque 1)
+      (drawsContent 1)
+      (backgroundColor #FFFFFF)
+      (event region
+        (rect (0,0) width=800 height=600)
+        (touch-action
+          (none          
+            (rect (18,18) width=102 height=102)
+          )
+        )
+      )
+    )
+  )
+)
+

Added: trunk/LayoutTests/pointerevents/ios/touch-action-none-inside-iframe.html (0 => 259761)


--- trunk/LayoutTests/pointerevents/ios/touch-action-none-inside-iframe.html	                        (rev 0)
+++ trunk/LayoutTests/pointerevents/ios/touch-action-none-inside-iframe.html	2020-04-08 22:38:33 UTC (rev 259761)
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html>
+<body>
+<iframe id="testFrame" srcdoc="<div style='touch-action: none; width: 100px; height: 100px; border:1px solid black'></div>" _onload_="runTest()"></iframe>
+<pre id="results"></pre>
+<script>
+if (window.testRunner) {
+    testRunner.dumpAsText();
+    testRunner.waitUntilDone();
+}
+
+function runTest()
+{
+    if (window.internals)
+        results.innerText = internals.layerTreeAsText(document, internals.LAYER_TREE_INCLUDES_EVENT_REGION | internals.LAYER_TREE_INCLUDES_ROOT_LAYER_PROPERTIES);
+    if (window.testRunner)
+        testRunner.notifyDone();
+}
+</script>
+</body>
+</html>

Added: trunk/LayoutTests/pointerevents/ios/touch-action-none-inside-nested-iframe-expected.txt (0 => 259761)


--- trunk/LayoutTests/pointerevents/ios/touch-action-none-inside-nested-iframe-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/pointerevents/ios/touch-action-none-inside-nested-iframe-expected.txt	2020-04-08 22:38:33 UTC (rev 259761)
@@ -0,0 +1,22 @@
+
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 800.00 600.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (contentsOpaque 1)
+      (drawsContent 1)
+      (backgroundColor #FFFFFF)
+      (event region
+        (rect (0,0) width=800 height=600)
+        (touch-action
+          (none          
+            (rect (28,28) width=102 height=102)
+          )
+        )
+      )
+    )
+  )
+)
+

Added: trunk/LayoutTests/pointerevents/ios/touch-action-none-inside-nested-iframe.html (0 => 259761)


--- trunk/LayoutTests/pointerevents/ios/touch-action-none-inside-nested-iframe.html	                        (rev 0)
+++ trunk/LayoutTests/pointerevents/ios/touch-action-none-inside-nested-iframe.html	2020-04-08 22:38:33 UTC (rev 259761)
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+<body>
+<iframe id="testFrame" src=""
+<pre id="results"></pre>
+<script>
+if (window.testRunner) {
+    testRunner.dumpAsText();
+    testRunner.waitUntilDone();
+}
+
+function dumpRegion()
+{
+    if (window.internals)
+        results.innerText = internals.layerTreeAsText(document, internals.LAYER_TREE_INCLUDES_EVENT_REGION | internals.LAYER_TREE_INCLUDES_ROOT_LAYER_PROPERTIES);
+    if (window.testRunner)
+        testRunner.notifyDone();
+}
+
+</script>
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (259760 => 259761)


--- trunk/Source/WebCore/ChangeLog	2020-04-08 22:15:16 UTC (rev 259760)
+++ trunk/Source/WebCore/ChangeLog	2020-04-08 22:38:33 UTC (rev 259761)
@@ -1,3 +1,109 @@
+2020-04-08  Daniel Bates  <[email protected]>
+
+        Should find touch-action elements inside non-composited iframes
+        https://bugs.webkit.org/show_bug.cgi?id=210041
+        <rdar://problem/61323558>
+
+        Reviewed by Simon Fraser.
+
+        Fix up event region code to traverse non-composited iframes that have elements with a non-auto
+        touch-action. The event region is computed for each composited layer during a compositing layer
+        update and was retricted to being updated if the layer's associated document may have an element
+        with a non-auto touch-action. To make this work for non-composited iframes I find its enclosing
+        compositing layer, set a special bit that it needs an event region update because of the non-
+        composited child iframe and schedule a compositing layer update. When the update happens, it
+        checks to see if the special bit is set and if so overrides any restrictions that would have
+        prevented the event region from being updated. The painting code for widgets is also fixed up to
+        pass through an EventRegionContext to update during EventRegion painting.
+
+        This strategy works well for updating the event region. However debug paint overlays are not
+        updated (i.e. RenderLayerBacking::paintDebugOverlays() is not called) until the embedding client's
+        view is repainted. For now, to fix this up I added another a hack, a special bit (RenderView::needsRepaintHackAfterCompositingLayerUpdateForDebugOverlaysOnly())
+        that is only set if debug overlays are to be shown, to have the compositor repaint the view after
+        updating compositing layers.
+
+        Tests: pointerevents/ios/programmatic-touch-action-none-inside-iframe.html
+               pointerevents/ios/touch-action-none-inside-iframe.html
+               pointerevents/ios/touch-action-none-inside-nested-iframe.html
+
+        * dom/Document.cpp:
+        (WebCore::Document::invalidateEventRegionsForFrame): Added. Try to invalidate the event region.
+        This may fail if the document does not have an enclosing compositing layer for repaint (e.g. nested
+        composited iframes - see test pointerevents/ios/touch-action-none-inside-nested-iframe.html). If
+        this happens then recursive on our owner element's document. Recursion is used instead of a loop
+        to future proof this code for out-of-process (OOP) frames, which will likely introduce document proxy objects.
+        * dom/Document.h:
+        * page/Frame.cpp:
+        (WebCore::Frame::invalidateContentEventRegionsIfNeeded): Added. Check if our document has any elements with
+        a non-auto touch-action. If it does then ask the compositor if the enclosing compositing layer for
+        repaint's event region must be invalidated - it will only reply true if this is a non-composited iframe.
+        If it does then forward this invalidation request to the document. The reason I delegate to the document
+        instead of handling the logic here is to future proof this code for OOP iframes.
+        * page/Frame.h:
+        * page/FrameView.cpp:
+        (WebCore::FrameView::didLayout): Call Frame::invalidateContentEventRegionsIfNeeded(). Also while
+        I am here take out a ref on the document to ensure it lives through the end of this function, including
+        through the accessibility's postNotification() code that calls out to the embedding client.
+
+        (WebCore::FrameView::paintContents):
+        * page/FrameView.h:
+        * platform/ScrollView.cpp:
+        (WebCore::ScrollView::paint):
+        * platform/ScrollView.h:
+        * platform/Scrollbar.cpp:
+        (WebCore::Scrollbar::paint):
+        * platform/Scrollbar.h:
+        * platform/Widget.cpp:
+        (WebCore::Widget::paint):
+        * platform/Widget.h:
+        * platform/gtk/WidgetGtk.cpp:
+        (WebCore::Widget::paint):
+        * platform/ios/WidgetIOS.mm:
+        (WebCore::Widget::paint):
+        * platform/mac/WidgetMac.mm:
+        (WebCore::Widget::paint):
+        * platform/win/WidgetWin.cpp:
+        (WebCore::Widget::paint):
+        * rendering/RenderBlock.cpp:
+        (WebCore::RenderBlock::paintObject):
+        Pass an EventRegionContext through.
+
+        * rendering/RenderElement.cpp:
+        (WebCore::RenderElement::styleWillChange): Update code now that RendeLayer::invalidateEventRegion()
+        takes a reason. 
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::paint): Pass the EventRegionContext through. If are passed one then update
+        paint flags to collect event region.
+        (WebCore::RenderLayer::invalidateEventRegion): Changed return value from void to bool so as to indicate
+        to the caller whether the event region was actually invalidated. Also made it take an argument as
+        to the reason for the invalidation. If invalidation is due to a non-composited iframe then sets some
+        state and schedule a compositing layer update.
+
+        * rendering/RenderLayerBacking.cpp:
+        (WebCore::RenderLayerBacking::updateEventRegion):
+        (WebCore::RenderLayerBacking::setContentsNeedDisplay):
+        (WebCore::RenderLayerBacking::setContentsNeedDisplayInRect):
+        * rendering/RenderLayerCompositor.cpp:
+        (WebCore::RenderLayerCompositor::updateCompositingLayers):
+        Pass an EventRegionContext through
+
+        (WebCore::RenderLayerCompositor::viewNeedsToInvalidateEventRegionOfEnclosingCompositingLayerForRepaint const): Added.
+
+        * rendering/RenderLayerCompositor.h:
+        * rendering/RenderScrollbar.cpp:
+        (WebCore::RenderScrollbar::paint):
+        * rendering/RenderScrollbar.h:
+        * rendering/RenderView.h:
+        Pass an EventRegionContext through.
+
+        * rendering/RenderWidget.cpp:
+        (WebCore::RenderWidget::paintContents): Translate the event region by our content paint offset.
+        (WebCore::RenderWidget::paint): Update for EventRegion. If painting the event region and the view
+        needs layout then do what we do now and bail out. Otherwise, proceed to paint the widget's content.
+        The changes to FrameView::didLayout() above means that for non-composited frames that need an event
+        region update they already performed a layout. So, these paints will be allowed to descend into
+        painting of the widget's content.
+
 2020-04-08  Rob Buis  <[email protected]>
 
         Make more use of FrameLoader pageID/frameID getters

Modified: trunk/Source/WebCore/dom/Document.cpp (259760 => 259761)


--- trunk/Source/WebCore/dom/Document.cpp	2020-04-08 22:15:16 UTC (rev 259760)
+++ trunk/Source/WebCore/dom/Document.cpp	2020-04-08 22:38:33 UTC (rev 259761)
@@ -4234,6 +4234,19 @@
         m_activeElement = m_activeElement->parentElement();
 }
 
+void Document::invalidateEventRegionsForFrame(HTMLFrameOwnerElement& element)
+{
+    auto* renderer = element.renderer();
+    if (!renderer)
+        return;
+    if (auto* layer = renderer->enclosingLayer()) {
+        if (layer->invalidateEventRegion(RenderLayer::EventRegionInvalidationReason::NonCompositedFrame))
+            return;
+    }
+    if (auto* ownerElement = this->ownerElement())
+        ownerElement->document().invalidateEventRegionsForFrame(*ownerElement);
+}
+
 void Document::invalidateRenderingDependentRegions()
 {
 #if PLATFORM(IOS_FAMILY) && ENABLE(TOUCH_EVENTS)

Modified: trunk/Source/WebCore/dom/Document.h (259760 => 259761)


--- trunk/Source/WebCore/dom/Document.h	2020-04-08 22:15:16 UTC (rev 259760)
+++ trunk/Source/WebCore/dom/Document.h	2020-04-08 22:38:33 UTC (rev 259761)
@@ -1140,6 +1140,7 @@
     WEBCORE_EXPORT String displayStringModifiedByEncoding(const String&) const;
 
     void invalidateRenderingDependentRegions();
+    void invalidateEventRegionsForFrame(HTMLFrameOwnerElement&);
 
     void removeAllEventListeners() final;
 

Modified: trunk/Source/WebCore/page/Frame.cpp (259760 => 259761)


--- trunk/Source/WebCore/page/Frame.cpp	2020-04-08 22:15:16 UTC (rev 259760)
+++ trunk/Source/WebCore/page/Frame.cpp	2020-04-08 22:38:33 UTC (rev 259761)
@@ -305,6 +305,20 @@
     m_documentIsBeingReplaced = false;
 }
 
+void Frame::invalidateContentEventRegionsIfNeeded()
+{
+    if (!m_page || !m_doc || !m_doc->renderView())
+        return;
+#if PLATFORM(IOS)
+    if (!m_doc->mayHaveElementsWithNonAutoTouchAction())
+        return;
+#endif
+    if (!m_doc->renderView()->compositor().viewNeedsToInvalidateEventRegionOfEnclosingCompositingLayerForRepaint())
+        return;
+    if (m_ownerElement)
+        m_ownerElement->document().invalidateEventRegionsForFrame(*m_ownerElement);
+}
+
 #if ENABLE(ORIENTATION_EVENTS)
 void Frame::orientationChanged()
 {

Modified: trunk/Source/WebCore/page/Frame.h (259760 => 259761)


--- trunk/Source/WebCore/page/Frame.h	2020-04-08 22:15:16 UTC (rev 259760)
+++ trunk/Source/WebCore/page/Frame.h	2020-04-08 22:38:33 UTC (rev 259761)
@@ -305,6 +305,8 @@
     void didPrewarmLocalStorage();
     bool mayPrewarmLocalStorage() const;
 
+    void invalidateContentEventRegionsIfNeeded();
+
 // ========
 
     void selfOnlyRef();

Modified: trunk/Source/WebCore/page/FrameView.cpp (259760 => 259761)


--- trunk/Source/WebCore/page/FrameView.cpp	2020-04-08 22:15:16 UTC (rev 259760)
+++ trunk/Source/WebCore/page/FrameView.cpp	2020-04-08 22:38:33 UTC (rev 259761)
@@ -1261,12 +1261,15 @@
 
     updateCompositingLayersAfterLayout();
 
+    auto document = makeRef(*frame().document());
+
 #if PLATFORM(COCOA) || PLATFORM(WIN) || PLATFORM(GTK)
-    if (auto* cache = frame().document()->existingAXObjectCache())
+    if (auto* cache = document->existingAXObjectCache())
         cache->postNotification(layoutRoot.get(), AXObjectCache::AXLayoutComplete);
 #endif
 
-    frame().document()->invalidateRenderingDependentRegions();
+    frame().invalidateContentEventRegionsIfNeeded();
+    document->invalidateRenderingDependentRegions();
 
     updateCanBlitOnScrollRecursively();
 
@@ -1274,10 +1277,10 @@
 
     handleDeferredScrollbarsUpdateAfterDirectionChange();
 
-    if (frame().document()->hasListenerType(Document::OVERFLOWCHANGED_LISTENER))
+    if (document->hasListenerType(Document::OVERFLOWCHANGED_LISTENER))
         updateOverflowStatus(layoutWidth() < contentsWidth(), layoutHeight() < contentsHeight());
 
-    frame().document()->markers().invalidateRectsForAllMarkers();
+    document->markers().invalidateRectsForAllMarkers();
 }
 
 bool FrameView::shouldDeferScrollUpdateAfterContentSizeChange()
@@ -4229,7 +4232,7 @@
     }
 }
 
-void FrameView::paintContents(GraphicsContext& context, const IntRect& dirtyRect, SecurityOriginPaintPolicy securityOriginPaintPolicy)
+void FrameView::paintContents(GraphicsContext& context, const IntRect& dirtyRect, SecurityOriginPaintPolicy securityOriginPaintPolicy, EventRegionContext* eventRegionContext)
 {
 #ifndef NDEBUG
     bool fillWithWarningColor;
@@ -4290,8 +4293,8 @@
     while (is<RenderInline>(renderer) && !downcast<RenderInline>(*renderer).firstLineBox())
         renderer = renderer->parent();
 
-    rootLayer->paint(context, dirtyRect, LayoutSize(), m_paintBehavior, renderer, { }, securityOriginPaintPolicy == SecurityOriginPaintPolicy::AnyOrigin ? RenderLayer::SecurityOriginPaintPolicy::AnyOrigin : RenderLayer::SecurityOriginPaintPolicy::AccessibleOriginOnly);
-    if (rootLayer->containsDirtyOverlayScrollbars())
+    rootLayer->paint(context, dirtyRect, LayoutSize(), m_paintBehavior, renderer, { }, securityOriginPaintPolicy == SecurityOriginPaintPolicy::AnyOrigin ? RenderLayer::SecurityOriginPaintPolicy::AnyOrigin : RenderLayer::SecurityOriginPaintPolicy::AccessibleOriginOnly, eventRegionContext);
+    if (rootLayer->containsDirtyOverlayScrollbars() && !eventRegionContext)
         rootLayer->paintOverlayScrollbars(context, dirtyRect, m_paintBehavior, renderer);
 
     didPaintContents(context, dirtyRect, paintingState);

Modified: trunk/Source/WebCore/page/FrameView.h (259760 => 259761)


--- trunk/Source/WebCore/page/FrameView.h	2020-04-08 22:15:16 UTC (rev 259760)
+++ trunk/Source/WebCore/page/FrameView.h	2020-04-08 22:38:33 UTC (rev 259761)
@@ -57,6 +57,7 @@
 
 class AXObjectCache;
 class Element;
+class EventRegionContext;
 class FloatSize;
 class Frame;
 class HTMLFrameOwnerElement;
@@ -351,7 +352,7 @@
     void addEmbeddedObjectToUpdate(RenderEmbeddedObject&);
     void removeEmbeddedObjectToUpdate(RenderEmbeddedObject&);
 
-    WEBCORE_EXPORT void paintContents(GraphicsContext&, const IntRect& dirtyRect, SecurityOriginPaintPolicy = SecurityOriginPaintPolicy::AnyOrigin) final;
+    WEBCORE_EXPORT void paintContents(GraphicsContext&, const IntRect& dirtyRect, SecurityOriginPaintPolicy = SecurityOriginPaintPolicy::AnyOrigin, EventRegionContext* = nullptr) final;
 
     struct PaintingState {
         OptionSet<PaintBehavior> paintBehavior;

Modified: trunk/Source/WebCore/platform/ScrollView.cpp (259760 => 259761)


--- trunk/Source/WebCore/platform/ScrollView.cpp	2020-04-08 22:15:16 UTC (rev 259760)
+++ trunk/Source/WebCore/platform/ScrollView.cpp	2020-04-08 22:38:33 UTC (rev 259761)
@@ -1237,7 +1237,7 @@
     context.drawImage(panScrollIcon, iconGCPoint);
 }
 
-void ScrollView::paint(GraphicsContext& context, const IntRect& rect, SecurityOriginPaintPolicy securityOriginPaintPolicy)
+void ScrollView::paint(GraphicsContext& context, const IntRect& rect, SecurityOriginPaintPolicy securityOriginPaintPolicy, EventRegionContext* eventRegionContext)
 {
     if (platformWidget()) {
         Widget::paint(context, rect);
@@ -1244,7 +1244,7 @@
         return;
     }
 
-    if (context.paintingDisabled() && !context.performingPaintInvalidation())
+    if (context.paintingDisabled() && !context.performingPaintInvalidation() && !eventRegionContext)
         return;
 
     notifyPageThatContentAreaWillPaint();
@@ -1269,7 +1269,7 @@
             context.clip(visibleContentRect(LegacyIOSDocumentVisibleRect));
         }
 
-        paintContents(context, documentDirtyRect, securityOriginPaintPolicy);
+        paintContents(context, documentDirtyRect, securityOriginPaintPolicy, eventRegionContext);
     }
 
 #if ENABLE(RUBBER_BANDING)

Modified: trunk/Source/WebCore/platform/ScrollView.h (259760 => 259761)


--- trunk/Source/WebCore/platform/ScrollView.h	2020-04-08 22:15:16 UTC (rev 259760)
+++ trunk/Source/WebCore/platform/ScrollView.h	2020-04-08 22:38:33 UTC (rev 259761)
@@ -57,6 +57,7 @@
 
 namespace WebCore {
 
+class EventRegionContext;
 class HostWindow;
 class LegacyTileCache;
 class Scrollbar;
@@ -350,7 +351,7 @@
     }
 
     // Widget override. Handles painting of the contents of the view as well as the scrollbars.
-    WEBCORE_EXPORT void paint(GraphicsContext&, const IntRect&, Widget::SecurityOriginPaintPolicy = SecurityOriginPaintPolicy::AnyOrigin) final;
+    WEBCORE_EXPORT void paint(GraphicsContext&, const IntRect&, Widget::SecurityOriginPaintPolicy = SecurityOriginPaintPolicy::AnyOrigin, EventRegionContext* = nullptr) final;
     void paintScrollbars(GraphicsContext&, const IntRect&);
 
     // Widget overrides to ensure that our children's visibility status is kept up to date when we get shown and hidden.
@@ -388,7 +389,7 @@
     ScrollView();
 
     virtual void repaintContentRectangle(const IntRect&);
-    virtual void paintContents(GraphicsContext&, const IntRect& damageRect, SecurityOriginPaintPolicy = SecurityOriginPaintPolicy::AnyOrigin) = 0;
+    virtual void paintContents(GraphicsContext&, const IntRect& damageRect, SecurityOriginPaintPolicy = SecurityOriginPaintPolicy::AnyOrigin, EventRegionContext* = nullptr) = 0;
 
     virtual void paintOverhangAreas(GraphicsContext&, const IntRect& horizontalOverhangArea, const IntRect& verticalOverhangArea, const IntRect& dirtyRect);
 

Modified: trunk/Source/WebCore/platform/Scrollbar.cpp (259760 => 259761)


--- trunk/Source/WebCore/platform/Scrollbar.cpp	2020-04-08 22:15:16 UTC (rev 259760)
+++ trunk/Source/WebCore/platform/Scrollbar.cpp	2020-04-08 22:38:33 UTC (rev 259761)
@@ -140,7 +140,7 @@
     updateThumb();
 }
 
-void Scrollbar::paint(GraphicsContext& context, const IntRect& damageRect, Widget::SecurityOriginPaintPolicy)
+void Scrollbar::paint(GraphicsContext& context, const IntRect& damageRect, Widget::SecurityOriginPaintPolicy, EventRegionContext*)
 {
     if (context.invalidatingControlTints() && theme().supportsControlTints()) {
         invalidate();

Modified: trunk/Source/WebCore/platform/Scrollbar.h (259760 => 259761)


--- trunk/Source/WebCore/platform/Scrollbar.h	2020-04-08 22:15:16 UTC (rev 259760)
+++ trunk/Source/WebCore/platform/Scrollbar.h	2020-04-08 22:38:33 UTC (rev 259761)
@@ -83,7 +83,7 @@
     WEBCORE_EXPORT void setProportion(int visibleSize, int totalSize);
     void setPressedPos(int p) { m_pressedPos = p; }
 
-    void paint(GraphicsContext&, const IntRect& damageRect, Widget::SecurityOriginPaintPolicy = SecurityOriginPaintPolicy::AnyOrigin) override;
+    void paint(GraphicsContext&, const IntRect& damageRect, Widget::SecurityOriginPaintPolicy = SecurityOriginPaintPolicy::AnyOrigin, EventRegionContext* = nullptr) override;
 
     bool enabled() const { return m_enabled; }
     virtual void setEnabled(bool);

Modified: trunk/Source/WebCore/platform/Widget.cpp (259760 => 259761)


--- trunk/Source/WebCore/platform/Widget.cpp	2020-04-08 22:15:16 UTC (rev 259760)
+++ trunk/Source/WebCore/platform/Widget.cpp	2020-04-08 22:38:33 UTC (rev 259761)
@@ -285,7 +285,7 @@
     notImplemented();
 }
 
-void Widget::paint(GraphicsContext&, const IntRect&, SecurityOriginPaintPolicy)
+void Widget::paint(GraphicsContext&, const IntRect&, SecurityOriginPaintPolicy, EventRegionContext*)
 {
     notImplemented();
 }

Modified: trunk/Source/WebCore/platform/Widget.h (259760 => 259761)


--- trunk/Source/WebCore/platform/Widget.h	2020-04-08 22:15:16 UTC (rev 259760)
+++ trunk/Source/WebCore/platform/Widget.h	2020-04-08 22:38:33 UTC (rev 259761)
@@ -60,6 +60,7 @@
 
 class Cursor;
 class Event;
+class EventRegionContext;
 class FontCascade;
 class FrameView;
 class GraphicsContext;
@@ -109,7 +110,7 @@
 
     enum class SecurityOriginPaintPolicy { AnyOrigin, AccessibleOriginOnly };
 
-    WEBCORE_EXPORT virtual void paint(GraphicsContext&, const IntRect&, SecurityOriginPaintPolicy = SecurityOriginPaintPolicy::AnyOrigin);
+    WEBCORE_EXPORT virtual void paint(GraphicsContext&, const IntRect&, SecurityOriginPaintPolicy = SecurityOriginPaintPolicy::AnyOrigin, EventRegionContext* = nullptr);
     void invalidate() { invalidateRect(boundsRect()); }
     virtual void invalidateRect(const IntRect&) = 0;
 

Modified: trunk/Source/WebCore/platform/gtk/WidgetGtk.cpp (259760 => 259761)


--- trunk/Source/WebCore/platform/gtk/WidgetGtk.cpp	2020-04-08 22:15:16 UTC (rev 259760)
+++ trunk/Source/WebCore/platform/gtk/WidgetGtk.cpp	2020-04-08 22:38:33 UTC (rev 259761)
@@ -62,7 +62,7 @@
     setSelfVisible(false);
 }
 
-void Widget::paint(GraphicsContext&, const IntRect&, SecurityOriginPaintPolicy)
+void Widget::paint(GraphicsContext&, const IntRect&, SecurityOriginPaintPolicy, EventRegionContext*)
 {
 }
 

Modified: trunk/Source/WebCore/platform/ios/WidgetIOS.mm (259760 => 259761)


--- trunk/Source/WebCore/platform/ios/WidgetIOS.mm	2020-04-08 22:15:16 UTC (rev 259760)
+++ trunk/Source/WebCore/platform/ios/WidgetIOS.mm	2020-04-08 22:38:33 UTC (rev 259761)
@@ -146,7 +146,7 @@
     return view;
 }
 
-void Widget::paint(GraphicsContext& p, const IntRect& r, SecurityOriginPaintPolicy)
+void Widget::paint(GraphicsContext& p, const IntRect& r, SecurityOriginPaintPolicy, EventRegionContext*)
 {
     if (p.paintingDisabled())
         return;

Modified: trunk/Source/WebCore/platform/mac/WidgetMac.mm (259760 => 259761)


--- trunk/Source/WebCore/platform/mac/WidgetMac.mm	2020-04-08 22:15:16 UTC (rev 259760)
+++ trunk/Source/WebCore/platform/mac/WidgetMac.mm	2020-04-08 22:38:33 UTC (rev 259761)
@@ -186,7 +186,7 @@
     return view;
 }
 
-void Widget::paint(GraphicsContext& p, const IntRect& r, SecurityOriginPaintPolicy)
+void Widget::paint(GraphicsContext& p, const IntRect& r, SecurityOriginPaintPolicy, EventRegionContext*)
 {
     if (p.paintingDisabled())
         return;

Modified: trunk/Source/WebCore/platform/win/WidgetWin.cpp (259760 => 259761)


--- trunk/Source/WebCore/platform/win/WidgetWin.cpp	2020-04-08 22:15:16 UTC (rev 259760)
+++ trunk/Source/WebCore/platform/win/WidgetWin.cpp	2020-04-08 22:38:33 UTC (rev 259761)
@@ -70,7 +70,7 @@
     view->hostWindow()->setCursor(cursor);
 }
 
-void Widget::paint(GraphicsContext&, const IntRect&, SecurityOriginPaintPolicy)
+void Widget::paint(GraphicsContext&, const IntRect&, SecurityOriginPaintPolicy, EventRegionContext*)
 {
 }
 

Modified: trunk/Source/WebCore/rendering/RenderBlock.cpp (259760 => 259761)


--- trunk/Source/WebCore/rendering/RenderBlock.cpp	2020-04-08 22:15:16 UTC (rev 259760)
+++ trunk/Source/WebCore/rendering/RenderBlock.cpp	2020-04-08 22:38:33 UTC (rev 259761)
@@ -1255,8 +1255,7 @@
             paintInfo.eventRegionContext->unite(borderRegion, style());
         }
 
-        // No need to check descendants if we don't have overflow and don't contain floats and the area is already covered.
-        bool needsTraverseDescendants = hasVisualOverflow() || containsFloats() || !paintInfo.eventRegionContext->contains(enclosingIntRect(borderRect));
+        bool needsTraverseDescendants = hasVisualOverflow() || containsFloats() || !paintInfo.eventRegionContext->contains(enclosingIntRect(borderRect)) || view().needsEventRegionUpdateForNonCompositedFrame();
 #if PLATFORM(IOS_FAMILY)
         needsTraverseDescendants = needsTraverseDescendants || document().mayHaveElementsWithNonAutoTouchAction();
 #endif

Modified: trunk/Source/WebCore/rendering/RenderElement.cpp (259760 => 259761)


--- trunk/Source/WebCore/rendering/RenderElement.cpp	2020-04-08 22:15:16 UTC (rev 259760)
+++ trunk/Source/WebCore/rendering/RenderElement.cpp	2020-04-08 22:38:33 UTC (rev 259761)
@@ -745,7 +745,7 @@
         if (needsInvalidateEventRegion()) {
             // Usually the event region gets updated as a result of paint invalidation. Here we need to request an update explicitly.
             if (auto* layer = enclosingLayer())
-                layer->invalidateEventRegion();
+                layer->invalidateEventRegion(RenderLayer::EventRegionInvalidationReason::Style);
         }
 
         if (m_parent && (newStyle.outlineSize() < m_style.outlineSize() || shouldRepaintForStyleDifference(diff)))

Modified: trunk/Source/WebCore/rendering/RenderLayer.cpp (259760 => 259761)


--- trunk/Source/WebCore/rendering/RenderLayer.cpp	2020-04-08 22:15:16 UTC (rev 259760)
+++ trunk/Source/WebCore/rendering/RenderLayer.cpp	2020-04-08 22:38:33 UTC (rev 259761)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2006-2020 Apple Inc. All rights reserved.
  * Copyright (C) 2019 Adobe. All rights reserved.
  *
  * Portions are Copyright (C) 1998 Netscape Communications Corporation.
@@ -4203,11 +4203,15 @@
     return ScrollableArea::scroll(direction, granularity, multiplier);
 }
 
-void RenderLayer::paint(GraphicsContext& context, const LayoutRect& damageRect, const LayoutSize& subpixelOffset, OptionSet<PaintBehavior> paintBehavior, RenderObject* subtreePaintRoot, OptionSet<PaintLayerFlag> paintFlags, SecurityOriginPaintPolicy paintPolicy)
+void RenderLayer::paint(GraphicsContext& context, const LayoutRect& damageRect, const LayoutSize& subpixelOffset, OptionSet<PaintBehavior> paintBehavior, RenderObject* subtreePaintRoot, OptionSet<PaintLayerFlag> paintFlags, SecurityOriginPaintPolicy paintPolicy, EventRegionContext* eventRegionContext)
 {
     OverlapTestRequestMap overlapTestRequests;
 
     LayerPaintingInfo paintingInfo(this, enclosingIntRect(damageRect), paintBehavior, subpixelOffset, subtreePaintRoot, &overlapTestRequests, paintPolicy == SecurityOriginPaintPolicy::AccessibleOriginOnly);
+    if (eventRegionContext) {
+        paintingInfo.eventRegionContext = eventRegionContext;
+        paintFlags.add(RenderLayer::PaintLayerCollectingEventRegion);
+    }
     paintLayer(context, paintingInfo, paintFlags);
 
     for (auto& widget : overlapTestRequests.keys())
@@ -7001,12 +7005,13 @@
     return false;
 }
 
-void RenderLayer::invalidateEventRegion()
+bool RenderLayer::invalidateEventRegion(EventRegionInvalidationReason reason)
 {
+    // FIXME: This should not be conditioned on PLATFORM(IOS_FAMILY). See <https://webkit.org/b/210216>.
 #if PLATFORM(IOS_FAMILY)
     auto* compositingLayer = enclosingCompositingLayerForRepaint();
     if (!compositingLayer)
-        return;
+        return false;
 
     auto maintainsEventRegion = [&] {
         // UI side scroll overlap testing.
@@ -7018,10 +7023,22 @@
         return false;
     };
 
-    if (!maintainsEventRegion())
-        return;
+    if (reason != EventRegionInvalidationReason::NonCompositedFrame && !maintainsEventRegion())
+        return false;
 
     compositingLayer->setNeedsCompositingConfigurationUpdate();
+
+    if (reason == EventRegionInvalidationReason::NonCompositedFrame) {
+        auto& view = renderer().view();
+        view.setNeedsEventRegionUpdateForNonCompositedFrame();
+        if (renderer().settings().visibleDebugOverlayRegions() & NonFastScrollableRegion)
+            view.setNeedsRepaintHackAfterCompositingLayerUpdateForDebugOverlaysOnly();
+        view.compositor().scheduleCompositingLayerUpdate();
+    }
+    return true;
+#else
+    UNUSED_PARAM(reason);
+    return false;
 #endif
 }
 

Modified: trunk/Source/WebCore/rendering/RenderLayer.h (259760 => 259761)


--- trunk/Source/WebCore/rendering/RenderLayer.h	2020-04-08 22:15:16 UTC (rev 259760)
+++ trunk/Source/WebCore/rendering/RenderLayer.h	2020-04-08 22:38:33 UTC (rev 259761)
@@ -695,7 +695,7 @@
     // front.  The hitTest method looks for mouse events by walking
     // layers that intersect the point from front to back.
     void paint(GraphicsContext&, const LayoutRect& damageRect, const LayoutSize& subpixelOffset = LayoutSize(), OptionSet<PaintBehavior> = PaintBehavior::Normal,
-        RenderObject* subtreePaintRoot = nullptr, OptionSet<PaintLayerFlag> = { }, SecurityOriginPaintPolicy = SecurityOriginPaintPolicy::AnyOrigin);
+        RenderObject* subtreePaintRoot = nullptr, OptionSet<PaintLayerFlag> = { }, SecurityOriginPaintPolicy = SecurityOriginPaintPolicy::AnyOrigin, EventRegionContext* = nullptr);
     bool hitTest(const HitTestRequest&, HitTestResult&);
     bool hitTest(const HitTestRequest&, const HitTestLocation&, HitTestResult&);
     void paintOverlayScrollbars(GraphicsContext&, const LayoutRect& damageRect, OptionSet<PaintBehavior>, RenderObject* subtreePaintRoot = nullptr);
@@ -924,7 +924,10 @@
 
     WEBCORE_EXPORT bool isTransparentRespectingParentFrames() const;
 
-    void invalidateEventRegion();
+    // Invalidation can fail if there is no enclosing compositing layer (e.g. nested iframe)
+    // or the layer does not maintain an event region.
+    enum class EventRegionInvalidationReason { Paint, Style, NonCompositedFrame };
+    bool invalidateEventRegion(EventRegionInvalidationReason);
 
     String debugDescription() const final;
 

Modified: trunk/Source/WebCore/rendering/RenderLayerBacking.cpp (259760 => 259761)


--- trunk/Source/WebCore/rendering/RenderLayerBacking.cpp	2020-04-08 22:15:16 UTC (rev 259760)
+++ trunk/Source/WebCore/rendering/RenderLayerBacking.cpp	2020-04-08 22:38:33 UTC (rev 259761)
@@ -1618,11 +1618,12 @@
     if (paintsIntoCompositedAncestor())
         return;
 
+    bool needsEventRegionUpdateForNonCompositedFrame = renderer().view().needsEventRegionUpdateForNonCompositedFrame();
     bool hasTouchActionElements = false;
 #if PLATFORM(IOS_FAMILY)
     hasTouchActionElements = renderer().document().mayHaveElementsWithNonAutoTouchAction();
 #endif
-    if (!hasTouchActionElements) {
+    if (!hasTouchActionElements && !needsEventRegionUpdateForNonCompositedFrame) {
         if (m_owningLayer.isRenderViewLayer())
             return;
 
@@ -1666,6 +1667,9 @@
 
     if (m_scrolledContentsLayer)
         updateEventRegionForLayer(*m_scrolledContentsLayer);
+
+    if (needsEventRegionUpdateForNonCompositedFrame)
+        renderer().view().setNeedsEventRegionUpdateForNonCompositedFrame(false);
 }
 #endif
 
@@ -2781,7 +2785,7 @@
     if (!m_owningLayer.isRenderViewLayer())
         m_owningLayer.setNeedsCompositingConfigurationUpdate();
 
-    m_owningLayer.invalidateEventRegion();
+    m_owningLayer.invalidateEventRegion(RenderLayer::EventRegionInvalidationReason::Paint);
 
     auto& frameView = renderer().view().frameView();
     if (m_isMainFrameRenderViewLayer && frameView.isTrackingRepaints())
@@ -2821,7 +2825,7 @@
     if (!m_owningLayer.isRenderViewLayer())
         m_owningLayer.setNeedsCompositingConfigurationUpdate();
 
-    m_owningLayer.invalidateEventRegion();
+    m_owningLayer.invalidateEventRegion(RenderLayer::EventRegionInvalidationReason::Paint);
 
     FloatRect pixelSnappedRectForPainting = snapRectToDevicePixels(r, deviceScaleFactor());
     auto& frameView = renderer().view().frameView();

Modified: trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp (259760 => 259761)


--- trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp	2020-04-08 22:15:16 UTC (rev 259760)
+++ trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp	2020-04-08 22:38:33 UTC (rev 259761)
@@ -858,6 +858,11 @@
 
     InspectorInstrumentation::layerTreeDidChange(&page());
 
+    if (m_renderView.needsRepaintHackAfterCompositingLayerUpdateForDebugOverlaysOnly()) {
+        m_renderView.repaintRootContents();
+        m_renderView.setNeedsRepaintHackAfterCompositingLayerUpdateForDebugOverlaysOnly(false);
+    }
+
     return true;
 }
 
@@ -3725,6 +3730,14 @@
 
 #endif
 
+bool RenderLayerCompositor::viewNeedsToInvalidateEventRegionOfEnclosingCompositingLayerForRepaint() const
+{
+    // Event regions are only updated on compositing layers. Non-composited layers must
+    // delegate to their enclosing compositing layer for repaint to update the event region
+    // for elements inside them.
+    return !m_renderView.isComposited();
+}
+
 bool RenderLayerCompositor::viewHasTransparentBackground(Color* backgroundColor) const
 {
     if (m_renderView.frameView().isTransparent()) {

Modified: trunk/Source/WebCore/rendering/RenderLayerCompositor.h (259760 => 259761)


--- trunk/Source/WebCore/rendering/RenderLayerCompositor.h	2020-04-08 22:15:16 UTC (rev 259760)
+++ trunk/Source/WebCore/rendering/RenderLayerCompositor.h	2020-04-08 22:38:33 UTC (rev 259761)
@@ -358,6 +358,8 @@
 
     bool viewHasTransparentBackground(Color* backgroundColor = nullptr) const;
 
+    bool viewNeedsToInvalidateEventRegionOfEnclosingCompositingLayerForRepaint() const;
+
     bool hasNonMainLayersWithTiledBacking() const { return m_layersWithTiledBackingCount; }
 
     OptionSet<CompositingReason> reasonsForCompositing(const RenderLayer&) const;

Modified: trunk/Source/WebCore/rendering/RenderScrollbar.cpp (259760 => 259761)


--- trunk/Source/WebCore/rendering/RenderScrollbar.cpp	2020-04-08 22:15:16 UTC (rev 259760)
+++ trunk/Source/WebCore/rendering/RenderScrollbar.cpp	2020-04-08 22:38:33 UTC (rev 259761)
@@ -100,7 +100,7 @@
     updateScrollbarParts();
 }
 
-void RenderScrollbar::paint(GraphicsContext& context, const IntRect& damageRect, Widget::SecurityOriginPaintPolicy)
+void RenderScrollbar::paint(GraphicsContext& context, const IntRect& damageRect, Widget::SecurityOriginPaintPolicy, EventRegionContext*)
 {
     if (context.invalidatingControlTints()) {
         updateScrollbarParts();

Modified: trunk/Source/WebCore/rendering/RenderScrollbar.h (259760 => 259761)


--- trunk/Source/WebCore/rendering/RenderScrollbar.h	2020-04-08 22:15:16 UTC (rev 259760)
+++ trunk/Source/WebCore/rendering/RenderScrollbar.h	2020-04-08 22:38:33 UTC (rev 259761)
@@ -68,7 +68,7 @@
     void setParent(ScrollView*) override;
     void setEnabled(bool) override;
 
-    void paint(GraphicsContext&, const IntRect& damageRect, Widget::SecurityOriginPaintPolicy) override;
+    void paint(GraphicsContext&, const IntRect& damageRect, Widget::SecurityOriginPaintPolicy, EventRegionContext*) override;
 
     void setHoveredPart(ScrollbarPart) override;
     void setPressedPart(ScrollbarPart) override;

Modified: trunk/Source/WebCore/rendering/RenderView.h (259760 => 259761)


--- trunk/Source/WebCore/rendering/RenderView.h	2020-04-08 22:15:16 UTC (rev 259760)
+++ trunk/Source/WebCore/rendering/RenderView.h	2020-04-08 22:38:33 UTC (rev 259761)
@@ -68,6 +68,12 @@
 
     FrameView& frameView() const { return m_frameView; }
 
+    bool needsRepaintHackAfterCompositingLayerUpdateForDebugOverlaysOnly() const { return m_needsRepaintHackAfterCompositingLayerUpdateForDebugOverlaysOnly; };
+    void setNeedsRepaintHackAfterCompositingLayerUpdateForDebugOverlaysOnly(bool value = true) { m_needsRepaintHackAfterCompositingLayerUpdateForDebugOverlaysOnly = value; }
+
+    bool needsEventRegionUpdateForNonCompositedFrame() const { return m_needsEventRegionUpdateForNonCompositedFrame; }
+    void setNeedsEventRegionUpdateForNonCompositedFrame(bool value = true) { m_needsEventRegionUpdateForNonCompositedFrame = value; }
+
     Optional<LayoutRect> computeVisibleRectInContainer(const LayoutRect&, const RenderLayerModelObject* container, VisibleRectContext) const override;
     void repaintRootContents();
     void repaintViewRectangle(const LayoutRect&) const;
@@ -255,6 +261,8 @@
     bool m_hasSoftwareFilters { false };
     bool m_usesFirstLineRules { false };
     bool m_usesFirstLetterRules { false };
+    bool m_needsRepaintHackAfterCompositingLayerUpdateForDebugOverlaysOnly { false };
+    bool m_needsEventRegionUpdateForNonCompositedFrame { false };
 
     HashMap<RenderElement*, Vector<CachedImage*>> m_renderersWithPausedImageAnimation;
     HashSet<RenderElement*> m_visibleInViewportRenderers;

Modified: trunk/Source/WebCore/rendering/RenderWidget.cpp (259760 => 259761)


--- trunk/Source/WebCore/rendering/RenderWidget.cpp	2020-04-08 22:15:16 UTC (rev 259760)
+++ trunk/Source/WebCore/rendering/RenderWidget.cpp	2020-04-08 22:38:33 UTC (rev 259761)
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 1999 Lars Knoll ([email protected])
  * Copyright (C) 2000 Dirk Mueller ([email protected])
- * Copyright (C) 2004, 2006, 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2004-2020 Apple Inc. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -246,9 +246,19 @@
         paintInfo.context().translate(widgetPaintOffset);
         paintRect.move(-widgetPaintOffset);
     }
+
+    if (paintInfo.eventRegionContext) {
+        AffineTransform transform;
+        transform.translate(contentPaintOffset);
+        paintInfo.eventRegionContext->pushTransform(transform);
+    }
+
     // FIXME: Remove repaintrect enclosing/integral snapping when RenderWidget becomes device pixel snapped.
-    m_widget->paint(paintInfo.context(), snappedIntRect(paintRect), paintInfo.requireSecurityOriginAccessForWidgets ? Widget::SecurityOriginPaintPolicy::AccessibleOriginOnly : Widget::SecurityOriginPaintPolicy::AnyOrigin);
+    m_widget->paint(paintInfo.context(), snappedIntRect(paintRect), paintInfo.requireSecurityOriginAccessForWidgets ? Widget::SecurityOriginPaintPolicy::AccessibleOriginOnly : Widget::SecurityOriginPaintPolicy::AnyOrigin, paintInfo.eventRegionContext);
 
+    if (paintInfo.eventRegionContext)
+        paintInfo.eventRegionContext->popTransform();
+
     if (!widgetPaintOffset.isZero())
         paintInfo.context().translate(-widgetPaintOffset);
 
@@ -282,7 +292,7 @@
     if ((paintInfo.phase == PaintPhase::Outline || paintInfo.phase == PaintPhase::SelfOutline) && hasOutline())
         paintOutline(paintInfo, LayoutRect(adjustedPaintOffset, size()));
 
-    if (paintInfo.phase != PaintPhase::Foreground)
+    if (paintInfo.phase != PaintPhase::Foreground && (paintInfo.phase != PaintPhase::EventRegion || view().needsLayout()))
         return;
 
     if (style().hasBorderRadius()) {
@@ -304,6 +314,9 @@
     if (style().hasBorderRadius())
         paintInfo.context().restore();
 
+    if (paintInfo.phase == PaintPhase::EventRegion)
+        return;
+
     // Paint a partially transparent wash over selected widgets.
     if (isSelected() && !document().printing()) {
         // FIXME: selectionRect() is in absolute, not painting coordinates.

Modified: trunk/Source/WebKit/ChangeLog (259760 => 259761)


--- trunk/Source/WebKit/ChangeLog	2020-04-08 22:15:16 UTC (rev 259760)
+++ trunk/Source/WebKit/ChangeLog	2020-04-08 22:38:33 UTC (rev 259761)
@@ -1,3 +1,17 @@
+2020-04-08  Daniel Bates  <[email protected]>
+
+        Should find touch-action elements inside non-composited iframes
+        https://bugs.webkit.org/show_bug.cgi?id=210041
+        <rdar://problem/61323558>
+
+        Reviewed by Simon Fraser.
+
+        Pass EventRegionContext through. It is unused as it's not applicable for plugin painting.
+
+        * WebProcess/Plugins/PluginView.cpp:
+        (WebKit::PluginView::paint):
+        * WebProcess/Plugins/PluginView.h:
+
 2020-04-08  Brady Eidson  <[email protected]>
 
         Fix handling non-linearized PDFs when incremental PDF loading is enabled.

Modified: trunk/Source/WebKit/WebProcess/Plugins/PluginView.cpp (259760 => 259761)


--- trunk/Source/WebKit/WebProcess/Plugins/PluginView.cpp	2020-04-08 22:15:16 UTC (rev 259760)
+++ trunk/Source/WebKit/WebProcess/Plugins/PluginView.cpp	2020-04-08 22:38:33 UTC (rev 259761)
@@ -783,7 +783,7 @@
     viewGeometryDidChange();
 }
 
-void PluginView::paint(GraphicsContext& context, const IntRect& /*dirtyRect*/, Widget::SecurityOriginPaintPolicy)
+void PluginView::paint(GraphicsContext& context, const IntRect& /*dirtyRect*/, Widget::SecurityOriginPaintPolicy, EventRegionContext*)
 {
     if (!m_plugin || !m_isInitialized || m_pluginElement->displayState() < HTMLPlugInElement::Restarting)
         return;

Modified: trunk/Source/WebKit/WebProcess/Plugins/PluginView.h (259760 => 259761)


--- trunk/Source/WebKit/WebProcess/Plugins/PluginView.h	2020-04-08 22:15:16 UTC (rev 259760)
+++ trunk/Source/WebKit/WebProcess/Plugins/PluginView.h	2020-04-08 22:38:33 UTC (rev 259761)
@@ -173,7 +173,7 @@
 
     // WebCore::Widget
     void setFrameRect(const WebCore::IntRect&) override;
-    void paint(WebCore::GraphicsContext&, const WebCore::IntRect&, WebCore::Widget::SecurityOriginPaintPolicy) override;
+    void paint(WebCore::GraphicsContext&, const WebCore::IntRect&, WebCore::Widget::SecurityOriginPaintPolicy, WebCore::EventRegionContext*) override;
     void invalidateRect(const WebCore::IntRect&) override;
     void setFocus(bool) override;
     void frameRectsChanged() override;

Modified: trunk/Source/WebKitLegacy/win/ChangeLog (259760 => 259761)


--- trunk/Source/WebKitLegacy/win/ChangeLog	2020-04-08 22:15:16 UTC (rev 259760)
+++ trunk/Source/WebKitLegacy/win/ChangeLog	2020-04-08 22:38:33 UTC (rev 259761)
@@ -1,3 +1,17 @@
+2020-04-08  Daniel Bates  <[email protected]>
+
+        Should find touch-action elements inside non-composited iframes
+        https://bugs.webkit.org/show_bug.cgi?id=210041
+        <rdar://problem/61323558>
+
+        Reviewed by Simon Fraser.
+
+        Pass EventRegionContext through. It is unused as it's not applicable for plugin painting.
+
+        * Plugins/PluginView.h:
+        * Plugins/PluginViewWin.cpp:
+        (WebCore::PluginView::paint):
+
 2020-04-03  Alex Christensen  <[email protected]>
 
         Add SPI to make WKUserScripts wait for a notification

Modified: trunk/Source/WebKitLegacy/win/Plugins/PluginView.h (259760 => 259761)


--- trunk/Source/WebKitLegacy/win/Plugins/PluginView.h	2020-04-08 22:15:16 UTC (rev 259760)
+++ trunk/Source/WebKitLegacy/win/Plugins/PluginView.h	2020-04-08 22:38:33 UTC (rev 259761)
@@ -181,7 +181,7 @@
         void setFocus(bool) override;
         void show() override;
         void hide() override;
-        void paint(GraphicsContext&, const IntRect&, Widget::SecurityOriginPaintPolicy) override;
+        void paint(GraphicsContext&, const IntRect&, Widget::SecurityOriginPaintPolicy, EventRegionContext*) override;
         void clipRectChanged() override;
 
         // This method is used by plugins on all platforms to obtain a clip rect that includes clips set by WebCore,

Modified: trunk/Source/WebKitLegacy/win/Plugins/PluginViewWin.cpp (259760 => 259761)


--- trunk/Source/WebKitLegacy/win/Plugins/PluginViewWin.cpp	2020-04-08 22:15:16 UTC (rev 259760)
+++ trunk/Source/WebKitLegacy/win/Plugins/PluginViewWin.cpp	2020-04-08 22:38:33 UTC (rev 259761)
@@ -530,7 +530,7 @@
 #endif
 }
 
-void PluginView::paint(GraphicsContext& context, const IntRect& rect, Widget::SecurityOriginPaintPolicy)
+void PluginView::paint(GraphicsContext& context, const IntRect& rect, Widget::SecurityOriginPaintPolicy, EventRegionContext*)
 {
     if (!m_isStarted) {
         // Draw the "missing plugin" image
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to