Skip to content

Commit

Permalink
REGRESSION (r294902): Overflowed area is not repainted when just chan…
Browse files Browse the repository at this point in the history
…ged to "hidden".

https://bugs.webkit.org/show_bug.cgi?id=246203
<rdar://problem/100901132>

Reviewed by Simon Fraser.

1. When a layer has "full repaint" flag set we skip any subsequent repaint requests on the associated renderer and on any of its descendants because we know that the layer would eventually issue a repaint on the enclosing rect after layout.
2. This "full repaint" produces a damaged rect based on the layer's (associated renderer) overflow status.

This works fine as long as we don't try to repaint the overflown area while also changing the renderer's overflow property from visible to hidden.
In such cases all incoming repaint requests will either be
1. clipped to the non-overflown area of the renderer (forced repaint) or
2. simply ignored as the associated layer already has the "full repaint" flag set.

This patch ensures that such style change always triggers repaint on the overflown content as well.

* LayoutTests/fast/repaint/incorrect-repaint-when-container-changes-from-overflow-visible-to-hidden-expected.txt: Added.
* LayoutTests/fast/repaint/incorrect-repaint-when-container-changes-from-overflow-visible-to-hidden.html: Added.
* Source/WebCore/rendering/RenderBox.cpp: Send forced repaint so that we don't delay issuing the repaint after layout when the renderer's overflow is already "hidden". Otherwise these 2 repaints get ignored and by the time we issue the repaint (layer, after layout) the damaged rect is computed with clipping applied.

(WebCore::RenderBox::updateFromStyle):
* Source/WebCore/rendering/RenderObject.cpp:
(WebCore::RenderObject::issueRepaint const):

Canonical link: https://commits.webkit.org/255312@main
  • Loading branch information
alanbaradlay committed Oct 8, 2022
1 parent 3127e0a commit 3cf19dc
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 2 deletions.
@@ -0,0 +1,8 @@
(repaint rects
(rect 8 8 50 50)
(rect 8 8 100 100)
(rect 8 8 50 50)
(rect 8 8 50 50)
(rect 8 8 50 50)
)

@@ -0,0 +1,26 @@
<style>
#container {
overflow: visible;
position: relative;
width: 50px;
height: 50px;
background-color: green;
}

#abs {
position: absolute;
background-color: red;
width: 100px;
height: 100px;
}

</style>
<div id=container><div id=abs></div></div>
<script src="resources/text-based-repaint.js" type="text/javascript"></script>
<script>
repaintTest = function() {
abs.style.display = "none";
container.style.overflow = "hidden";
};
runRepaintTest();
</script>
4 changes: 2 additions & 2 deletions Source/WebCore/rendering/RenderBox.cpp
Expand Up @@ -529,8 +529,8 @@ void RenderBox::updateFromStyle()
// Erase the overflow.
// Overflow changes have to result in immediate repaints of the entire layout overflow area because
// repaints issued by removal of descendants get clipped using the updated style when they shouldn't.
repaintRectangle(visualOverflowRect());
repaintRectangle(layoutOverflowRect());
issueRepaint(visualOverflowRect(), ClipRepaintToLayer::Yes, ForceRepaint::Yes);
issueRepaint(layoutOverflowRect(), ClipRepaintToLayer::Yes, ForceRepaint::Yes);
}
setHasNonVisibleOverflow();
}
Expand Down

0 comments on commit 3cf19dc

Please sign in to comment.