summaryrefslogtreecommitdiffstats
path: root/chrome/browser/gtk
diff options
context:
space:
mode:
authorwillchan@chromium.org <willchan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-06 18:45:56 +0000
committerwillchan@chromium.org <willchan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-06 18:45:56 +0000
commit7b9627d188d04b224f972fae709e7cb4f61ae504 (patch)
tree4d37368f881c9dae023e5172013e87f0b7c58676 /chrome/browser/gtk
parent72baf67602ab1dbf95c34a5d8301e0ac5f8b8b41 (diff)
downloadchromium_src-7b9627d188d04b224f972fae709e7cb4f61ae504.zip
chromium_src-7b9627d188d04b224f972fae709e7cb4f61ae504.tar.gz
chromium_src-7b9627d188d04b224f972fae709e7cb4f61ae504.tar.bz2
Render a "sad tab" on tab crash.
Uses the NotificationRegistrar to notice TAB_CONTENTS_[DIS]CONNECTED events. When it disconnects, add a SadTabGtk to the TabContentsView. Delete it when the tab contents reconnects. BUG=http://www.crbug.com/11081 TEST=Open http://about:crash. Verify that the sad tab renders properly. Navigate to another page to make sure the SadTabGtk is correctly replaced with a new RenderWidgetHostViewGtk. Review URL: http://codereview.chromium.org/111003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@15435 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/gtk')
-rw-r--r--chrome/browser/gtk/browser_window_gtk.cc7
-rw-r--r--chrome/browser/gtk/sad_tab_gtk.cc148
-rw-r--r--chrome/browser/gtk/sad_tab_gtk.h51
3 files changed, 203 insertions, 3 deletions
diff --git a/chrome/browser/gtk/browser_window_gtk.cc b/chrome/browser/gtk/browser_window_gtk.cc
index dcc8c98..a1ded9e 100644
--- a/chrome/browser/gtk/browser_window_gtk.cc
+++ b/chrome/browser/gtk/browser_window_gtk.cc
@@ -213,9 +213,10 @@ gboolean HandleCustomAccelerator(guint keyval, GdkModifierType modifier,
gboolean OnKeyPress(GtkWindow* window, GdkEventKey* event, Browser* browser) {
TabContents* current_tab_contents =
browser->tabstrip_model()->GetSelectedTabContents();
- // If there is no current tab contents or it is not focused then let the
- // default GtkWindow key handler run.
- if (!current_tab_contents ||
+ // If there is no current tab contents or its view is gone (if the renderview
+ // crashed) or it is not focused then let the default GtkWindow key handler
+ // run.
+ if (!current_tab_contents || !current_tab_contents->GetContentNativeView() ||
!gtk_widget_is_focus(current_tab_contents->GetContentNativeView())) {
return HandleCustomAccelerator(event->keyval,
static_cast<GdkModifierType>(event->state), browser);
diff --git a/chrome/browser/gtk/sad_tab_gtk.cc b/chrome/browser/gtk/sad_tab_gtk.cc
new file mode 100644
index 0000000..594b2ad
--- /dev/null
+++ b/chrome/browser/gtk/sad_tab_gtk.cc
@@ -0,0 +1,148 @@
+// Copyright (c) 2009 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/gtk/sad_tab_gtk.h"
+
+#include <string>
+
+#include "app/gfx/chrome_canvas.h"
+#include "app/gfx/chrome_font.h"
+#include "app/l10n_util.h"
+#include "app/resource_bundle.h"
+#include "base/gfx/size.h"
+#include "base/lazy_instance.h"
+#include "grit/generated_resources.h"
+#include "grit/theme_resources.h"
+#include "skia/ext/skia_utils.h"
+#include "skia/include/SkGradientShader.h"
+
+namespace {
+
+// The y offset from the center at which to paint the icon.
+const int kSadTabOffset = -64;
+// The spacing between the icon and the title.
+const int kIconTitleSpacing = 20;
+// The spacing between the title and the message.
+const int kTitleMessageSpacing = 15;
+const SkColor kTitleTextColor = SK_ColorWHITE;
+const SkColor kMessageTextColor = SK_ColorWHITE;
+const SkColor kBackgroundColor = SkColorSetRGB(35, 48, 64);
+const SkColor kBackgroundEndColor = SkColorSetRGB(35, 48, 64);
+
+struct SadTabGtkConstants {
+ SadTabGtkConstants()
+ : sad_tab_bitmap(
+ ResourceBundle::GetSharedInstance().GetBitmapNamed(IDR_SAD_TAB)),
+ title_font(
+ ResourceBundle::GetSharedInstance().GetFont(
+ ResourceBundle::BaseFont).DeriveFont(2, ChromeFont::BOLD)),
+ message_font(
+ ResourceBundle::GetSharedInstance().GetFont(
+ ResourceBundle::BaseFont).DeriveFont(1)),
+ title(l10n_util::GetString(IDS_SAD_TAB_TITLE)),
+ message(l10n_util::GetString(IDS_SAD_TAB_MESSAGE)) {}
+
+ const SkBitmap* sad_tab_bitmap;
+ ChromeFont title_font;
+ ChromeFont message_font;
+ std::wstring title;
+ std::wstring message;
+};
+
+base::LazyInstance<SadTabGtkConstants>
+ g_sad_tab_constants(base::LINKER_INITIALIZED);
+
+} // namespace
+
+SadTabGtk::SadTabGtk()
+ : width_(0),
+ height_(0),
+ title_y_(0),
+ message_y_(0),
+ widget_(gtk_drawing_area_new()) {
+ gtk_widget_set_double_buffered(widget_.get(), FALSE);
+ g_signal_connect(widget_.get(), "expose-event",
+ G_CALLBACK(OnExposeThunk), this);
+ g_signal_connect(widget_.get(), "configure-event",
+ G_CALLBACK(OnConfigureThunk), this);
+}
+
+SadTabGtk::~SadTabGtk() {
+ widget_.Destroy();
+}
+
+// static
+gboolean SadTabGtk::OnExposeThunk(GtkWidget* widget,
+ GdkEventExpose* event,
+ const SadTabGtk* sad_tab) {
+ return sad_tab->OnExpose(widget, event);
+}
+
+gboolean SadTabGtk::OnExpose(GtkWidget* widget, GdkEventExpose* event) const {
+ ChromeCanvasPaint canvas(event);
+ SkPaint paint;
+ paint.setShader(skia::CreateGradientShader(0, height_,
+ kBackgroundColor,
+ kBackgroundEndColor))->safeUnref();
+ paint.setStyle(SkPaint::kFill_Style);
+ canvas.drawRectCoords(0, 0,
+ SkIntToScalar(width_),
+ SkIntToScalar(height_),
+ paint);
+
+ const SadTabGtkConstants& sad_tab_constants =
+ g_sad_tab_constants.Get();
+
+ // Paint the sad tab icon.
+ canvas.DrawBitmapInt(*sad_tab_constants.sad_tab_bitmap,
+ icon_bounds_.x(),
+ icon_bounds_.y());
+
+ // Paint the "Aw, snap!"
+ canvas.DrawStringInt(sad_tab_constants.title,
+ sad_tab_constants.title_font,
+ kTitleTextColor,
+ 0,
+ title_y_,
+ width_,
+ sad_tab_constants.title_font.height(),
+ ChromeCanvas::TEXT_ALIGN_CENTER);
+
+ // Paint the explanatory message.
+ canvas.DrawStringInt(sad_tab_constants.message,
+ sad_tab_constants.message_font,
+ kMessageTextColor,
+ 0,
+ message_y_,
+ width_,
+ sad_tab_constants.message_font.height(),
+ ChromeCanvas::TEXT_ALIGN_CENTER);
+ return TRUE;
+}
+
+// static
+gboolean SadTabGtk::OnConfigureThunk(GtkWidget* widget,
+ GdkEventConfigure* event,
+ SadTabGtk* sad_tab) {
+ return sad_tab->OnConfigure(widget, event);
+}
+
+gboolean SadTabGtk::OnConfigure(GtkWidget* widget, GdkEventConfigure* event) {
+ const SadTabGtkConstants& sad_tab_constants =
+ g_sad_tab_constants.Get();
+ width_ = event->width;
+ height_= event->height;
+ int icon_width = sad_tab_constants.sad_tab_bitmap->width();
+ int icon_height = sad_tab_constants.sad_tab_bitmap->height();
+ int icon_x = (event->width - icon_width) / 2;
+ int icon_y = ((event->height - icon_height) / 2) + kSadTabOffset;
+ icon_bounds_.SetRect(icon_x, icon_y, icon_width, icon_height);
+
+ title_y_ =
+ icon_bounds_.bottom() + kIconTitleSpacing;
+ int title_height = sad_tab_constants.title_font.height();
+ message_y_ =
+ title_y_ + title_height + kTitleMessageSpacing;
+ return TRUE;
+}
diff --git a/chrome/browser/gtk/sad_tab_gtk.h b/chrome/browser/gtk/sad_tab_gtk.h
new file mode 100644
index 0000000..aed2454
--- /dev/null
+++ b/chrome/browser/gtk/sad_tab_gtk.h
@@ -0,0 +1,51 @@
+// Copyright (c) 2009 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_GTK_SAD_TAB_GTK_H_
+#define CHROME_BROWSER_GTK_SAD_TAB_GTK_H_
+
+#include <gtk/gtk.h>
+
+#include "base/basictypes.h"
+#include "base/gfx/rect.h"
+#include "chrome/common/owned_widget_gtk.h"
+
+class SadTabGtk {
+ public:
+ SadTabGtk();
+ ~SadTabGtk();
+
+ GtkWidget* widget() { return widget_.get(); }
+
+ private:
+ // expose-event handler that redraws the SadTabGtk.
+ static gboolean OnExposeThunk(GtkWidget* widget,
+ GdkEventExpose* event,
+ const SadTabGtk* sad_tab);
+
+ gboolean OnExpose(GtkWidget* widget, GdkEventExpose* event) const;
+
+ // configure-event handler that gets the new bounds of the SadTabGtk.
+ static gboolean OnConfigureThunk(GtkWidget* widget,
+ GdkEventConfigure* event,
+ SadTabGtk* sad_tab);
+
+ gboolean OnConfigure(GtkWidget* widget, GdkEventConfigure* event);
+
+ // Track the view's width and height from configure-event signals.
+ int width_;
+ int height_;
+
+ // Regions within the display for different components, set on a
+ // configure-event. These are relative to the bounds of the widget.
+ gfx::Rect icon_bounds_;
+ int title_y_;
+ int message_y_;
+
+ OwnedWidgetGtk widget_;
+
+ DISALLOW_COPY_AND_ASSIGN(SadTabGtk);
+};
+
+#endif // CHROME_BROWSER_GTK_SAD_TAB_GTK_H__