Bug 4334

Summary: REGRESSION: Flickering when css-hover should change opacity on floating elements
Product: WebKit Reporter: Jonas Munk <jonasmunk>
Component: Layout and RenderingAssignee: Dave Hyatt <hyatt>
Status: RESOLVED FIXED    
Severity: Normal CC: alice.barraclough, bdakin, darin, hyatt, mitz
Priority: P1 Keywords: HasReduction, InRadar, Regression
Version: 420+   
Hardware: Mac   
OS: OS X 10.4   
URL: http://mezzoblue.com/tests/opacity/
Attachments:
Description Flags
Same file as the URL
none
Update the noPaint flag as necessary
none
Patch, including change log and pixel test
hyatt: review-
Patch, including change log and pixel test
darin: review+
Patch that fixes the mezzoblue version of this bug
mitz: review+
Test case to go with patch none

Description Jonas Munk 2005-08-08 06:20:46 PDT
When hovering over an element that has been assigned a css-float-value AND should change opacity it 
"flickers" instead.

See the URL for a minimal testcase.

The problem is found in Safari Version 2.0 (412.2). I remember that it worked in Safari 1.2 or so. I also 
remember seeing someone else found it as a regression on Hyatts old blog.

Hep hey - my first bug :-)
Comment 1 Mark Rowe (bdash) 2005-08-15 03:36:38 PDT
Confirmed with both Safari 412.2 and ToT WebKit.
Comment 2 Jonas Munk 2005-12-01 14:05:27 PST
Created attachment 4897 [details]
Same file as the URL

Attached the test just to be sure it doesn't go away.
Comment 3 Jonas Munk 2005-12-01 14:08:44 PST
Can anyone tell me if this bug has any priority or maybe it is dependant on some other actvity?
Comment 4 Maciej Stachowiak 2006-01-12 14:44:53 PST
It's unassigned, so no one is actively working on it. Priority would go up if it affects a major site, is shown 
to be a regression, otherwise become higher profile than standard.
Comment 5 Jonas Munk 2006-01-18 00:42:11 PST
I understand.

Actually I believe it is a regression (it worked a long time ago / when you first started supporting opacity) 
- but I'm unable to prove that :-)

As of nightly 2006-01-17 the problem no longer occurs on the news-box on jonasmunk.dk ("Nyheder").
But it still occurs on www.in2isoft.dk (the links in the top-right corner)
Comment 6 Dave Hyatt 2006-01-18 00:44:07 PST
Yeah I'm sure this is a regression.
Comment 7 Jonas Munk 2006-01-18 00:55:52 PST
Just tried it in different versions of OmniWeb. It worked in OmniWeb 5.1 - should be AppleWebKit/125.4 
according to http://www.omnigroup.com/applications/omniweb/developer/

Can be downloaded here: http://browsers.evolt.org/?omniweb/MacOSX/5.1

So I guess it's a regression
Comment 8 mitz 2006-01-18 09:11:32 PST
I think this is what's happening: when the float is first inserted into its containing block, because it's 
transparent it has a layer, and therefore the containing block sets noPaint to true. When it becomes 
opaque, it loses the layer but the containing block doesn't update the noPaint flag, so nobody paints the 
float.

I suspect that in the opposite situation, the float is painted twice.
Comment 9 Joost de Valk (AlthA) 2006-01-22 04:41:05 PST
Upping to P1 because this is a regression.
Comment 10 Darin Adler 2006-01-22 15:55:56 PST
I thin Mitz's analysis is right. But I couldn't figure out the right way to get the noDraw bit updated properly when a child's layer changes in RenderBox::setStyle. Need to talk to Dave about this one.
Comment 11 Alice Liu 2006-01-26 17:41:45 PST
<rdar://problem/4424077>
Comment 12 mitz 2006-06-05 16:38:57 PDT
Created attachment 8720 [details]
Update the noPaint flag as necessary

This is work in progress.
Comment 13 mitz 2006-06-06 07:52:15 PDT
Created attachment 8727 [details]
Patch, including change log and pixel test
Comment 14 Darin Adler 2006-06-06 09:50:46 PDT
Comment on attachment 8727 [details]
Patch, including change log and pixel test

This patch probably needs to be reviewed by Hyatt. I don't understand the issues well enough to review its behavior.

+                RenderObject* o = parent();
+                while (o && (!lastBlock || !o->layer())) {
+                    if (o->isRenderBlock())
+                        lastBlock = o;
+                    o = o->parent();
+                }

I think this reads better as a for loop.  I'd also make lastBlock be a RenderBlock* to put the cast to RenderBlock closer to the isRenderBlock call.

    for (RenderObject* o = parent(); o; o = o->parent()) {
        if (lastBlock && o->layer())
            break;
        if (o->isRenderBlock())
            lastBlock = static_cast<RenderBlock*>(o);
    }

For me, it's easier to see what the loop is doing in this form. And since this code appears twice, I think it should be factored out into a helper function. It probably doesn't need to be a member function.
Comment 15 Dave Hyatt 2006-06-06 12:23:17 PDT
Comment on attachment 8727 [details]
Patch, including change log and pixel test

r=me
Comment 16 Dave Hyatt 2006-06-06 12:33:34 PDT
Comment on attachment 8727 [details]
Patch, including change log and pixel test

Minusing so you can address Darin's comments.
Comment 17 mitz 2006-06-07 00:24:24 PDT
Created attachment 8745 [details]
Patch, including change log and pixel test

Addressed Darin's comments.
Comment 18 Darin Adler 2006-06-07 08:36:54 PDT
Comment on attachment 8745 [details]
Patch, including change log and pixel test

r=hyatt :-)
Comment 19 Darin Adler 2006-06-07 09:22:27 PDT
Committed revision 14759.
Comment 20 Dave Hyatt 2007-03-30 02:48:34 PDT
Reopening.

Comment 21 Dave Hyatt 2007-03-30 02:50:31 PDT
Created attachment 13886 [details]
Patch that fixes the mezzoblue version of this bug
Comment 22 Dave Hyatt 2007-03-30 02:51:14 PDT
Changed the URL field to the test case that fails.
Comment 23 Dave Hyatt 2007-03-30 03:00:39 PDT
Created attachment 13887 [details]
Test case to go with patch
Comment 24 mitz 2007-03-30 03:00:59 PDT
Comment on attachment 13886 [details]
Patch that fixes the mezzoblue version of this bug

I'm told there's a test to go with this patch, so r=me!
Comment 25 Dave Hyatt 2007-03-30 03:07:58 PDT
Fixed in r20609.