diff options
author | viettrungluu@chromium.org <viettrungluu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-01-04 15:43:20 +0000 |
---|---|---|
committer | viettrungluu@chromium.org <viettrungluu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-01-04 15:43:20 +0000 |
commit | 6ce8ba65f2767fcabec600bf4c0022e0022c16cb (patch) | |
tree | 36921eb1bfb5f90dcb2b9c9d69d5a3064f6fb897 /chrome/browser | |
parent | 66edf481b897f0ebc5d0eb6751a02af6b60c30d6 (diff) | |
download | chromium_src-6ce8ba65f2767fcabec600bf4c0022e0022c16cb.zip chromium_src-6ce8ba65f2767fcabec600bf4c0022e0022c16cb.tar.gz chromium_src-6ce8ba65f2767fcabec600bf4c0022e0022c16cb.tar.bz2 |
Mac: fix crashes related to detaching tabs.
There are actually two problems, with two fixes:
- Remove TabStripController as observer when removing a tab. (Otherwise, there's a race condition which can result in a stale observation.)
- Make sure the TabController (and its TabView) aren't deleted while handling a torn-off tab.
BUG=31138
TEST=Attach/re-attach/move/close tabs under a variety of circumstances (see in particular the situation described in the bug). Do so till the cows come home. It should hopefully not crash. (Perhaps also check a debug build, and make sure no assertions fail.)
Review URL: http://codereview.chromium.org/515066
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@35455 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r-- | chrome/browser/cocoa/tab_strip_controller.mm | 10 | ||||
-rw-r--r-- | chrome/browser/cocoa/tab_view.mm | 10 |
2 files changed, 16 insertions, 4 deletions
diff --git a/chrome/browser/cocoa/tab_strip_controller.mm b/chrome/browser/cocoa/tab_strip_controller.mm index 31a38ef..b3a1e87 100644 --- a/chrome/browser/cocoa/tab_strip_controller.mm +++ b/chrome/browser/cocoa/tab_strip_controller.mm @@ -947,8 +947,8 @@ private: } } -// Remove all knowledge about this tab and it's associated -// controller and remove the view from the strip. +// Remove all knowledge about this tab and its associated controller, and remove +// the view from the strip. - (void)removeTab:(TabController*)controller { NSUInteger index = [tabArray_ indexOfObject:controller]; @@ -962,6 +962,12 @@ private: NSView* tab = [controller view]; [tab removeFromSuperview]; + // Remove ourself as an observer. + [[NSNotificationCenter defaultCenter] + removeObserver:self + name:NSViewDidUpdateTrackingAreasNotification + object:tab]; + // Clear the tab controller's target. // TODO(viettrungluu): [crbug.com/23829] Find a better way to handle the tab // controller's target. diff --git a/chrome/browser/cocoa/tab_view.mm b/chrome/browser/cocoa/tab_view.mm index 0ad8c8c..4267b15 100644 --- a/chrome/browser/cocoa/tab_view.mm +++ b/chrome/browser/cocoa/tab_view.mm @@ -264,6 +264,12 @@ const CGFloat kRapidCloseDist = 2.5; dragOrigin_ = [NSEvent mouseLocation]; + // If the tab gets torn off, the tab controller will be removed from the tab + // strip and then deallocated. This will also result in *us* being + // deallocated. Both these are bad, so we prevent this by retaining the + // controller. + scoped_nsobject<TabController> controller([controller_ retain]); + // Because we move views between windows, we need to handle the event loop // ourselves. Ideally we should use the standard event loop. while (1) { @@ -286,12 +292,12 @@ const CGFloat kRapidCloseDist = 2.5; // and the mouse hasn't moved too much, we close the tab. if (closeButtonActive && (dx*dx + dy*dy) <= kRapidCloseDist*kRapidCloseDist && - [controller_ inRapidClosureMode]) { + [controller inRapidClosureMode]) { NSPoint hitLocation = [[self superview] convertPoint:[theEvent locationInWindow] fromView:nil]; if ([self hitTest:hitLocation] == closeButton_) { - [controller_ closeTab:self]; + [controller closeTab:self]; break; } } |