Closed Bug 331880 Opened 18 years ago Closed 18 years ago

[FIX]nsStackLayout::Layout(..) 's redraw logic is not entirely correct.

Categories

(Core :: XUL, defect, P1)

defect

Tracking

()

RESOLVED FIXED
mozilla1.9alpha1

People

(Reporter: lihster, Assigned: bzbarsky)

References

Details

(Keywords: fixed1.8.1, regression, testcase)

Attachments

(2 files)

User-Agent:       Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.0.1) Gecko/20060111 Firefox/1.5.0.1
Build Identifier: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.0.1) Gecko/20060111 Firefox/1.5.0.1

Inside nsStackLayout::Layout(nsIBox* aBox, nsBoxLayoutState &aState) method in layout/xul/base/src/nsStackLayout.cpp, the box is redrawn if and only if childRect's top coordinate(y) is not equal to its original top position or the similar discrepancy appears in it's left coordinate(x). 

If a box is resized in the S, SE, or E direction, the affected region is not invalidated; hence, you will see a trail of the resizing activity.

My Fix: 
change the line 
if(childRect.x != oldRect.x || childRect.y != oldRect.y) 
to
if(childRect!=oldRect)

I would love to disclose my xul/js source that would reproduce this problem everytime. However, this is an enterprise sw. 


Reproducible: Always

Steps to Reproduce:
1. Write a xul document with a stack. Inside the stack, have a box. 
2. Inside a js associated with a stack, capture mousedown, mousemove, mouseup event for moving and resize of a box.
3. drag to resize the south or east edge of the box and you shall see.

Actual Results:  
You will see the trace of your resizing activity if you reduce the size of the box. 

Expected Results:  
If you resize the box in the north direction, you will see that gecko invalidate the affected region correctly. We should expect the same for all the other edges as well.

I just download the most recent source tarball off  from ftp://ftp.mozilla.org/pub/mozilla.org/mozilla/nightly/latest-trunk/. I am still seeing the same line of code, though I haven't recompile the source and test against that source. 

Free feel to contact me at lihster@gmail.com. Thank you.
Could you attach a minimal testcase that shows the bug?
Assignee: guifeatures → nobody
Component: XP Apps: GUI Features → Layout: Misc Code
Product: Mozilla Application Suite → Core
QA Contact: layout.misc-code
Version: unspecified → Trunk
Attached file testcase
Testcase that shows the bug, you should see no red in the testcase.
Thanks for showing me the extension, Lih. That allowed me to create this testcase.
Assignee: nobody → roc
Status: UNCONFIRMED → NEW
Component: Layout: Misc Code → Layout: View Rendering
Ever confirmed: true
Keywords: testcase
QA Contact: layout.misc-code → ian
Assignee: roc → nobody
Component: Layout: View Rendering → XP Toolkit/Widgets: XUL
QA Contact: ian → xptoolkit.xul
Sorry, mid-air collision at work.
Component: Layout: View Rendering → XP Toolkit/Widgets: XUL
roc, it looks liks nsSprocketLayout calls SetBounds() in a bunch of places but never calls Invalidate().  And nsBox::SetBounds() also doesn't invalidate.

If I recall correctly, invalidating a child that gets resized  (or rather the difference between new and old areas) is the responsibility of the thing doing the resizing, right?
Attached patch FixSplinter Review
Assignee: nobody → bzbarsky
Status: NEW → ASSIGNED
Attachment #220076 - Flags: superreview?(roc)
Attachment #220076 - Flags: review?(roc)
Attachment #220076 - Flags: approval-branch-1.8.1?(roc)
OS: Windows XP → All
Priority: -- → P1
Hardware: PC → All
Summary: nsStackLayout::Layout(..) 's redraw logic is not entirely correct. → [FIX]nsStackLayout::Layout(..) 's redraw logic is not entirely correct.
Target Milestone: --- → mozilla1.9alpha
Attachment #220076 - Flags: superreview?(roc)
Attachment #220076 - Flags: superreview+
Attachment #220076 - Flags: review?(roc)
Attachment #220076 - Flags: review+
Attachment #220076 - Flags: approval-branch-1.8.1?(roc)
Attachment #220076 - Flags: approval-branch-1.8.1+
Fixed, and on branch.
Status: ASSIGNED → RESOLVED
Closed: 18 years ago
Keywords: fixed1.8.1
Resolution: --- → FIXED
I'm a little surprised that this added 174 bytes of codesize on prometheus; that seems like a lot for such a small patch.
Two things got added, basically:

  childRectNoMargin = childRect

which ends up compiler-generated; presumably 4 assignments inlined?

  childRectNoMargin != oldRect

instead of two compares.  This inlines the following:

138   PRBool  operator==(const nsRect& aRect) const {
139     return (PRBool) ((IsEmpty() && aRect.IsEmpty()) ||
140                      ((x == aRect.x) && (y == aRect.y) &&
141                       (width == aRect.width) && (height == aRect.height)));
142   }

(with a "!" tossed on the whole thing).  IsEmpty() is also inlined.  So instead of two compares we now have 8, plus more logic connecting them....

Not sure whether that's enough to give that big an increase, of course.
Might be interesting to try un-inlining nsRect::== globally to see what that does to codesize.
Component: XP Toolkit/Widgets: XUL → XUL
QA Contact: xptoolkit.xul → xptoolkit.widgets
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: