Closed Bug 596955 Opened 14 years ago Closed 14 years ago

[OS X] [OpenGL] Painting errors while resizing window using nsIWidget::Resize, causing Preferences window to flicker when switching between preference tabs


(Core :: Graphics, defect)

Not set



Tracking Status
blocking2.0 --- final+


(Reporter: mstange, Assigned: mstange)




(2 files)

When Gecko causes a window to be resized to a smaller size, the window briefly shows garbage. This can be reproduced in the preferences window by switching panes, or using by typing javascript:resizeTo(800,600) into the URL bar (and allowing JavaScript to resize existing windows).

I can't reproduce the bug using the native window resizer, so it's probably something in nsCocoaWindow::Resize - maybe we're changing mBounds at the wrong time or something like that.
blocking2.0: --- → ?
When do we run into this?
When switching between panes in the Firefox preferences window, for example.
I see some white flickering when we the preferences window gets smaller. The precise behaviour probably depends on OS X version or driver or something.

Matt, would you like to look into this?
Assignee: nobody → matt.woodrow+bugzilla
blocking2.0: ? → final+
Summary: [OS X] [OpenGL] Painting errors while resizing window using nsIWidget::Resize → [OS X] [OpenGL] Painting errors while resizing window using nsIWidget::Resize, causing Preferences window to flicker when switching between preference tabs
I see the same in Thunderbird trunk (32bit) if I change from one tab to another in the preferences.
OS: Mac OS X → Windows 7
OS: Windows 7 → Mac OS X
Not sure if I know enough about cocoa for this.

The garbage happens approximately here:

#0  0x00007fff82e539e2 in mach_msg ()
#1  0x00007fff819232af in -[NSSurface setFrame:] ()
#2  0x00007fff81922d9c in -[NSSurface syncToViewUnconditionally] ()
#3  0x00007fff81924c8d in -[NSSurface syncToView:] ()
#4  0x00007fff8182ff51 in -[NSView _invalidateGStatesForTree] ()
#5  0x00007fff8182fc98 in -[NSView _invalidateFocus] ()
#6  0x00007fff8182a682 in -[NSView setFrameSize:] ()
#7  0x00007fff8182a19a in -[NSView setFrame:] ()
#8  0x0000000101364ee2 in nsChildView::Resize (this=0x12526dad0, aX=0, aY=0, aWidth=613, aHeight=414, aRepaint=0) at /Users/mattwoodrow/mozilla-central2/widget/src/cocoa/
#9  0x0000000100323db5 in DocumentViewerImpl::SetBounds (this=0x1251f6d20, aBounds=@0x1296e4bf0) at /Users/mattwoodrow/mozilla-central2/layout/base/nsDocumentViewer.cpp:1871
#10 0x0000000100fc3b37 in nsDocShell::SetPositionAndSize (this=0x1296e4a20, x=0, y=0, cx=613, cy=414, fRepaint=0) at /Users/mattwoodrow/mozilla-central2/docshell/base/nsDocShell.cpp:4592
#11 0x0000000101092f3f in nsWebShellWindow::HandleEvent (aEvent=0x7fff5fbfa830) at /Users/mattwoodrow/mozilla-central2/xpfe/appshell/src/nsWebShellWindow.cpp:357
#12 0x0000000101349a67 in nsCocoaWindow::DispatchEvent (this=0x12525d7d0, event=0x7fff5fbfa830, aStatus=@0x7fff5fbfa8ec) at /Users/mattwoodrow/mozilla-central2/widget/src/cocoa/
#13 0x000000010134ee20 in nsCocoaWindow::ReportSizeEvent (this=0x12525d7d0, r=0x7fff5fbfa9a0) at /Users/mattwoodrow/mozilla-central2/widget/src/cocoa/
#14 0x000000010134f4bb in nsCocoaWindow::Resize (this=0x12525d7d0, aX=460, aY=163, aWidth=613, aHeight=436, aRepaint=1) at /Users/mattwoodrow/mozilla-central2/widget/src/cocoa/
#15 0x000000010134f2ae in nsCocoaWindow::Resize (this=0x12525d7d0, aWidth=613, aHeight=436, aRepaint=1) at /Users/mattwoodrow/mozilla-central2/widget/src/cocoa/

And then we repaint at the end of nsCocoaWindow::Resize and it renders correctly.

The strip of garbage appears to be about the size that we are reducing the view by. Cocoa native coordinates use 0,0 at the bottom left don't they? Looks like its somehow invalidating the strip along the top that's now no longer part of the view before moving it up.
So the root cause is that we're calling [NSView setFrame:] before the actual NSWindow resize. I think we can just stop doing that.
Attached patch v1Splinter Review
This backs out most of bug 355177. Calling nsCocoaWindow::Resize now basically comes down to a single [mWindow setFrame:] call, which then goes the same path as regular window resizing caused by dragging the resizer.

The first ReportSizeEvent call can be removed because the comment is no longer true: The NSView won't be briefly shown at a wrong position. It might have at the time when this code was added, but it sure doesn't now - otherwise we'd also see that phenomenon during normal user resizing.

The StartResizing/StopResizing/IsResizing guards can be removed because the ReportSizeEvent call has been removed. The guards prevented windowDidResize from firing a duplicate size event, but in the new world that event will be the only one that's sent.

The second ReportSizeEvent call can be removed because the size event that will be sent by windowDidResize will already carry the right dimensions.

I've pushed this patch to the tryserver, let's see what it says.
Assignee: matt.woodrow+bugzilla → mstange
Attachment #492962 - Flags: review?(joshmoz)
All tests passed on tryserver.
Attachment #492962 - Flags: review?(joshmoz) → review+
Closed: 14 years ago
Resolution: --- → FIXED
Backed out for causing crash tests on OSX to go permanently orange.
Resolution: FIXED → ---
This patch can probably re-land after the tree opens, it looks like it wasn't the cause of the crashtest failures after all.
Closed: 14 years ago14 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla2.0b8
You need to log in before you can comment on or make changes to this bug.