diff options
author | shess@chromium.org <shess@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-08-31 22:44:09 +0000 |
---|---|---|
committer | shess@chromium.org <shess@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-08-31 22:44:09 +0000 |
commit | 4e8c4f9f882e8ccd85a8c629cbb58d8819773db1 (patch) | |
tree | 4ad1238a7f4e0d780c079788c36dfd91097114df | |
parent | 8267dfd1852d76a08e0b5e64710914a6b7367055 (diff) | |
download | chromium_src-4e8c4f9f882e8ccd85a8c629cbb58d8819773db1.zip chromium_src-4e8c4f9f882e8ccd85a8c629cbb58d8819773db1.tar.gz chromium_src-4e8c4f9f882e8ccd85a8c629cbb58d8819773db1.tar.bz2 |
[Mac] Hung-renderer dialogs observes the initiating tab in case it goes away.
The user can close the tab out from under the dialog, at which point
killing from the dialog will cause a crash.
BUG=89909
TEST=See bug, monitor crash server.
Review URL: http://codereview.chromium.org/7810011
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@99064 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/ui/cocoa/hung_renderer_controller.h | 9 | ||||
-rw-r--r-- | chrome/browser/ui/cocoa/hung_renderer_controller.mm | 34 |
2 files changed, 43 insertions, 0 deletions
diff --git a/chrome/browser/ui/cocoa/hung_renderer_controller.h b/chrome/browser/ui/cocoa/hung_renderer_controller.h index 957e5fb..7d4fd1c 100644 --- a/chrome/browser/ui/cocoa/hung_renderer_controller.h +++ b/chrome/browser/ui/cocoa/hung_renderer_controller.h @@ -22,9 +22,11 @@ #import "base/mac/cocoa_protocols.h" #import "base/memory/scoped_nsobject.h" +#import "base/memory/scoped_ptr.h" @class MultiKeyEquivalentButton; class TabContents; +class TabContentsObserverBridge; @interface HungRendererController : NSWindowController<NSTableViewDataSource> { @private @@ -38,6 +40,9 @@ class TabContents; // NULL while this dialog is open. TabContents* hungContents_; + // Observes |hungContents_| in case it closes while the panel is up. + scoped_ptr<TabContentsObserverBridge> hungContentsObserver_; + // Backing data for |tableView_|. Titles of each TabContents that // shares a renderer process with |hungContents_|. scoped_nsobject<NSArray> hungTitles_; @@ -65,6 +70,10 @@ class TabContents; // If |contents| has a different process, this function does nothing. - (void)endForTabContents:(TabContents*)contents; +// Called by |hungContentsObserver_| to indicate that |hungContents_| +// has gone away. +- (void)renderViewGone; + @end // HungRendererController diff --git a/chrome/browser/ui/cocoa/hung_renderer_controller.mm b/chrome/browser/ui/cocoa/hung_renderer_controller.mm index f8dc950..bab2472 100644 --- a/chrome/browser/ui/cocoa/hung_renderer_controller.mm +++ b/chrome/browser/ui/cocoa/hung_renderer_controller.mm @@ -36,6 +36,29 @@ namespace { HungRendererController* g_instance = NULL; } // namespace +class TabContentsObserverBridge : public TabContentsObserver { + public: + TabContentsObserverBridge(TabContents* tab_contents, + HungRendererController* controller) + : TabContentsObserver(tab_contents), + controller_(controller) { + } + + protected: + // TabContentsObserver overrides: + virtual void RenderViewGone() OVERRIDE { + [controller_ renderViewGone]; + } + virtual void TabContentsDestroyed(TabContents* tab) OVERRIDE { + [controller_ renderViewGone]; + } + + private: + HungRendererController* controller_; // weak + + DISALLOW_COPY_AND_ASSIGN(TabContentsObserverBridge); +}; + @implementation HungRendererController - (id)initWithWindowNibName:(NSString*)nibName { @@ -134,9 +157,15 @@ HungRendererController* g_instance = NULL; [self autorelease]; } +// TODO(shess): This could observe all of the tabs referenced in the +// loop, updating the dialog and keeping it up so long as any remain. +// Tabs closed by their renderer will close the dialog (that's +// activity!), so it would not add much value. Also, the views +// implementation only monitors the initiating tab. - (void)showForTabContents:(TabContents*)contents { DCHECK(contents); hungContents_ = contents; + hungContentsObserver_.reset(new TabContentsObserverBridge(contents, self)); scoped_nsobject<NSMutableArray> titles([[NSMutableArray alloc] init]); scoped_nsobject<NSMutableArray> favicons([[NSMutableArray alloc] init]); for (TabContentsIterator it; !it.done(); ++it) { @@ -167,6 +196,11 @@ HungRendererController* g_instance = NULL; } } +- (void)renderViewGone { + // Cannot call performClose:, because the close button is disabled. + [self close]; +} + @end @implementation HungRendererController (JustForTesting) |