diff options
-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) |