diff options
author | avi@chromium.org <avi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-15 15:04:27 +0000 |
---|---|---|
committer | avi@chromium.org <avi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-15 15:04:27 +0000 |
commit | 9cddb1a26ca716f6e3f42bc8d7180a2809afea69 (patch) | |
tree | 62c18c1dec6a8c9efda6ddb0054441d51054cccc | |
parent | b60ae4b0ea0bcdd455e45a4971da0ddfc6464c69 (diff) | |
download | chromium_src-9cddb1a26ca716f6e3f42bc8d7180a2809afea69.zip chromium_src-9cddb1a26ca716f6e3f42bc8d7180a2809afea69.tar.gz chromium_src-9cddb1a26ca716f6e3f42bc8d7180a2809afea69.tar.bz2 |
Move Sad Tab implementation out of the TabContentsViews.
BUG=103258
TEST=no change in sad tab behavior
Review URL: http://codereview.chromium.org/8477042
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@110086 0039d316-1c4b-4281-b951-d872f2087c98
43 files changed, 362 insertions, 208 deletions
diff --git a/chrome/browser/automation/automation_tab_helper.cc b/chrome/browser/automation/automation_tab_helper.cc index 3e4945a..30d203b 100644 --- a/chrome/browser/automation/automation_tab_helper.cc +++ b/chrome/browser/automation/automation_tab_helper.cc @@ -87,7 +87,7 @@ void AutomationTabHelper::DidStopLoading() { } } -void AutomationTabHelper::RenderViewGone() { +void AutomationTabHelper::RenderViewGone(base::TerminationStatus status) { OnTabOrRenderViewDestroyed(tab_contents()); } diff --git a/chrome/browser/automation/automation_tab_helper.h b/chrome/browser/automation/automation_tab_helper.h index a8ddef7..ae764ba 100644 --- a/chrome/browser/automation/automation_tab_helper.h +++ b/chrome/browser/automation/automation_tab_helper.h @@ -106,11 +106,11 @@ class AutomationTabHelper const std::string& error_msg); // TabContentsObserver implementation. - virtual void DidStartLoading(); - virtual void DidStopLoading(); - virtual void RenderViewGone(); - virtual void TabContentsDestroyed(TabContents* tab_contents); - virtual bool OnMessageReceived(const IPC::Message& message); + virtual void DidStartLoading() OVERRIDE; + virtual void DidStopLoading() OVERRIDE; + virtual void RenderViewGone(base::TerminationStatus status) OVERRIDE; + virtual void TabContentsDestroyed(TabContents* tab_contents) OVERRIDE; + virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; void OnWillPerformClientRedirect(int64 frame_id, double delay_seconds); void OnDidCompleteOrCancelClientRedirect(int64 frame_id); diff --git a/chrome/browser/infobars/infobar_tab_helper.cc b/chrome/browser/infobars/infobar_tab_helper.cc index ac10be6..000bfb4 100644 --- a/chrome/browser/infobars/infobar_tab_helper.cc +++ b/chrome/browser/infobars/infobar_tab_helper.cc @@ -155,7 +155,7 @@ void InfoBarTabHelper::OnDidBlockRunningInsecureContent() { InsecureContentInfoBarDelegate::RUN)); } -void InfoBarTabHelper::RenderViewGone() { +void InfoBarTabHelper::RenderViewGone(base::TerminationStatus status) { RemoveAllInfoBars(true); } diff --git a/chrome/browser/infobars/infobar_tab_helper.h b/chrome/browser/infobars/infobar_tab_helper.h index d1332f0..f614a8b 100644 --- a/chrome/browser/infobars/infobar_tab_helper.h +++ b/chrome/browser/infobars/infobar_tab_helper.h @@ -50,7 +50,7 @@ class InfoBarTabHelper : public TabContentsObserver, void set_infobars_enabled(bool value) { infobars_enabled_ = value; } // TabContentsObserver overrides: - virtual void RenderViewGone() OVERRIDE; + virtual void RenderViewGone(base::TerminationStatus status) OVERRIDE; virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; // content::NotificationObserver overrides: diff --git a/chrome/browser/notifications/balloon_host.cc b/chrome/browser/notifications/balloon_host.cc index ee586cc..e476972 100644 --- a/chrome/browser/notifications/balloon_host.cc +++ b/chrome/browser/notifications/balloon_host.cc @@ -93,7 +93,7 @@ void BalloonHost::RenderViewReady() { content::NotificationService::NoDetails()); } -void BalloonHost::RenderViewGone() { +void BalloonHost::RenderViewGone(base::TerminationStatus status) { CloseContents(tab_contents_.get()); } diff --git a/chrome/browser/notifications/balloon_host.h b/chrome/browser/notifications/balloon_host.h index 7dfd875..257fba8 100644 --- a/chrome/browser/notifications/balloon_host.h +++ b/chrome/browser/notifications/balloon_host.h @@ -68,7 +68,7 @@ class BalloonHost : public TabContentsDelegate, // TabContentsObserver implementation: virtual void RenderViewCreated(RenderViewHost* render_view_host) OVERRIDE; virtual void RenderViewReady() OVERRIDE; - virtual void RenderViewGone() OVERRIDE; + virtual void RenderViewGone(base::TerminationStatus status) OVERRIDE; virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; // Message handlers diff --git a/chrome/browser/prerender/prerender_browsertest.cc b/chrome/browser/prerender/prerender_browsertest.cc index be115b1..9891dc9 100644 --- a/chrome/browser/prerender/prerender_browsertest.cc +++ b/chrome/browser/prerender/prerender_browsertest.cc @@ -161,7 +161,7 @@ class TestPrerenderContents : public PrerenderContents { MessageLoopForUI::current()->Quit(); } - virtual void RenderViewGone() OVERRIDE { + virtual void RenderViewGone(base::TerminationStatus status) OVERRIDE { // On quit, it's possible to end up here when render processes are closed // before the PrerenderManager is destroyed. As a result, it's possible to // get either FINAL_STATUS_APP_TERMINATING or FINAL_STATUS_RENDERER_CRASHED @@ -175,7 +175,7 @@ class TestPrerenderContents : public PrerenderContents { expected_final_status_ = FINAL_STATUS_RENDERER_CRASHED; } - PrerenderContents::RenderViewGone(); + PrerenderContents::RenderViewGone(status); } virtual bool AddAliasURL(const GURL& url) OVERRIDE { diff --git a/chrome/browser/prerender/prerender_contents.cc b/chrome/browser/prerender/prerender_contents.cc index c4b67322..02bb75b 100644 --- a/chrome/browser/prerender/prerender_contents.cc +++ b/chrome/browser/prerender/prerender_contents.cc @@ -523,7 +523,7 @@ void PrerenderContents::OnJSOutOfMemory() { Destroy(FINAL_STATUS_JS_OUT_OF_MEMORY); } -void PrerenderContents::RenderViewGone() { +void PrerenderContents::RenderViewGone(base::TerminationStatus status) { Destroy(FINAL_STATUS_RENDERER_CRASHED); } diff --git a/chrome/browser/prerender/prerender_contents.h b/chrome/browser/prerender/prerender_contents.h index 3c26e30..37010cc 100644 --- a/chrome/browser/prerender/prerender_contents.h +++ b/chrome/browser/prerender/prerender_contents.h @@ -145,7 +145,7 @@ class PrerenderContents : public content::NotificationObserver, const GURL& validated_url, bool is_error_page, RenderViewHost* render_view_host) OVERRIDE; - virtual void RenderViewGone() OVERRIDE; + virtual void RenderViewGone(base::TerminationStatus status) OVERRIDE; // content::NotificationObserver virtual void Observe(int type, diff --git a/chrome/browser/printing/print_view_manager.cc b/chrome/browser/printing/print_view_manager.cc index 6d4ddcd..c24affa 100644 --- a/chrome/browser/printing/print_view_manager.cc +++ b/chrome/browser/printing/print_view_manager.cc @@ -135,7 +135,7 @@ void PrintViewManager::StopNavigation() { TerminatePrintJob(true); } -void PrintViewManager::RenderViewGone() { +void PrintViewManager::RenderViewGone(base::TerminationStatus status) { if (!print_job_.get()) return; diff --git a/chrome/browser/printing/print_view_manager.h b/chrome/browser/printing/print_view_manager.h index d75e3d8..1702461 100644 --- a/chrome/browser/printing/print_view_manager.h +++ b/chrome/browser/printing/print_view_manager.h @@ -80,10 +80,10 @@ class PrintViewManager : public content::NotificationObserver, virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; // Terminates or cancels the print job if one was pending. - virtual void RenderViewGone(); + virtual void RenderViewGone(base::TerminationStatus status) OVERRIDE; // Cancels the print job. - virtual void StopNavigation(); + virtual void StopNavigation() OVERRIDE; private: // IPC Message handlers. diff --git a/chrome/browser/tab_contents/background_contents.cc b/chrome/browser/tab_contents/background_contents.cc index b52f39b..19d04f3 100644 --- a/chrome/browser/tab_contents/background_contents.cc +++ b/chrome/browser/tab_contents/background_contents.cc @@ -94,7 +94,7 @@ void BackgroundContents::DidNavigateMainFramePostCommit(TabContents* tab) { content::Details<BackgroundContents>(this)); } -void BackgroundContents::RenderViewGone() { +void BackgroundContents::RenderViewGone(base::TerminationStatus status) { content::NotificationService::current()->Notify( chrome::NOTIFICATION_BACKGROUND_CONTENTS_TERMINATED, content::Source<Profile>(profile_), @@ -103,7 +103,7 @@ void BackgroundContents::RenderViewGone() { // Our RenderView went away, so we should go away also, so killing the process // via the TaskManager doesn't permanently leave a BackgroundContents hanging // around the system, blocking future instances from being created - // (http://crbug.com/65189). + // <http://crbug.com/65189>. delete this; } diff --git a/chrome/browser/tab_contents/background_contents.h b/chrome/browser/tab_contents/background_contents.h index e92f517..fc3a443 100644 --- a/chrome/browser/tab_contents/background_contents.h +++ b/chrome/browser/tab_contents/background_contents.h @@ -51,7 +51,7 @@ class BackgroundContents : public TabContentsDelegate, virtual void DidNavigateMainFramePostCommit(TabContents* tab) OVERRIDE; // TabContentsObserver implementation: - virtual void RenderViewGone() OVERRIDE; + virtual void RenderViewGone(base::TerminationStatus status) OVERRIDE; // content::NotificationObserver virtual void Observe(int type, diff --git a/chrome/browser/tab_contents/tab_contents_view_gtk.cc b/chrome/browser/tab_contents/tab_contents_view_gtk.cc index 4284f64..d297b99 100644 --- a/chrome/browser/tab_contents/tab_contents_view_gtk.cc +++ b/chrome/browser/tab_contents/tab_contents_view_gtk.cc @@ -13,11 +13,9 @@ #include "base/string_util.h" #include "base/utf_string_conversions.h" #include "build/build_config.h" -#include "chrome/browser/browser_shutdown.h" #include "chrome/browser/tab_contents/render_view_context_menu_gtk.h" #include "chrome/browser/tab_contents/web_drag_bookmark_handler_gtk.h" #include "chrome/browser/ui/gtk/constrained_window_gtk.h" -#include "chrome/browser/ui/gtk/sad_tab_gtk.h" #include "content/browser/renderer_host/render_view_host.h" #include "content/browser/renderer_host/render_view_host_factory.h" #include "content/browser/renderer_host/render_widget_host_view_gtk.h" @@ -26,8 +24,6 @@ #include "content/browser/tab_contents/tab_contents_delegate.h" #include "content/browser/tab_contents/web_drag_dest_gtk.h" #include "content/browser/tab_contents/web_drag_source_gtk.h" -#include "content/public/browser/notification_source.h" -#include "content/public/browser/notification_types.h" #include "ui/base/gtk/gtk_expanded_container.h" #include "ui/base/gtk/gtk_floating_container.h" #include "ui/gfx/point.h" @@ -81,7 +77,8 @@ TabContentsViewGtk::TabContentsViewGtk(TabContents* tab_contents) : tab_contents_(tab_contents), floating_(gtk_floating_container_new()), expanded_(gtk_expanded_container_new()), - constrained_window_(NULL) { + constrained_window_(NULL), + overlaid_view_(NULL) { gtk_widget_set_name(expanded_, "chrome-tab-contents-view"); g_signal_connect(expanded_, "size-allocate", G_CALLBACK(OnSizeAllocateThunk), this); @@ -93,8 +90,6 @@ TabContentsViewGtk::TabContentsViewGtk(TabContents* tab_contents) gtk_container_add(GTK_CONTAINER(floating_.get()), expanded_); gtk_widget_show(expanded_); gtk_widget_show(floating_.get()); - registrar_.Add(this, content::NOTIFICATION_TAB_CONTENTS_CONNECTED, - content::Source<TabContents>(tab_contents)); drag_source_.reset(new content::WebDragSourceGtk(tab_contents)); } @@ -198,20 +193,6 @@ void TabContentsViewGtk::SetPageTitle(const string16& title) { void TabContentsViewGtk::OnTabCrashed(base::TerminationStatus status, int error_code) { - // Only show the sad tab if we're not in browser shutdown, so that TabContents - // objects that are not in a browser (e.g., HTML dialogs) and thus are - // visible do not flash a sad tab page. - if (browser_shutdown::GetShutdownType() != browser_shutdown::NOT_VALID) - return; - - if (tab_contents_ != NULL && !sad_tab_.get()) { - sad_tab_.reset(new SadTabGtk( - tab_contents_, - status == base::TERMINATION_STATUS_PROCESS_WAS_KILLED ? - SadTabGtk::KILLED : SadTabGtk::CRASHED)); - InsertIntoContentArea(sad_tab_->widget()); - gtk_widget_show(sad_tab_->widget()); - } } void TabContentsViewGtk::SizeContents(const gfx::Size& size) { @@ -279,6 +260,19 @@ void TabContentsViewGtk::GetViewBounds(gfx::Rect* out) const { out->SetRect(x, y, w, h); } +void TabContentsViewGtk::InstallOverlayView(gfx::NativeView view) { + DCHECK(!overlaid_view_); + overlaid_view_ = view; + InsertIntoContentArea(view); + gtk_widget_show(view); +} + +void TabContentsViewGtk::RemoveOverlayView() { + DCHECK(overlaid_view_); + gtk_container_remove(GTK_CONTAINER(expanded_), overlaid_view_); + overlaid_view_ = NULL; +} + void TabContentsViewGtk::SetFocusedWidget(GtkWidget* widget) { focus_store_.SetWidget(widget); } @@ -301,24 +295,6 @@ void TabContentsViewGtk::TakeFocus(bool reverse) { } } -void TabContentsViewGtk::Observe(int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) { - switch (type) { - case content::NOTIFICATION_TAB_CONTENTS_CONNECTED: { - // No need to remove the SadTabGtk's widget from the container since - // the new RenderWidgetHostViewGtk instance already removed all the - // vbox's children. - sad_tab_.reset(); - break; - } - default: - NOTREACHED() << "Got a notification we didn't register for."; - break; - } -} - - void TabContentsViewGtk::CreateNewWindow( int route_id, const ViewHostMsg_CreateWindow_Params& params) { diff --git a/chrome/browser/tab_contents/tab_contents_view_gtk.h b/chrome/browser/tab_contents/tab_contents_view_gtk.h index feb56b2..efa4133 100644 --- a/chrome/browser/tab_contents/tab_contents_view_gtk.h +++ b/chrome/browser/tab_contents/tab_contents_view_gtk.h @@ -14,14 +14,11 @@ #include "chrome/browser/tab_contents/render_view_host_delegate_helper.h" #include "chrome/browser/ui/gtk/focus_store_gtk.h" #include "content/browser/tab_contents/tab_contents_view.h" -#include "content/public/browser/notification_observer.h" -#include "content/public/browser/notification_registrar.h" #include "ui/base/gtk/gtk_signal.h" #include "ui/base/gtk/owned_widget_gtk.h" class ConstrainedWindowGtk; class RenderViewContextMenuGtk; -class SadTabGtk; class WebDragBookmarkHandlerGtk; namespace content { @@ -29,8 +26,7 @@ class WebDragDestGtk; class WebDragSourceGtk; } -class TabContentsViewGtk : public TabContentsView, - public content::NotificationObserver { +class TabContentsViewGtk : public TabContentsView { public: // The corresponding TabContents is passed in the constructor, and manages our // lifetime. This doesn't need to be the case, but is this way currently @@ -71,6 +67,8 @@ class TabContentsViewGtk : public TabContentsView, virtual bool IsEventTracking() const OVERRIDE; virtual void CloseTabAfterEventTracking() OVERRIDE; virtual void GetViewBounds(gfx::Rect* out) const OVERRIDE; + virtual void InstallOverlayView(gfx::NativeView view) OVERRIDE; + virtual void RemoveOverlayView() OVERRIDE; // Backend implementation of RenderViewHostDelegate::View. virtual void CreateNewWindow( @@ -99,12 +97,6 @@ class TabContentsViewGtk : public TabContentsView, virtual void GotFocus(); virtual void TakeFocus(bool reverse); - // content::NotificationObserver implementation ------------------------------ - - virtual void Observe(int type, - const content::NotificationSource& source, - const content::NotificationDetails& details); - private: // Insert the given widget into the content area. Should only be used for // web pages and the like (including interstitials and sad tab). Note that @@ -136,7 +128,6 @@ class TabContentsViewGtk : public TabContentsView, // Common implementations of some RenderViewHostDelegate::View methods. RenderViewHostDelegateViewHelper delegate_view_helper_; - // Contains |expanded_| as its GtkBin member. ui::OwnedWidgetGtk floating_; @@ -148,11 +139,6 @@ class TabContentsViewGtk : public TabContentsView, // between uses so that it won't go out of scope before we're done with it. scoped_ptr<RenderViewContextMenuGtk> context_menu_; - // Used to get notifications about renderers coming and going. - content::NotificationRegistrar registrar_; - - scoped_ptr<SadTabGtk> sad_tab_; - FocusStoreGtk focus_store_; // The UI for the constrained dialog currently displayed. This is owned by @@ -173,6 +159,10 @@ class TabContentsViewGtk : public TabContentsView, // variable because resizing in GTK+ is async. gfx::Size requested_size_; + // The overlaid view. Owned by the caller of |InstallOverlayView|; this is a + // weak reference. + GtkWidget* overlaid_view_; + DISALLOW_COPY_AND_ASSIGN(TabContentsViewGtk); }; diff --git a/chrome/browser/tab_contents/tab_contents_view_mac.h b/chrome/browser/tab_contents/tab_contents_view_mac.h index 670358b..406e221 100644 --- a/chrome/browser/tab_contents/tab_contents_view_mac.h +++ b/chrome/browser/tab_contents/tab_contents_view_mac.h @@ -17,8 +17,6 @@ #include "base/memory/scoped_ptr.h" #include "chrome/browser/tab_contents/render_view_host_delegate_helper.h" #include "content/browser/tab_contents/tab_contents_view.h" -#include "content/public/browser/notification_observer.h" -#include "content/public/browser/notification_registrar.h" #include "ui/base/cocoa/base_view.h" #include "ui/gfx/size.h" @@ -48,8 +46,7 @@ class Point; // Mac-specific implementation of the TabContentsView. It owns an NSView that // contains all of the contents of the tab and associated child views. -class TabContentsViewMac : public TabContentsView, - public content::NotificationObserver { +class TabContentsViewMac : public TabContentsView { public: // The corresponding TabContents is passed in the constructor, and manages our // lifetime. This doesn't need to be the case, but is this way currently @@ -80,6 +77,8 @@ class TabContentsViewMac : public TabContentsView, virtual bool IsEventTracking() const OVERRIDE; virtual void CloseTabAfterEventTracking() OVERRIDE; virtual void GetViewBounds(gfx::Rect* out) const OVERRIDE; + virtual void InstallOverlayView(gfx::NativeView view) OVERRIDE; + virtual void RemoveOverlayView() OVERRIDE; // Backend implementation of RenderViewHostDelegate::View. virtual void CreateNewWindow( @@ -108,12 +107,6 @@ class TabContentsViewMac : public TabContentsView, virtual void GotFocus(); virtual void TakeFocus(bool reverse); - // content::NotificationObserver implementation ------------------------------ - - virtual void Observe(int type, - const content::NotificationSource& source, - const content::NotificationDetails& details); - // A helper method for closing the tab in the // CloseTabAfterEventTracking() implementation. void CloseTab(); @@ -135,19 +128,16 @@ class TabContentsViewMac : public TabContentsView, // focus returns. scoped_nsobject<FocusTracker> focus_tracker_; - // Used to get notifications about renderers coming and going. - content::NotificationRegistrar registrar_; - - // Used to render the sad tab. This will be non-NULL only when the sad tab is - // visible. - scoped_nsobject<SadTabController> sad_tab_; - // The context menu. Callbacks are asynchronous so we need to keep it around. scoped_ptr<RenderViewContextMenuMac> context_menu_; // The page content's intrinsic width. int preferred_width_; + // The overlaid view. Owned by the caller of |InstallOverlayView|; this is a + // weak reference. + NSView* overlaid_view_; + DISALLOW_COPY_AND_ASSIGN(TabContentsViewMac); }; diff --git a/chrome/browser/tab_contents/tab_contents_view_mac.mm b/chrome/browser/tab_contents/tab_contents_view_mac.mm index 6f71e3a..ba507b4 100644 --- a/chrome/browser/tab_contents/tab_contents_view_mac.mm +++ b/chrome/browser/tab_contents/tab_contents_view_mac.mm @@ -8,12 +8,10 @@ #include <string> -#include "chrome/browser/browser_shutdown.h" #import "chrome/browser/renderer_host/chrome_render_widget_host_view_mac_delegate.h" #include "chrome/browser/tab_contents/render_view_context_menu_mac.h" #include "chrome/browser/tab_contents/web_drag_bookmark_handler_mac.h" #import "chrome/browser/ui/cocoa/focus_tracker.h" -#import "chrome/browser/ui/cocoa/tab_contents/sad_tab_controller.h" #import "chrome/browser/ui/cocoa/view_id_util.h" #include "content/browser/renderer_host/render_view_host.h" #include "content/browser/renderer_host/render_view_host_factory.h" @@ -27,9 +25,6 @@ #import "content/common/chrome_application_mac.h" #import "content/common/mac/scoped_sending_event.h" #include "content/common/view_messages.h" -#include "content/public/browser/notification_details.h" -#include "content/public/browser/notification_source.h" -#include "content/public/browser/notification_types.h" #include "skia/ext/skia_utils_mac.h" #import "third_party/mozilla/NSPasteboard+Utils.h" @@ -71,9 +66,8 @@ TabContentsView* CreateTabContentsView(TabContents* tab_contents) { TabContentsViewMac::TabContentsViewMac(TabContents* tab_contents) : tab_contents_(tab_contents), - preferred_width_(0) { - registrar_.Add(this, content::NOTIFICATION_TAB_CONTENTS_CONNECTED, - content::Source<TabContents>(tab_contents)); + preferred_width_(0), + overlaid_view_(nil) { } TabContentsViewMac::~TabContentsViewMac() { @@ -120,6 +114,8 @@ RenderWidgetHostView* TabContentsViewMac::CreateViewForWidget( NSView* view_view = view->native_view(); [view_view setFrame:[cocoa_view_.get() bounds]]; [view_view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; + // Add the new view below all other views; this also keeps it below any + // overlay view installed. [cocoa_view_.get() addSubview:view_view positioned:NSWindowBelow relativeTo:nil]; @@ -188,21 +184,6 @@ void TabContentsViewMac::SetPageTitle(const string16& title) { void TabContentsViewMac::OnTabCrashed(base::TerminationStatus /* status */, int /* error_code */) { - // Only show the sad tab if we're not in browser shutdown, so that TabContents - // objects that are not in a browser (e.g., HTML dialogs) and thus are - // visible do not flash a sad tab page. - if (browser_shutdown::GetShutdownType() != browser_shutdown::NOT_VALID) - return; - - if (!sad_tab_.get()) { - DCHECK(tab_contents_); - if (tab_contents_) { - SadTabController* sad_tab = - [[SadTabController alloc] initWithTabContents:tab_contents_ - superview:cocoa_view_]; - sad_tab_.reset(sad_tab); - } - } } void TabContentsViewMac::SizeContents(const gfx::Size& size) { @@ -397,21 +378,22 @@ void TabContentsViewMac::GetViewBounds(gfx::Rect* out) const { NOTIMPLEMENTED(); } -void TabContentsViewMac::CloseTab() { - tab_contents_->Close(tab_contents_->render_view_host()); +void TabContentsViewMac::InstallOverlayView(gfx::NativeView view) { + DCHECK(!overlaid_view_); + overlaid_view_ = view; + [view setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)]; + [cocoa_view_.get() addSubview:view]; + [view setFrame:[cocoa_view_.get() bounds]]; } -void TabContentsViewMac::Observe(int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) { - switch (type) { - case content::NOTIFICATION_TAB_CONTENTS_CONNECTED: { - sad_tab_.reset(); - break; - } - default: - NOTREACHED() << "Got a notification we didn't register for."; - } +void TabContentsViewMac::RemoveOverlayView() { + DCHECK(overlaid_view_); + [overlaid_view_ removeFromSuperview]; + overlaid_view_ = nil; +} + +void TabContentsViewMac::CloseTab() { + tab_contents_->Close(tab_contents_->render_view_host()); } @implementation TabContentsViewCocoa diff --git a/chrome/browser/ui/cocoa/browser_window_controller.mm b/chrome/browser/ui/cocoa/browser_window_controller.mm index 90ba5a4..c3de07b 100644 --- a/chrome/browser/ui/cocoa/browser_window_controller.mm +++ b/chrome/browser/ui/cocoa/browser_window_controller.mm @@ -1746,7 +1746,7 @@ enum { // Handle the openLearnMoreAboutCrashLink: action from SadTabController when // "Learn more" link in "Aw snap" page (i.e. crash page or sad tab) is -// clicked. Decoupling the action from its target makes unitestting possible. +// clicked. Decoupling the action from its target makes unit testing possible. - (void)openLearnMoreAboutCrashLink:(id)sender { if ([sender isKindOfClass:[SadTabController class]]) { SadTabController* sad_tab = static_cast<SadTabController*>(sender); diff --git a/chrome/browser/ui/cocoa/hung_renderer_controller.mm b/chrome/browser/ui/cocoa/hung_renderer_controller.mm index c0d162a..0003ae1 100644 --- a/chrome/browser/ui/cocoa/hung_renderer_controller.mm +++ b/chrome/browser/ui/cocoa/hung_renderer_controller.mm @@ -46,7 +46,7 @@ class TabContentsObserverBridge : public TabContentsObserver { protected: // TabContentsObserver overrides: - virtual void RenderViewGone() OVERRIDE { + virtual void RenderViewGone(base::TerminationStatus status) OVERRIDE { [controller_ renderViewGone]; } virtual void TabContentsDestroyed(TabContents* tab) OVERRIDE { diff --git a/chrome/browser/ui/cocoa/tab_contents/sad_tab_controller.h b/chrome/browser/ui/cocoa/tab_contents/sad_tab_controller.h index 48a97f6..f91327d 100644 --- a/chrome/browser/ui/cocoa/tab_contents/sad_tab_controller.h +++ b/chrome/browser/ui/cocoa/tab_contents/sad_tab_controller.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -6,19 +6,24 @@ #define CHROME_BROWSER_UI_COCOA_TAB_CONTENTS_SAD_TAB_CONTROLLER_H_ #pragma once +#include "ui/gfx/native_widget_types.h" + +#if defined(__OBJC__) #import <Cocoa/Cocoa.h> +#endif // __OBJC__ class TabContents; +#if defined(__OBJC__) + // A controller class that manages the SadTabView (aka "Aw Snap" or crash page). @interface SadTabController : NSViewController { @private TabContents* tabContents_; // Weak reference. } -// Designated initializer is initWithTabContents. -- (id)initWithTabContents:(TabContents*)someTabContents - superview:(NSView*)superview; +// Designated initializer. +- (id)initWithTabContents:(TabContents*)tabContents; // This action just calls the NSApp sendAction to get it into the standard // Cocoa action processing. @@ -30,4 +35,16 @@ class TabContents; @end +#else + +class SadTabController; + +#endif // __OBJC__ + +// Functions that may be accessed from non-Objective-C C/C++ code. +namespace sad_tab_controller_mac { +SadTabController* CreateSadTabController(TabContents* tab_contents); +gfx::NativeView GetViewOfSadTabController(SadTabController* sad_tab); +} + #endif // CHROME_BROWSER_UI_COCOA_TAB_CONTENTS_SAD_TAB_CONTROLLER_H_ diff --git a/chrome/browser/ui/cocoa/tab_contents/sad_tab_controller.mm b/chrome/browser/ui/cocoa/tab_contents/sad_tab_controller.mm index c01a945..5812a8c 100644 --- a/chrome/browser/ui/cocoa/tab_contents/sad_tab_controller.mm +++ b/chrome/browser/ui/cocoa/tab_contents/sad_tab_controller.mm @@ -7,17 +7,24 @@ #include "base/mac/mac_util.h" #import "chrome/browser/ui/cocoa/tab_contents/sad_tab_view.h" +namespace sad_tab_controller_mac { + +SadTabController* CreateSadTabController(TabContents* tab_contents) { + return [[SadTabController alloc] initWithTabContents:tab_contents]; +} + +gfx::NativeView GetViewOfSadTabController(SadTabController* sad_tab) { + return [sad_tab view]; +} + +} // namespace sad_tab_controller_mac + @implementation SadTabController -- (id)initWithTabContents:(TabContents*)someTabContents - superview:(NSView*)superview { +- (id)initWithTabContents:(TabContents*)tabContents { if ((self = [super initWithNibName:@"SadTab" bundle:base::mac::MainAppBundle()])) { - tabContents_ = someTabContents; - - NSView* view = [self view]; - [superview addSubview:view]; - [view setFrame:[superview bounds]]; + tabContents_ = tabContents; } return self; @@ -31,11 +38,6 @@ } } -- (void)dealloc { - [[self view] removeFromSuperview]; - [super dealloc]; -} - - (TabContents*)tabContents { return tabContents_; } diff --git a/chrome/browser/ui/cocoa/tab_contents/sad_tab_controller_unittest.mm b/chrome/browser/ui/cocoa/tab_contents/sad_tab_controller_unittest.mm index 0ddf62f..2694d1d 100644 --- a/chrome/browser/ui/cocoa/tab_contents/sad_tab_controller_unittest.mm +++ b/chrome/browser/ui/cocoa/tab_contents/sad_tab_controller_unittest.mm @@ -52,13 +52,13 @@ class SadTabControllerTest : public ChromeRenderViewHostTestHarness { // Creates the controller and adds its view to contents, caller has ownership. SadTabController* CreateController() { - NSView* contentView = [test_window_ contentView]; SadTabController* controller = - [[SadTabController alloc] initWithTabContents:contents() - superview:contentView]; + [[SadTabController alloc] initWithTabContents:contents()]; EXPECT_TRUE(controller); NSView* view = [controller view]; EXPECT_TRUE(view); + NSView* contentView = [test_window_ contentView]; + [contentView addSubview:view]; return controller; } diff --git a/chrome/browser/ui/cocoa/tab_contents/sad_tab_view.mm b/chrome/browser/ui/cocoa/tab_contents/sad_tab_view.mm index dffe008..b79f400 100644 --- a/chrome/browser/ui/cocoa/tab_contents/sad_tab_view.mm +++ b/chrome/browser/ui/cocoa/tab_contents/sad_tab_view.mm @@ -161,9 +161,9 @@ static const CGFloat kTabHorzMargin = 13; } // Called when someone clicks on the embedded link. -- (BOOL) textView:(NSTextView*)textView - clickedOnLink:(id)link - atIndex:(NSUInteger)charIndex { +- (BOOL)textView:(NSTextView*)textView + clickedOnLink:(id)link + atIndex:(NSUInteger)charIndex { if (controller_) [controller_ openLearnMoreAboutCrashLink:nil]; return YES; diff --git a/chrome/browser/ui/gtk/hung_renderer_dialog_gtk.cc b/chrome/browser/ui/gtk/hung_renderer_dialog_gtk.cc index 2fb798a..f00a32b 100644 --- a/chrome/browser/ui/gtk/hung_renderer_dialog_gtk.cc +++ b/chrome/browser/ui/gtk/hung_renderer_dialog_gtk.cc @@ -49,7 +49,7 @@ class HungRendererDialogGtk { } // TabContentsObserver overrides: - virtual void RenderViewGone() OVERRIDE { + virtual void RenderViewGone(base::TerminationStatus status) OVERRIDE { dialog_->Hide(); } virtual void TabContentsDestroyed(TabContents* tab) OVERRIDE { diff --git a/chrome/browser/ui/sad_tab_observer.cc b/chrome/browser/ui/sad_tab_observer.cc new file mode 100644 index 0000000..51a788a --- /dev/null +++ b/chrome/browser/ui/sad_tab_observer.cc @@ -0,0 +1,100 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/sad_tab_observer.h" + +#include "chrome/browser/browser_shutdown.h" +#include "content/browser/tab_contents/tab_contents.h" +#include "content/browser/tab_contents/tab_contents_view.h" +#include "content/public/browser/notification_source.h" +#include "content/public/browser/notification_types.h" + +#if defined(OS_MACOSX) +#include "chrome/browser/ui/cocoa/tab_contents/sad_tab_controller.h" +#elif defined(TOOLKIT_VIEWS) +#include "chrome/browser/ui/views/sad_tab_view.h" +#include "chrome/browser/ui/views/tab_contents/tab_contents_view_views.h" +#elif defined(TOOLKIT_GTK) +#include "chrome/browser/ui/gtk/sad_tab_gtk.h" +#endif + +SadTabObserver::SadTabObserver(TabContents* tab_contents) + : TabContentsObserver(tab_contents) { + registrar_.Add(this, content::NOTIFICATION_TAB_CONTENTS_CONNECTED, + content::Source<TabContents>(tab_contents)); +} + +SadTabObserver::~SadTabObserver() { +} + +void SadTabObserver::RenderViewGone(base::TerminationStatus status) { + // Only show the sad tab if we're not in browser shutdown, so that TabContents + // objects that are not in a browser (e.g., HTML dialogs) and thus are + // visible do not flash a sad tab page. + if (browser_shutdown::GetShutdownType() != browser_shutdown::NOT_VALID) + return; + + if (HasSadTab()) + return; + + gfx::NativeView view = AcquireSadTab(status); + tab_contents()->view()->InstallOverlayView(view); +} + +void SadTabObserver::Observe(int type, + const content::NotificationSource& source, + const content::NotificationDetails& details) { + switch (type) { + case content::NOTIFICATION_TAB_CONTENTS_CONNECTED: + if (HasSadTab()) { + tab_contents()->view()->RemoveOverlayView(); + ReleaseSadTab(); + } + break; + + default: + NOTREACHED() << "Got a notification we didn't register for."; + } +} + +gfx::NativeView SadTabObserver::AcquireSadTab(base::TerminationStatus status) { +#if defined(OS_MACOSX) + sad_tab_.reset( + sad_tab_controller_mac::CreateSadTabController(tab_contents())); + return sad_tab_controller_mac::GetViewOfSadTabController(sad_tab_.get()); +#elif defined(TOOLKIT_VIEWS) + SadTabView::Kind kind = + status == base::TERMINATION_STATUS_PROCESS_WAS_KILLED ? + SadTabView::KILLED : SadTabView::CRASHED; + views::Widget::InitParams sad_tab_params( + views::Widget::InitParams::TYPE_CONTROL); + // It is not possible to create a widget that has no parent, and later + // re-parent it. TODO(avi): This is a cheat. Can this be made cleaner? + sad_tab_params.parent_widget = + static_cast<TabContentsViewViews*>(tab_contents()->view()); + sad_tab_params.ownership = + views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; + sad_tab_.reset(new views::Widget); + sad_tab_->Init(sad_tab_params); + sad_tab_->SetContentsView(new SadTabView(tab_contents(), kind)); + return sad_tab_->GetNativeView(); +#elif defined(TOOLKIT_GTK) + sad_tab_.reset(new SadTabGtk( + tab_contents(), + status == base::TERMINATION_STATUS_PROCESS_WAS_KILLED + ? SadTabGtk::KILLED + : SadTabGtk::CRASHED)); + return sad_tab_->widget(); +#else +#error Unknown platform +#endif +} + +void SadTabObserver::ReleaseSadTab() { + sad_tab_.reset(); +} + +bool SadTabObserver::HasSadTab() { + return sad_tab_.get() != NULL; +} diff --git a/chrome/browser/ui/sad_tab_observer.h b/chrome/browser/ui/sad_tab_observer.h new file mode 100644 index 0000000..ace1044 --- /dev/null +++ b/chrome/browser/ui/sad_tab_observer.h @@ -0,0 +1,75 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_SAD_TAB_OBSERVER_H_ +#define CHROME_BROWSER_UI_SAD_TAB_OBSERVER_H_ +#pragma once + +#include "base/memory/scoped_ptr.h" +#include "content/browser/tab_contents/tab_contents_observer.h" +#include "content/public/browser/notification_observer.h" +#include "content/public/browser/notification_registrar.h" +#include "ui/gfx/native_widget_types.h" + +#if defined(OS_MACOSX) +#include "base/mac/foundation_util.h" +#endif + +#if defined(OS_MACOSX) +class SadTabController; +#elif defined(TOOLKIT_VIEWS) +namespace views { +class Widget; +} +#elif defined(TOOLKIT_GTK) +class SadTabGtk; +#endif + +// Per-tab class to manage sad tab views. +class SadTabObserver : public TabContentsObserver, + public content::NotificationObserver { + public: + explicit SadTabObserver(TabContents* tab_contents); + virtual ~SadTabObserver(); + + private: + // Platform specific function to get an instance of the sad tab page. + gfx::NativeView AcquireSadTab(base::TerminationStatus status); + + // Platform specific function to release the instance of the sad tab page. + void ReleaseSadTab(); + + // Platform specific function to determine if there is a current sad tab page. + bool HasSadTab(); + + // Overridden from TabContentsObserver: + virtual void RenderViewGone(base::TerminationStatus status) OVERRIDE; + + // Overridden from content::NotificationObserver: + virtual void Observe(int type, + const content::NotificationSource& source, + const content::NotificationDetails& details) OVERRIDE; + + // Used to get notifications about renderers coming and going. + content::NotificationRegistrar registrar_; + + // The platform views used to render the sad tab, non-NULL if visible. +#if defined(OS_MACOSX) + class ScopedPtrRelease { + public: + inline void operator()(void* x) const { + base::mac::NSObjectRelease(x); + } + }; + scoped_ptr_malloc<SadTabController, ScopedPtrRelease> sad_tab_; +#elif defined(TOOLKIT_VIEWS) + scoped_ptr<views::Widget> sad_tab_; +#elif defined(TOOLKIT_GTK) + scoped_ptr<SadTabGtk> sad_tab_; +#endif + + DISALLOW_COPY_AND_ASSIGN(SadTabObserver); +}; + +#endif // CHROME_BROWSER_UI_SAD_TAB_OBSERVER_H_ diff --git a/chrome/browser/ui/tab_contents/tab_contents_wrapper.cc b/chrome/browser/ui/tab_contents/tab_contents_wrapper.cc index eb0f311..b381a03 100644 --- a/chrome/browser/ui/tab_contents/tab_contents_wrapper.cc +++ b/chrome/browser/ui/tab_contents/tab_contents_wrapper.cc @@ -47,6 +47,7 @@ #include "chrome/browser/ui/find_bar/find_tab_helper.h" #include "chrome/browser/ui/intents/web_intent_picker_factory_impl.h" #include "chrome/browser/ui/intents/web_intent_picker_controller.h" +#include "chrome/browser/ui/sad_tab_observer.h" #include "chrome/browser/ui/search_engines/search_engine_tab_helper.h" #include "chrome/browser/ui/tab_contents/tab_contents_wrapper_delegate.h" #include "chrome/common/chrome_notification_types.h" @@ -306,6 +307,7 @@ TabContentsWrapper::TabContentsWrapper(TabContents* contents) external_protocol_observer_.reset(new ExternalProtocolObserver(contents)); plugin_observer_.reset(new PluginObserver(this)); print_preview_.reset(new printing::PrintPreviewMessageHandler(contents)); + sad_tab_observer_.reset(new SadTabObserver(contents)); // Start the in-browser thumbnailing if the feature is enabled. if (switches::IsInBrowserThumbnailingEnabled()) { thumbnail_generation_observer_.reset(new ThumbnailGenerator); diff --git a/chrome/browser/ui/tab_contents/tab_contents_wrapper.h b/chrome/browser/ui/tab_contents/tab_contents_wrapper.h index 1592e6c..33ba9a5 100644 --- a/chrome/browser/ui/tab_contents/tab_contents_wrapper.h +++ b/chrome/browser/ui/tab_contents/tab_contents_wrapper.h @@ -43,6 +43,7 @@ class PasswordManagerDelegate; class PluginObserver; class Profile; class RestoreTabHelper; +class SadTabObserver; class SearchEngineTabHelper; class TabContentsSSLHelper; class TabContentsWrapperDelegate; @@ -324,6 +325,7 @@ class TabContentsWrapper : public TabContentsObserver, scoped_ptr<ExternalProtocolObserver> external_protocol_observer_; scoped_ptr<PluginObserver> plugin_observer_; scoped_ptr<printing::PrintPreviewMessageHandler> print_preview_; + scoped_ptr<SadTabObserver> sad_tab_observer_; scoped_ptr<ThumbnailGenerator> thumbnail_generation_observer_; // TabContents (MUST BE LAST) ------------------------------------------------ diff --git a/chrome/browser/ui/views/hung_renderer_view.cc b/chrome/browser/ui/views/hung_renderer_view.cc index d397f52..0b75aa6 100644 --- a/chrome/browser/ui/views/hung_renderer_view.cc +++ b/chrome/browser/ui/views/hung_renderer_view.cc @@ -90,7 +90,7 @@ class HungPagesTableModel : public views::GroupTableModel { } // TabContentsObserver overrides: - virtual void RenderViewGone() OVERRIDE; + virtual void RenderViewGone(base::TerminationStatus status) OVERRIDE; virtual void TabContentsDestroyed(TabContents* tab) OVERRIDE; private: @@ -212,7 +212,8 @@ HungPagesTableModel::TabContentsObserverImpl::TabContentsObserverImpl( tab_(tab) { } -void HungPagesTableModel::TabContentsObserverImpl::RenderViewGone() { +void HungPagesTableModel::TabContentsObserverImpl::RenderViewGone( + base::TerminationStatus status) { model_->TabDestroyed(this); } diff --git a/chrome/browser/ui/views/tab_contents/tab_contents_view_views.cc b/chrome/browser/ui/views/tab_contents/tab_contents_view_views.cc index 08d083e..8ec3234 100644 --- a/chrome/browser/ui/views/tab_contents/tab_contents_view_views.cc +++ b/chrome/browser/ui/views/tab_contents/tab_contents_view_views.cc @@ -7,11 +7,9 @@ #include <vector> #include "base/time.h" -#include "chrome/browser/browser_shutdown.h" #include "chrome/browser/ui/constrained_window.h" #include "chrome/browser/ui/constrained_window_tab_helper.h" #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" -#include "chrome/browser/ui/views/sad_tab_view.h" #include "chrome/browser/ui/views/tab_contents/native_tab_contents_view.h" #include "chrome/browser/ui/views/tab_contents/render_view_context_menu_views.h" #include "content/browser/renderer_host/render_process_host.h" @@ -39,9 +37,9 @@ using WebKit::WebInputEvent; TabContentsViewViews::TabContentsViewViews(TabContents* tab_contents) : tab_contents_(tab_contents), native_tab_contents_view_(NULL), - sad_tab_widget_(NULL), close_tab_after_drag_ends_(false), - focus_manager_(NULL) { + focus_manager_(NULL), + overlaid_view_(NULL) { last_focused_view_storage_id_ = views::ViewStorage::GetInstance()->CreateStorageID(); } @@ -89,12 +87,6 @@ RenderWidgetHostView* TabContentsViewViews::CreateViewForWidget( return render_widget_host->view(); } - // If we were showing sad tab, remove it now. - if (sad_tab_widget_) { - sad_tab_widget_->Close(); - sad_tab_widget_ = NULL; - } - return native_tab_contents_view_->CreateRenderWidgetHostView( render_widget_host); } @@ -130,26 +122,6 @@ void TabContentsViewViews::SetPageTitle(const string16& title) { void TabContentsViewViews::OnTabCrashed(base::TerminationStatus status, int /* error_code */) { - // Only show the sad tab if we're not in browser shutdown, so that TabContents - // objects that are not in a browser (e.g., HTML dialogs) and thus are - // visible do not flash a sad tab page. - if (browser_shutdown::GetShutdownType() != browser_shutdown::NOT_VALID) - return; - - // Note that it's possible to get this message after the window was destroyed. - if (GetNativeView()) { - SadTabView::Kind kind = - status == base::TERMINATION_STATUS_PROCESS_WAS_KILLED ? - SadTabView::KILLED : SadTabView::CRASHED; - views::Widget::InitParams sad_tab_widget_params( - views::Widget::InitParams::TYPE_CONTROL); - sad_tab_widget_params.parent_widget = this; - sad_tab_widget_params.bounds = - gfx::Rect(GetClientAreaScreenBounds().size()); - sad_tab_widget_ = new views::Widget; - sad_tab_widget_->Init(sad_tab_widget_params); - sad_tab_widget_->SetContentsView(new SadTabView(tab_contents_, kind)); - } } void TabContentsViewViews::SizeContents(const gfx::Size& size) { @@ -173,8 +145,8 @@ void TabContentsViewViews::Focus() { return; } - if (tab_contents_->is_crashed() && sad_tab_widget_ != NULL) { - sad_tab_widget_->GetContentsView()->RequestFocus(); + if (overlaid_view_) { + overlaid_view_->GetContentsView()->RequestFocus(); return; } @@ -285,6 +257,19 @@ void TabContentsViewViews::GetViewBounds(gfx::Rect* out) const { *out = GetWindowScreenBounds(); } +void TabContentsViewViews::InstallOverlayView(gfx::NativeView view) { + DCHECK(!overlaid_view_); + views::Widget::ReparentNativeView(view, GetNativeView()); + overlaid_view_ = views::Widget::GetWidgetForNativeView(view); + overlaid_view_->SetBounds(gfx::Rect(GetClientAreaScreenBounds().size())); +} + +void TabContentsViewViews::RemoveOverlayView() { + DCHECK(overlaid_view_); + overlaid_view_->Close(); + overlaid_view_ = NULL; +} + void TabContentsViewViews::UpdateDragCursor(WebDragOperation operation) { native_tab_contents_view_->SetDragCursor(operation); } @@ -385,7 +370,7 @@ TabContents* TabContentsViewViews::GetTabContents() { } bool TabContentsViewViews::IsShowingSadTab() const { - return tab_contents_->is_crashed() && sad_tab_widget_; + return tab_contents_->is_crashed() && overlaid_view_; } void TabContentsViewViews::OnNativeTabContentsViewShown() { @@ -472,7 +457,7 @@ void TabContentsViewViews::OnNativeWidgetVisibilityChanged(bool visible) { void TabContentsViewViews::OnNativeWidgetSizeChanged( const gfx::Size& new_size) { - if (sad_tab_widget_) - sad_tab_widget_->SetBounds(gfx::Rect(new_size)); + if (overlaid_view_) + overlaid_view_->SetBounds(gfx::Rect(new_size)); views::Widget::OnNativeWidgetSizeChanged(new_size); } diff --git a/chrome/browser/ui/views/tab_contents/tab_contents_view_views.h b/chrome/browser/ui/views/tab_contents/tab_contents_view_views.h index 413d01e..b11f1d3 100644 --- a/chrome/browser/ui/views/tab_contents/tab_contents_view_views.h +++ b/chrome/browser/ui/views/tab_contents/tab_contents_view_views.h @@ -16,7 +16,6 @@ class ConstrainedWindowGtk; class NativeTabContentsView; class RenderViewContextMenuViews; -class SadTabView; class SkBitmap; struct WebDropData; namespace gfx { @@ -28,8 +27,6 @@ class Widget; } // Views-specific implementation of the TabContentsView. -// TODO(beng): Remove last remnants of Windows-specificity, and make this -// subclass Widget. class TabContentsViewViews : public views::Widget, public TabContentsView, public internal::NativeTabContentsViewDelegate { @@ -75,6 +72,8 @@ class TabContentsViewViews : public views::Widget, virtual bool IsEventTracking() const; virtual void CloseTabAfterEventTracking(); virtual void GetViewBounds(gfx::Rect* out) const OVERRIDE; + virtual void InstallOverlayView(gfx::NativeView view) OVERRIDE; + virtual void RemoveOverlayView() OVERRIDE; // Implementation of RenderViewHostDelegate::View. virtual void CreateNewWindow( @@ -152,11 +151,6 @@ class TabContentsViewViews : public views::Widget, NativeTabContentsView* native_tab_contents_view_; - // If non-null we're showing a sad tab. SadTabView is hosted in a separate - // widget so that TabContentsViewViews does not need to draw, and can be - // created without a texture. - views::Widget* sad_tab_widget_; - // The id used in the ViewStorage to store the last focused view. int last_focused_view_storage_id_; @@ -174,6 +168,10 @@ class TabContentsViewViews : public views::Widget, // accessible when un-parented. mutable const views::FocusManager* focus_manager_; + // The overlaid view. Owned by the caller of |InstallOverlayView|; this is a + // weak reference. + views::Widget* overlaid_view_; + DISALLOW_COPY_AND_ASSIGN(TabContentsViewViews); }; diff --git a/chrome/browser/ui/virtual_keyboard/virtual_keyboard_manager.cc b/chrome/browser/ui/virtual_keyboard/virtual_keyboard_manager.cc index fe7b26b..0d90627 100644 --- a/chrome/browser/ui/virtual_keyboard/virtual_keyboard_manager.cc +++ b/chrome/browser/ui/virtual_keyboard/virtual_keyboard_manager.cc @@ -115,7 +115,7 @@ class KeyboardWidget // Overridden from TabContentsObserver. virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; - virtual void RenderViewGone() OVERRIDE; + virtual void RenderViewGone(base::TerminationStatus status) OVERRIDE; void OnRequest(const ExtensionHostMsg_Request_Params& params); // Overridden from TextInputTypeObserver. @@ -347,7 +347,7 @@ bool KeyboardWidget::OnMessageReceived(const IPC::Message& message) { return handled; } -void KeyboardWidget::RenderViewGone() { +void KeyboardWidget::RenderViewGone(base::TerminationStatus status) { // Reload the keyboard if it crashes. dom_view_->LoadURL(keyboard_url_); dom_view_->SchedulePaint(); diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 178bc21..b1f107a 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -3187,6 +3187,8 @@ 'browser/ui/panels/panel_window_controller_cocoa.mm', 'browser/ui/profile_error_dialog.cc', 'browser/ui/profile_error_dialog.h', + 'browser/ui/sad_tab_observer.cc', + 'browser/ui/sad_tab_observer.h', 'browser/ui/search_engines/edit_search_engine_controller.cc', 'browser/ui/search_engines/edit_search_engine_controller.h', 'browser/ui/search_engines/keyword_editor_controller.cc', diff --git a/content/browser/renderer_host/render_widget_host_view_mac.mm b/content/browser/renderer_host/render_widget_host_view_mac.mm index 2322fb1..f559281 100644 --- a/content/browser/renderer_host/render_widget_host_view_mac.mm +++ b/content/browser/renderer_host/render_widget_host_view_mac.mm @@ -588,7 +588,6 @@ void RenderWidgetHostViewMac::DidUpdateBackingStore( void RenderWidgetHostViewMac::RenderViewGone(base::TerminationStatus status, int error_code) { - // TODO(darin): keep this around, and draw sad-tab into it. Destroy(); } diff --git a/content/browser/renderer_host/render_widget_host_view_win.cc b/content/browser/renderer_host/render_widget_host_view_win.cc index cd14d83..59257b0 100644 --- a/content/browser/renderer_host/render_widget_host_view_win.cc +++ b/content/browser/renderer_host/render_widget_host_view_win.cc @@ -793,7 +793,6 @@ void RenderWidgetHostViewWin::DidUpdateBackingStore( void RenderWidgetHostViewWin::RenderViewGone(base::TerminationStatus status, int error_code) { - // TODO(darin): keep this around, and draw sad-tab into it. UpdateCursorIfOverSelf(); Destroy(); } diff --git a/content/browser/tab_contents/tab_contents.cc b/content/browser/tab_contents/tab_contents.cc index f84158a..2c1e8ff 100644 --- a/content/browser/tab_contents/tab_contents.cc +++ b/content/browser/tab_contents/tab_contents.cc @@ -1487,7 +1487,9 @@ void TabContents::RenderViewGone(RenderViewHost* rvh, SetIsCrashed(status, error_code); view()->OnTabCrashed(crashed_status(), crashed_error_code()); - FOR_EACH_OBSERVER(TabContentsObserver, observers_, RenderViewGone()); + FOR_EACH_OBSERVER(TabContentsObserver, + observers_, + RenderViewGone(crashed_status())); } void TabContents::RenderViewDeleted(RenderViewHost* rvh) { diff --git a/content/browser/tab_contents/tab_contents_observer.cc b/content/browser/tab_contents/tab_contents_observer.cc index 42d6fbe..29ab1a5 100644 --- a/content/browser/tab_contents/tab_contents_observer.cc +++ b/content/browser/tab_contents/tab_contents_observer.cc @@ -17,7 +17,7 @@ void TabContentsObserver::RenderViewDeleted(RenderViewHost* render_view_host) { void TabContentsObserver::RenderViewReady() { } -void TabContentsObserver::RenderViewGone() { +void TabContentsObserver::RenderViewGone(base::TerminationStatus status) { } void TabContentsObserver::NavigateToPendingEntry( diff --git a/content/browser/tab_contents/tab_contents_observer.h b/content/browser/tab_contents/tab_contents_observer.h index cbeecd0..4155753 100644 --- a/content/browser/tab_contents/tab_contents_observer.h +++ b/content/browser/tab_contents/tab_contents_observer.h @@ -5,6 +5,7 @@ #ifndef CONTENT_BROWSER_TAB_CONTENTS_TAB_CONTENTS_OBSERVER_H_ #define CONTENT_BROWSER_TAB_CONTENTS_TAB_CONTENTS_OBSERVER_H_ +#include "base/process_util.h" #include "content/browser/tab_contents/navigation_controller.h" #include "content/common/content_export.h" #include "content/public/common/page_transition_types.h" @@ -22,7 +23,7 @@ class CONTENT_EXPORT TabContentsObserver : public IPC::Channel::Listener, virtual void RenderViewCreated(RenderViewHost* render_view_host); virtual void RenderViewDeleted(RenderViewHost* render_view_host); virtual void RenderViewReady(); - virtual void RenderViewGone(); + virtual void RenderViewGone(base::TerminationStatus status); virtual void NavigateToPendingEntry( const GURL& url, NavigationController::ReloadType reload_type); diff --git a/content/browser/tab_contents/tab_contents_view.h b/content/browser/tab_contents/tab_contents_view.h index 05da7c6..10535ca 100644 --- a/content/browser/tab_contents/tab_contents_view.h +++ b/content/browser/tab_contents/tab_contents_view.h @@ -66,8 +66,7 @@ class CONTENT_EXPORT TabContentsView : public RenderViewHostDelegate::View { // trying to find a specific window. virtual void SetPageTitle(const string16& title) = 0; - // Used to notify the view that a tab has crashed so each platform can - // prepare the sad tab. + // Used to notify the view that a tab has crashed. virtual void OnTabCrashed(base::TerminationStatus status, int error_code) = 0; @@ -117,6 +116,18 @@ class CONTENT_EXPORT TabContentsView : public RenderViewHostDelegate::View { // TODO(beng): Return a rect rather than using an out param. virtual void GetViewBounds(gfx::Rect* out) const = 0; + // --------------------------------------------------------------------------- + // Functions for embedders. + // TODO(avi): Figure out where these go on the API surface. + + // Installs a native view to cover the visible web contents. Removed by + // |RemoveOverlayView|. This is not a transfer of ownership, and the view must + // remain valid until removed. + virtual void InstallOverlayView(gfx::NativeView view) = 0; + + // Removes the native overlay view installed by |InstallOverlayView|. + virtual void RemoveOverlayView() = 0; + protected: TabContentsView(); // Abstract interface. diff --git a/content/browser/tab_contents/tab_contents_view_win.cc b/content/browser/tab_contents/tab_contents_view_win.cc index 45d4c0f..0dc9826f 100644 --- a/content/browser/tab_contents/tab_contents_view_win.cc +++ b/content/browser/tab_contents/tab_contents_view_win.cc @@ -74,6 +74,8 @@ void TabContentsViewWin::SetPageTitle(const string16& title) { void TabContentsViewWin::OnTabCrashed(base::TerminationStatus status, int error_code) { + // TODO(avi): No other TCV implementation does anything in this callback. Can + // this be moved elsewhere so that |OnTabCrashed| can be removed everywhere? view_ = NULL; } @@ -147,6 +149,14 @@ void TabContentsViewWin::GetViewBounds(gfx::Rect* out) const { *out = gfx::Rect(r); } +void TabContentsViewWin::InstallOverlayView(gfx::NativeView view) { + NOTREACHED(); +} + +void TabContentsViewWin::RemoveOverlayView() { + NOTREACHED(); +} + void TabContentsViewWin::CreateNewWindow( int route_id, const ViewHostMsg_CreateWindow_Params& params) { diff --git a/content/browser/tab_contents/tab_contents_view_win.h b/content/browser/tab_contents/tab_contents_view_win.h index d603899..f726eba 100644 --- a/content/browser/tab_contents/tab_contents_view_win.h +++ b/content/browser/tab_contents/tab_contents_view_win.h @@ -50,6 +50,8 @@ class TabContentsViewWin : public TabContentsView, virtual bool IsEventTracking() const OVERRIDE; virtual void CloseTabAfterEventTracking() OVERRIDE; virtual void GetViewBounds(gfx::Rect* out) const OVERRIDE; + virtual void InstallOverlayView(gfx::NativeView view) OVERRIDE; + virtual void RemoveOverlayView() OVERRIDE; // Implementation of RenderViewHostDelegate::View. virtual void CreateNewWindow( diff --git a/content/test/test_tab_contents_view.cc b/content/test/test_tab_contents_view.cc index 216e163..25ddcec 100644 --- a/content/test/test_tab_contents_view.cc +++ b/content/test/test_tab_contents_view.cc @@ -126,3 +126,9 @@ void TestTabContentsView::CloseTabAfterEventTracking() { void TestTabContentsView::GetViewBounds(gfx::Rect* out) const { } + +void TestTabContentsView::InstallOverlayView(gfx::NativeView view) { +} + +void TestTabContentsView::RemoveOverlayView() { +} diff --git a/content/test/test_tab_contents_view.h b/content/test/test_tab_contents_view.h index 90af73c..04c1b10 100644 --- a/content/test/test_tab_contents_view.h +++ b/content/test/test_tab_contents_view.h @@ -65,6 +65,8 @@ class TestTabContentsView : public TabContentsView { virtual bool IsEventTracking() const OVERRIDE; virtual void CloseTabAfterEventTracking() OVERRIDE; virtual void GetViewBounds(gfx::Rect* out) const OVERRIDE; + virtual void InstallOverlayView(gfx::NativeView view) OVERRIDE; + virtual void RemoveOverlayView() OVERRIDE; private: DISALLOW_COPY_AND_ASSIGN(TestTabContentsView); |