WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
Bug 116994
Setting overflow:hidden does not always repaint clipped content.
https://bugs.webkit.org/show_bug.cgi?id=116994
Summary
Setting overflow:hidden does not always repaint clipped content.
Luis de Bethencourt
Reported
2013-05-29 13:47:21 PDT
Created
attachment 203271
[details]
simple testcase When updating an inline element, the browser does not redraw the screen until a block-level change happens in the DOM, frame is scrolled or window is resized. I have searched around online and seen many web developers having this problem and forcing a refresh to work around it. By changing the zoom level to 1.1 and back to 1.0, by using eloffsetHeight in the element, or with el.hide().show(). I have added a simple testcase to easily reproduce the bug. This has been happening for some time, as can be seen in the following pages:
http://stackoverflow.com/questions/3485365/how-can-i-force-webkit-to-redraw-repaint-to-propagate-style-changes
http://mir.aculo.us/2009/09/25/force-redraw-dom-technique-for-webkit-based-browsers/
https://gist.github.com/madrobby/1362093
Attachments
simple testcase
(1.23 KB, text/html)
2013-05-29 13:47 PDT
,
Luis de Bethencourt
no flags
Details
Patch
(6.06 KB, patch)
2013-05-31 04:37 PDT
,
Yuki Sekiguchi
no flags
Details
Formatted Diff
Diff
Patch
(7.62 KB, patch)
2013-06-04 00:47 PDT
,
Yuki Sekiguchi
no flags
Details
Formatted Diff
Diff
Patch
(6.64 KB, patch)
2013-06-09 20:20 PDT
,
Yuki Sekiguchi
no flags
Details
Formatted Diff
Diff
Patch
(6.52 KB, patch)
2013-06-10 22:19 PDT
,
Yuki Sekiguchi
no flags
Details
Formatted Diff
Diff
Narrowed content for WebInspector selection problem
(602 bytes, text/html)
2013-06-18 19:51 PDT
,
Yuki Sekiguchi
no flags
Details
Patch
(8.73 KB, patch)
2013-06-19 22:49 PDT
,
Yuki Sekiguchi
no flags
Details
Formatted Diff
Diff
Test reduction
(468 bytes, text/html)
2016-05-25 09:47 PDT
,
zalan
no flags
Details
Test reduction
(470 bytes, text/html)
2016-05-25 09:49 PDT
,
zalan
no flags
Details
Patch
(4.77 KB, patch)
2016-05-25 13:37 PDT
,
zalan
no flags
Details
Formatted Diff
Diff
Patch
(4.86 KB, patch)
2016-05-25 14:45 PDT
,
zalan
no flags
Details
Formatted Diff
Diff
Show Obsolete
(7)
View All
Add attachment
proposed patch, testcase, etc.
Simon Fraser (smfr)
Comment 1
2013-05-29 14:16:15 PDT
This seems to be a repaint issue overflow and position (nothing to do with inlines).
Luis de Bethencourt
Comment 2
2013-05-29 14:19:53 PDT
Simon, have you looked at the links? Unless I'm missunderstanding things this overflow issue is just an example of undrawn propagated style changes. Correct me if I'm wrong. Unfortunately the links have code snippet but not a full example to attach here.
Simon Fraser (smfr)
Comment 3
2013-05-29 21:00:03 PDT
I looked at the links. It's quite possible that every link is talking about a different bug; unless we get specific reports with tests, it's hard to generalize.
Luis de Bethencourt
Comment 4
2013-05-30 08:09:33 PDT
I understand, I will try to write more tests. Any idea why the overflow and position bug happens?
Yuki Sekiguchi
Comment 5
2013-05-31 04:37:16 PDT
Created
attachment 203434
[details]
Patch
Yuki Sekiguchi
Comment 6
2013-05-31 04:42:44 PDT
As Simon says, we don't have general test case, so we cannot fix all bugs. I try to fix a bug of this simple testcase. I think a cause of this bug is very rare condition, so my patch doen't fix many issues. If you find another repaint problem, please file another bug.
Robert Hogan
Comment 7
2013-06-02 02:51:52 PDT
Comment on
attachment 203434
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=203434&action=review
Seems like a nice catch!
> Source/WebCore/rendering/RenderBox.cpp:2036 > + if (!hasSelfPaintingLayer() && o->hasOverflowClip()) {
This pattern pops up in a couple of other places too. Why not make a helper called shouldUseOverflowClip() or similar - that would also be a good place to add a comment about why we only need to worry about clipping on layers that aren't self-painting, something from the Changelog in
r41203
for example. I say this because I had to dig around a bit to find out for myself. You also need to fix this function in RenderObject.
Simon Fraser (smfr)
Comment 8
2013-06-02 09:27:43 PDT
Comment on
attachment 203434
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=203434&action=review
> Source/WebCore/rendering/RenderBox.cpp:2034 > + // If this RenderBox has self painting layer, visial overflow clip of "o" doesn't contain a rect of the RenderBox.
"visial" -> "visual"
> Source/WebCore/rendering/RenderBox.cpp:2035 > + // Clipping this painting rect make the rect narrower.
Not sure what you mean here.
Yuki Sekiguchi
Comment 9
2013-06-04 00:47:40 PDT
Created
attachment 203661
[details]
Patch
Yuki Sekiguchi
Comment 10
2013-06-04 05:26:46 PDT
Hi Robert, (In reply to
comment #7
)
> (From update of
attachment 203434
[details]
) > View in context:
https://bugs.webkit.org/attachment.cgi?id=203434&action=review
> > Seems like a nice catch! > > > Source/WebCore/rendering/RenderBox.cpp:2036 > > + if (!hasSelfPaintingLayer() && o->hasOverflowClip()) { > > This pattern pops up in a couple of other places too. Why not make a helper called shouldUseOverflowClip() or similar - that would also be a good place to add a comment about why we only need to worry about clipping on layers that aren't self-painting, something from the Changelog in
r41203
for example. I say this because I had to dig around a bit to find out for myself. > > You also need to fix this function in RenderObject.
I found two method using this pattern, but all of them (including my patch) check different conditions. * RenderBlock::nodeAtPoint() want probability that children overflow, so it only checks whether it clips children or not. * RenderBox::addOverflowFromChild() want to know it should add a child to its visual overflow, so it checks that it has overflow clip (never overflow) and it should contain the child as visual overflow(if the child have self painting layer, it never overflow). * My patch checks that parent contains it as visual overflow. Yes. We can rewrite addOverflowFromChild() to the following:
> if ((!child->hasSelfPaintingLayer() && hasOverflowClip()) || child->hasSelfPaintingLayer())
Then, we can refactor the code to use helper function. However, I think original code is more clear than refactored code.
Yuki Sekiguchi
Comment 11
2013-06-04 05:27:48 PDT
Hi Simon, (In reply to
comment #8
)
> (From update of
attachment 203434
[details]
) > View in context:
https://bugs.webkit.org/attachment.cgi?id=203434&action=review
> > > Source/WebCore/rendering/RenderBox.cpp:2034 > > + // If this RenderBox has self painting layer, visial overflow clip of "o" doesn't contain a rect of the RenderBox. > > "visial" -> "visual"
Fixed.
> > > Source/WebCore/rendering/RenderBox.cpp:2035 > > + // Clipping this painting rect make the rect narrower. > > Not sure what you mean here.
Changed a sentence.
Yuki Sekiguchi
Comment 12
2013-06-04 05:35:08 PDT
(In reply to
comment #10
)
> Hi Robert, > > (In reply to
comment #7
) > > (From update of
attachment 203434
[details]
[details]) > > View in context:
https://bugs.webkit.org/attachment.cgi?id=203434&action=review
> > > > Seems like a nice catch! > > > > > Source/WebCore/rendering/RenderBox.cpp:2036 > > > + if (!hasSelfPaintingLayer() && o->hasOverflowClip()) { > > > > This pattern pops up in a couple of other places too. Why not make a helper called shouldUseOverflowClip() or similar - that would also be a good place to add a comment about why we only need to worry about clipping on layers that aren't self-painting, something from the Changelog in
r41203
for example. I say this because I had to dig around a bit to find out for myself. > > > > You also need to fix this function in RenderObject. > > I found two method using this pattern, but all of them (including my patch) check different conditions. > * RenderBlock::nodeAtPoint() want probability that children overflow, so it only checks whether it clips children or not. > * RenderBox::addOverflowFromChild() want to know it should add a child to its visual overflow, so it checks that it has overflow clip (never overflow) and it should contain the child as visual overflow(if the child have self painting layer, it never overflow). > * My patch checks that parent contains it as visual overflow. > > Yes. We can rewrite addOverflowFromChild() to the following: > > if ((!child->hasSelfPaintingLayer() && hasOverflowClip()) || child->hasSelfPaintingLayer()) > Then, we can refactor the code to use helper function. > However, I think original code is more clear than refactored code.
I forgot to added the following... However, making condition more clear using method is good! I added the method.
Simon Fraser (smfr)
Comment 13
2013-06-06 17:27:33 PDT
Comment on
attachment 203661
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=203661&action=review
> Source/WebCore/ChangeLog:18 > + In the reproduced content, overflow:hidden parent(called P) has display:none replaced child(called C). > + If we hover a element, P becomes overflow:visible, and C becomes display:block. > + If we mouse out from the element, P becomes hidden, and C becomes none, and part of C is not repainted. > + > + When we mouse out from the element, P and C request repaint. > + Before requesting repaint, P becomes overflow: hidden, and it makes hasOverflowClip() true. > + Requesting repaint from C is clipped by P at RenderBox::computeRectForRepaint(). > + The rect which P requests repaint is content rect of P, so the rect which is overflowed from P is not requested. > + > + If C is not relative, visual overflow rect of P has the rect of C, so we can repaint well. > + If C doesn't become display:none, layouting C requests repaint the rect of C, so we can repaint well.
I don't think this long explanation is necessary.
> Source/WebCore/rendering/RenderLayerModelObject.cpp:82 > + return !hasSelfPaintingLayer() && container->hasOverflowClip();
You should ASSERT that o is the container.
> LayoutTests/fast/repaint/change-overflow-and-display-of-relative-expected.html:2 > +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
Don't need the <meta> tag.
> LayoutTests/fast/repaint/change-overflow-and-display-of-relative.html:32 > + }, 50);
Can this be < 50ms?
Yuki Sekiguchi
Comment 14
2013-06-09 20:20:10 PDT
Created
attachment 204133
[details]
Patch
Yuki Sekiguchi
Comment 15
2013-06-09 20:28:09 PDT
(In reply to
comment #13
)
> (From update of
attachment 203661
[details]
) > View in context:
https://bugs.webkit.org/attachment.cgi?id=203661&action=review
> > > Source/WebCore/ChangeLog:18 > > + In the reproduced content, overflow:hidden parent(called P) has display:none replaced child(called C). > > + If we hover a element, P becomes overflow:visible, and C becomes display:block. > > + If we mouse out from the element, P becomes hidden, and C becomes none, and part of C is not repainted. > > + > > + When we mouse out from the element, P and C request repaint. > > + Before requesting repaint, P becomes overflow: hidden, and it makes hasOverflowClip() true. > > + Requesting repaint from C is clipped by P at RenderBox::computeRectForRepaint(). > > + The rect which P requests repaint is content rect of P, so the rect which is overflowed from P is not requested. > > + > > + If C is not relative, visual overflow rect of P has the rect of C, so we can repaint well. > > + If C doesn't become display:none, layouting C requests repaint the rect of C, so we can repaint well. > > I don't think this long explanation is necessary.
Removed.
> > > Source/WebCore/rendering/RenderLayerModelObject.cpp:82 > > + return !hasSelfPaintingLayer() && container->hasOverflowClip(); > > You should ASSERT that o is the container.
Added.
> > > LayoutTests/fast/repaint/change-overflow-and-display-of-relative-expected.html:2 > > +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> > > Don't need the <meta> tag.
Removed, and added closing tag of head.
> > > LayoutTests/fast/repaint/change-overflow-and-display-of-relative.html:32 > > + }, 50); > > Can this be < 50ms?
No, this can't. I tried 0ms and used "overflow.offsetHeight;" to force to redraw. However, if I open this test from Finder, the problem is sometimes not reproduced. I think 1st drawing is combined with 2nd drawing.
Simon Fraser (smfr)
Comment 16
2013-06-09 22:05:17 PDT
(In reply to
comment #15
)
> > > > > LayoutTests/fast/repaint/change-overflow-and-display-of-relative.html:32 > > > + }, 50); > > > > Can this be < 50ms? > > No, this can't. > I tried 0ms and used "overflow.offsetHeight;" to force to redraw. > However, if I open this test from Finder, the problem is sometimes not reproduced. > I think 1st drawing is combined with 2nd drawing.
If it's this timing sensitive on your machine, it's likely it will fail on a bot, or EWS. You should try to find a way to make the test reliable with a setTimeout. Does testRunner.display() help? Thinking about the test some more, I think it should not be a ref test, and instead be a repaint test. See tests that call repaintRectsAsText.
Yuki Sekiguchi
Comment 17
2013-06-10 22:19:59 PDT
Created
attachment 204286
[details]
Patch
Yuki Sekiguchi
Comment 18
2013-06-11 04:20:07 PDT
Hi Simon, (In reply to
comment #16
)
> (In reply to
comment #15
) > > > > > > > LayoutTests/fast/repaint/change-overflow-and-display-of-relative.html:32 > > > > + }, 50); > > > > > > Can this be < 50ms? > > > > No, this can't. > > I tried 0ms and used "overflow.offsetHeight;" to force to redraw. > > However, if I open this test from Finder, the problem is sometimes not reproduced. > > I think 1st drawing is combined with 2nd drawing. > > If it's this timing sensitive on your machine, it's likely it will fail on a bot, or EWS. You should try to find a way to make the test reliable with a setTimeout. Does testRunner.display() help? > > Thinking about the test some more, I think it should not be a ref test, and instead be a repaint test. See tests that call repaintRectsAsText.
testRunner.display() doesn't work well for pixel and ref test, but it works well for text based repaint test. Therefore, I changed the test to use repaintRectsAsText for DumpRenderTree and setTimeout() for Safari. Could you review this?
WebKit Commit Bot
Comment 19
2013-06-13 08:37:20 PDT
Comment on
attachment 204286
[details]
Patch Clearing flags on attachment: 204286 Committed
r151549
: <
http://trac.webkit.org/changeset/151549
>
WebKit Commit Bot
Comment 20
2013-06-13 08:37:23 PDT
All reviewed patches have been landed. Closing bug.
Simon Fraser (smfr)
Comment 21
2013-06-18 10:31:24 PDT
This broke selection painting in the web inspector source view. I'm going to revert it.
WebKit Commit Bot
Comment 22
2013-06-18 10:33:24 PDT
Re-opened since this is blocked by
bug 117741
Yuki Sekiguchi
Comment 23
2013-06-18 19:51:50 PDT
Created
attachment 204963
[details]
Narrowed content for WebInspector selection problem
Yuki Sekiguchi
Comment 24
2013-06-18 19:52:56 PDT
Thank you for reverting. I created narrowed content for WebInspector selection problem. I'll investigate it and fix it.
Yuki Sekiguchi
Comment 25
2013-06-19 22:49:18 PDT
Created
attachment 205060
[details]
Patch
Alexey Proskuryakov
Comment 26
2013-06-20 10:46:02 PDT
The previous patch also broke beta.icloud.com,
bug 117743
. Could you please test that, too?
Alexey Proskuryakov
Comment 27
2013-06-20 10:50:14 PDT
And
bug 117739
, too.
Yuki Sekiguchi
Comment 28
2013-06-20 20:07:02 PDT
Hi Alexey, (In reply to
comment #26
)
> The previous patch also broke beta.icloud.com,
bug 117743
. Could you please test that, too?
Hmm.. I could not sign in to beta.icloud.com. It says "Developer Account Required" and "Using beta.icloud.com requires a developer Apple ID that has been set up on the latest version of iOS or OS X." I use iCloud on MacOS X 10.8.4 and iOS 6.1.3 and have free developer account. i.e. I can download old Xcode. Do I need iOS 7 or paid developer account to use beta.icloud.com ?
Yuki Sekiguchi
Comment 29
2013-07-01 02:13:49 PDT
I could sign in beta.icloud.com and reproduced those bugs on old Safari. I confirmed that new patch fixed those bugs.
Radu Stavila
Comment 30
2014-05-29 04:38:52 PDT
Comment on
attachment 205060
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=205060&action=review
> Source/WebCore/rendering/RenderLayerModelObject.cpp:80 > +bool RenderLayerModelObject::shouldUseClipForRepaint(RenderObject* container) const
this->container() is RenderElement, so the paramater passed to this function should also be RenderElemenet.
Brady Eidson
Comment 31
2016-05-24 22:01:06 PDT
Comment on
attachment 205060
[details]
Patch Assuming that patches for review since 2013 are stale, r-
zalan
Comment 32
2016-05-25 09:47:47 PDT
Created
attachment 279779
[details]
Test reduction
zalan
Comment 33
2016-05-25 09:49:07 PDT
Created
attachment 279780
[details]
Test reduction
zalan
Comment 34
2016-05-25 13:32:12 PDT
rdar://problem/26476697
zalan
Comment 35
2016-05-25 13:37:10 PDT
Created
attachment 279802
[details]
Patch
Dave Hyatt
Comment 36
2016-05-25 13:50:29 PDT
Comment on
attachment 279802
[details]
Patch r=me, but I think you need to explain why this code is necessary. It's because repaints issued by the removal of descendants before layout() gets called to updateLayerPositions (which would have issued the right repaints) use the updated style and so clip when they shouldn't. This is why overflow changes have to result in immediate repaints of the entire layout overflow area.
zalan
Comment 37
2016-05-25 14:45:56 PDT
Created
attachment 279819
[details]
Patch
WebKit Commit Bot
Comment 38
2016-05-25 16:00:42 PDT
Comment on
attachment 279819
[details]
Patch Clearing flags on attachment: 279819 Committed
r201407
: <
http://trac.webkit.org/changeset/201407
>
WebKit Commit Bot
Comment 39
2016-05-25 16:00:50 PDT
All reviewed patches have been landed. Closing bug.
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug