Closed
Bug 372003
Opened 17 years ago
Closed 17 years ago
Camino should remove tracking rects in viewWillMoveToWindow
Categories
(Camino Graveyard :: General, defect)
Tracking
(Not tracked)
RESOLVED
FIXED
Camino1.6
People
(Reporter: smichaud, Assigned: stuart.morgan+bugzilla)
References
()
Details
(Keywords: fixed1.8.1.5)
Attachments
(2 files)
2.67 KB,
patch
|
jaas
:
review+
mikepinkerton
:
superreview+
|
Details | Diff | Splinter Review |
2.92 KB,
patch
|
jaas
:
review+
mikepinkerton
:
superreview+
|
Details | Diff | Splinter Review |
Cocoa supports the use of tracking rectangles to help keep track of where the mouse is located -- it sends mouse-entered and mouse-exited events whenever the mouse enters or exits one of these "tracking rects". The NSView class contains methods to add and remove tracking rects (addTrackingRect and removeTrackingRect). But the actual list of an NSView's tracking rects is stored in the NSWindow object to whose view hierachy the NSView object belongs. So it's very important to remove an NSView object's tracking rects when it's about to be deleted -- otherwise the NSWindow will keep sending it mouse-entered and mouse-exited events, and crashes will result. And it's also important to call removeTrackingRect on an NSView object before it has been removed from it's NSWindow's view hierarchy -- otherwise the call to removeTrackingRect will have no effect (since the OS no longer knows which NSWindow the NSView was attached to). Intuitively, you'd think you should call removeTrackingRect when an NSView object receives a removeFromSuperview message. But I know from personal experience that removeFromSuperview is sometimes called after the NSView object has been removed from its NSWindow. Apple has given a number of (coy and indirect) hints that it's best to call removeTrackingRect from viewWillMoveToWindow. This works for me (I call removeTrackingRect when viewWillMoveToWindow is called with its newWindow parameter set to nil). In Apple's chapter on handling mouse tracking events (http://developer.apple.com/documentation/Cocoa/Conceptual/EventOverview/MouseTrackingEvents/chapter_7_section_2.html), listing 6-4 shows removeTrackingRect being called from viewWillMoveToWindow, as an example of "removing a tracking rectangle when a view is removed from its window". In Apple's WebKit, removeTrackingRect is called from the viewWillMoveToWindow method of the WebBaseNetscapePluginView class. And above this call there's the following comment -- "We must remove the tracking rect before we move to the new window. Once we move to the new window, it will be too late." Cocoa widgets seems to handle this properly -- removeTrackingRect gets called from nsChildView's viewWillMoveToWindow method. But Camino doesn't. On the trunk, Camino calls removeTrackingRect from RolloverImageButton's removeFromSuperview method. And on the 1.8 branch Camino doesn't make any attempt to call removeTrackingRect as an NSView object that might "contain" tracking rects is being destroyed (the code seems to assume that these tracking rects will always already have been removed by other means). In my experience, crashes due to leftover tracking rects (ones that still exist after their NSView object has been deleted) always take place in [NSWindow sendEvent:]. A couple of examples that I've seen recently have the following at the top of the thread 0 stack trace: Exception: EXC_BAD_ACCESS (0x0001) Codes: KERN_INVALID_ADDRESS (0x0001) at 0xa1b1c1f3 Thread 0 Crashed: 0 <<00000000>> 0xfffeff18 objc_msgSend_rtp + 24 1 com.apple.AppKit 0x93768fa0 -[NSWindow sendEvent:] + 6424 ... The crashes I saw were on OS X 10.4.8 in Camino 1.1b (there were two in quick succession), while I had four or five tabs open (each containing at least one Java applet), with the map24.com in the current tab, while I was resizing the browser window. At first I thought this might be a JEP bug. But I recognized the "lost tracking rect crash" signature. And I found out that, while Apple's JVM also uses tracking rects, it seems to always remove them correctly (it seems to always call removeTrackingRect from viewWillMoveToWindow). I've found my crashes very difficult to reproduce -- I haven't seen any more since the first two. But I've noticed several other BMO bugs that might be caused by "lost tracking rects" -- particularly bug 370954. (Some other possibilities are bug 371550 and bug 359488.)
Assignee | ||
Comment 1•17 years ago
|
||
(In reply to comment #0) > Intuitively, you'd think you should call removeTrackingRect when an > NSView object receives a removeFromSuperview message. But I know from > personal experience that removeFromSuperview is sometimes called after > the NSView object has been removed from its NSWindow. Nice. Thanks for the tip; I knew we were chasing a tracking rect problem in bug 370954, but I added new guards in the wrong place. I really should have thought to go back and look at that doc again, but I didn't. I'll make a new patch to do the right thing. > On the trunk, Camino calls removeTrackingRect from > RolloverImageButton's removeFromSuperview method. And on the 1.8 > branch Camino doesn't make any attempt to call removeTrackingRect as > an NSView object that might "contain" tracking rects is being > destroyed (the code seems to assume that these tracking rects will > always already have been removed by other means). Could you elaborate here? If we are talking just about RolloverImageButton, there shouldn't be any differences between trunk and branch.
Assignee: nobody → stuart.morgan
Reporter | ||
Comment 2•17 years ago
|
||
> Could you elaborate here?
When I say "1.8 branch" I mean "Camino 1.0.3" ... for which there's a
nice and convenient source download :-)
There actually isn't a RolloverImageButton in the Camino 1.0.3 source
download. But since the only existing (indirect) call to
removeTrackingRect is called on BrowserTabBarView, that's where I'd
add a viewWillMoveToWindow method (from which I'd call
removeTrackingRect on "self"). (The existing call is "[tab
removeTrackingRectFromView: self]" in BrowserTabBarView's
unregisterTabButtonsForTracking).
Since BrowserTabBarView is (I think) the only view that uses tracking
rects even on trunk, it might be a good idea to add a
viewWillMoveToWindow method to that class on the trunk, too (and
replace the indirect call to removeTrackingRect in
RolloverImageButton's removeFromSuperview with a direct call in
BrowserTabBarView's new viewWillMoveToWindow method).
Assignee | ||
Comment 3•17 years ago
|
||
> Since BrowserTabBarView is (I think) the only view that uses tracking
> rects even on trunk
Definitely not true on trunk; RolloverImageButton manages its own rects, and given that that's the code that started being used more when things got worse, that's probably most/all of the crashes.
This should be the right fix for RIB, using viewWillMoveToWindow:. It also moves the tracking rect to self, rather than superview; I'm not clear on why it wasn't already that way, and having things based on the superview when we don't know the tear-down order seems like a recipe for pain.
I'll leave this open to audit the other uses.
Attachment #256712 -
Flags: review?(joshmoz)
Assignee | ||
Comment 4•17 years ago
|
||
(In reply to comment #3) > Definitely not true on trunk By which I actually mean, definitely not true on trunk or 1.8 branch. 1.0.3 is not 1.8 branch, it's a mini-branch off of the version of 1.8 that was current when 1.0 was released.
Comment 5•17 years ago
|
||
(In reply to comment #4) > (In reply to comment #3) > > Definitely not true on trunk > > By which I actually mean, definitely not true on trunk or 1.8 branch. 1.0.3 is > not 1.8 branch, it's a mini-branch off of the version of 1.8 that was current > when 1.0 was released. By which you mean, it's a minibranch off the 1.8.0 branch each time we release a new 1.0.x release.
Reporter | ||
Comment 6•17 years ago
|
||
>> Since BrowserTabBarView is (I think) the only view that uses tracking >> rects even on trunk > > Definitely not true on trunk; As far as I can tell, BrowserTabBarView is RolloverImageButton's superview. If so, BrowserTabBarView _is_ the only view that uses tracking rects (on trunk or the branches) ... though with your patch it will now be RolloverImageButton on the trunk. You patch should work fine on the trunk. But I suspect it's only an accident that crashes haven't been reported on the branches. viewWillMoveToWindow should also be used on the branches -- on whatever view(s) that tracking rects are added to or removed from.
Assignee | ||
Comment 7•17 years ago
|
||
(In reply to comment #6) > As far as I can tell, BrowserTabBarView is RolloverImageButton's > superview. The popup blocker uses it as well. > You patch should work fine on the trunk. But I suspect it's only an > accident that crashes haven't been reported on the branches. > viewWillMoveToWindow should also be used on the branches My patch is for both trunk and the 1.8 branch (which is the only branch that is under active development; 1.0.x is pretty much just security fixes only). Crashes have been reported on the 1.8 branch. As I said, I'll leave this open to deal with the tabs themselves.
Reporter | ||
Comment 8•17 years ago
|
||
(In reply to comment #7) I stand corrected on both counts (assuming that there will never be another 1.0.X branch release). I took another look at the trunk code and noticed that there's a mBlockedPopupCloseButton RolloverImageButton created in a nib file and (presumably) added to a mBlockedPopupView NSView. Sneaky, sneaky :-)
Assignee | ||
Comment 9•17 years ago
|
||
(In reply to comment #8) > I stand corrected on both counts (assuming that there will never be > another 1.0.X branch release). There will be, and I'll probably back-port the tab patch. On the other hand, I think accidents of the complex code paths that tabs use left us safe, since we weren't really seeing any of these crashes in the 1.0 timeframe (AFAIK).
Comment 10•17 years ago
|
||
Comment on attachment 256712 [details] [diff] [review] fix RolloverImageButton +- (void)setBounds:(NSRect)inBounds +{ + NSLog(@"calling setBounds:"); Do you really want to leave a live NSLog in there? Probably either take that out or mark it with a debug macro.
Attachment #256712 -
Flags: review?(joshmoz) → review+
Assignee | ||
Comment 11•17 years ago
|
||
Comment on attachment 256712 [details] [diff] [review] fix RolloverImageButton I'll pull the NSLog out on checkin.
Attachment #256712 -
Flags: superreview?(mikepinkerton)
Comment 12•17 years ago
|
||
Comment on attachment 256712 [details] [diff] [review] fix RolloverImageButton sr=pink
Attachment #256712 -
Flags: superreview?(mikepinkerton) → superreview+
Assignee | ||
Comment 13•17 years ago
|
||
Checked in on trunk and MOZILLA_1_8_BRANCH (sans NSLog). Again, thanks Steven! You saved us a lot of debugging here. Leaving open until I check over the tab tracking rects.
Assignee | ||
Comment 14•17 years ago
|
||
It looks like the tab code is safe, but not in a robust way. The tracking rects are removed in a method called from a windowWillClose handler (this method is called windowClosed, confusingly enough), and hiding the tabs just shrinks the view, rather than removing it, so windowWillClose should cover the only case. So while our current tab usage works, it's not hard to imagine usage where it wouldn't be, so I'll definitely fix it. It won't need a 1.0.x port though. Marking as 1.2 since it should definitely be done before then, but I'll likely fix it for 1.1
Target Milestone: --- → Camino1.2
Assignee | ||
Comment 15•17 years ago
|
||
Here's the BrowserTabBarView fix. It removes the now-unnecessary windowClosed method on BTBV.
Attachment #263428 -
Flags: review?
Assignee | ||
Updated•17 years ago
|
Attachment #263428 -
Flags: review? → review?(joshmoz)
Attachment #263428 -
Flags: review?(joshmoz) → review+
Assignee | ||
Updated•17 years ago
|
Attachment #263428 -
Flags: superreview?(mikepinkerton)
Comment 16•17 years ago
|
||
why have we switched from doing this when the window closes to doing it when it moves to a view? shouldn't we be checking the param for nil here, not just always doing it?
Assignee | ||
Comment 17•17 years ago
|
||
If they are moving to another window, then all the tracking rects are going to be hosed since they are, under the covers, associated with a specific window. They would be built up again correctly in the new window.
Comment 18•17 years ago
|
||
Comment on attachment 263428 [details] [diff] [review] fix BrowserTabBarView sr=pink
Attachment #263428 -
Flags: superreview?(mikepinkerton) → superreview+
Assignee | ||
Comment 19•17 years ago
|
||
Checked in on trunk and MOZILLA_1_8_BRANCH.
You need to log in
before you can comment on or make changes to this bug.
Description
•