summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoravi@chromium.org <avi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-11-15 15:04:27 +0000
committeravi@chromium.org <avi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-11-15 15:04:27 +0000
commit9cddb1a26ca716f6e3f42bc8d7180a2809afea69 (patch)
tree62c18c1dec6a8c9efda6ddb0054441d51054cccc
parentb60ae4b0ea0bcdd455e45a4971da0ddfc6464c69 (diff)
downloadchromium_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
-rw-r--r--chrome/browser/automation/automation_tab_helper.cc2
-rw-r--r--chrome/browser/automation/automation_tab_helper.h10
-rw-r--r--chrome/browser/infobars/infobar_tab_helper.cc2
-rw-r--r--chrome/browser/infobars/infobar_tab_helper.h2
-rw-r--r--chrome/browser/notifications/balloon_host.cc2
-rw-r--r--chrome/browser/notifications/balloon_host.h2
-rw-r--r--chrome/browser/prerender/prerender_browsertest.cc4
-rw-r--r--chrome/browser/prerender/prerender_contents.cc2
-rw-r--r--chrome/browser/prerender/prerender_contents.h2
-rw-r--r--chrome/browser/printing/print_view_manager.cc2
-rw-r--r--chrome/browser/printing/print_view_manager.h4
-rw-r--r--chrome/browser/tab_contents/background_contents.cc4
-rw-r--r--chrome/browser/tab_contents/background_contents.h2
-rw-r--r--chrome/browser/tab_contents/tab_contents_view_gtk.cc54
-rw-r--r--chrome/browser/tab_contents/tab_contents_view_gtk.h24
-rw-r--r--chrome/browser/tab_contents/tab_contents_view_mac.h24
-rw-r--r--chrome/browser/tab_contents/tab_contents_view_mac.mm54
-rw-r--r--chrome/browser/ui/cocoa/browser_window_controller.mm2
-rw-r--r--chrome/browser/ui/cocoa/hung_renderer_controller.mm2
-rw-r--r--chrome/browser/ui/cocoa/tab_contents/sad_tab_controller.h25
-rw-r--r--chrome/browser/ui/cocoa/tab_contents/sad_tab_controller.mm26
-rw-r--r--chrome/browser/ui/cocoa/tab_contents/sad_tab_controller_unittest.mm6
-rw-r--r--chrome/browser/ui/cocoa/tab_contents/sad_tab_view.mm6
-rw-r--r--chrome/browser/ui/gtk/hung_renderer_dialog_gtk.cc2
-rw-r--r--chrome/browser/ui/sad_tab_observer.cc100
-rw-r--r--chrome/browser/ui/sad_tab_observer.h75
-rw-r--r--chrome/browser/ui/tab_contents/tab_contents_wrapper.cc2
-rw-r--r--chrome/browser/ui/tab_contents/tab_contents_wrapper.h2
-rw-r--r--chrome/browser/ui/views/hung_renderer_view.cc5
-rw-r--r--chrome/browser/ui/views/tab_contents/tab_contents_view_views.cc55
-rw-r--r--chrome/browser/ui/views/tab_contents/tab_contents_view_views.h14
-rw-r--r--chrome/browser/ui/virtual_keyboard/virtual_keyboard_manager.cc4
-rw-r--r--chrome/chrome_browser.gypi2
-rw-r--r--content/browser/renderer_host/render_widget_host_view_mac.mm1
-rw-r--r--content/browser/renderer_host/render_widget_host_view_win.cc1
-rw-r--r--content/browser/tab_contents/tab_contents.cc4
-rw-r--r--content/browser/tab_contents/tab_contents_observer.cc2
-rw-r--r--content/browser/tab_contents/tab_contents_observer.h3
-rw-r--r--content/browser/tab_contents/tab_contents_view.h15
-rw-r--r--content/browser/tab_contents/tab_contents_view_win.cc10
-rw-r--r--content/browser/tab_contents/tab_contents_view_win.h2
-rw-r--r--content/test/test_tab_contents_view.cc6
-rw-r--r--content/test/test_tab_contents_view.h2
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);