summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/cocoa/sad_tab_view.h22
-rw-r--r--chrome/browser/cocoa/sad_tab_view.mm74
-rw-r--r--chrome/browser/tab_contents/web_contents_view_mac.h18
-rw-r--r--chrome/browser/tab_contents/web_contents_view_mac.mm33
-rw-r--r--chrome/chrome.xcodeproj/project.pbxproj10
-rw-r--r--chrome/common/temp_scaffolding_stubs.h2
6 files changed, 157 insertions, 2 deletions
diff --git a/chrome/browser/cocoa/sad_tab_view.h b/chrome/browser/cocoa/sad_tab_view.h
new file mode 100644
index 0000000..ffe57a5
--- /dev/null
+++ b/chrome/browser/cocoa/sad_tab_view.h
@@ -0,0 +1,22 @@
+// 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_COCOA_SAD_TAB_VIEW_H_
+#define CHROME_BROWSER_COCOA_SAD_TAB_VIEW_H_
+
+#include "chrome/browser/cocoa/event_view.h"
+
+#import <Cocoa/Cocoa.h>
+
+// A view that displays the "sad tab".
+
+@interface SadTabView : EventView {
+ @private
+}
+
+// Designated initializer is -initWithFrame: .
+
+@end
+
+#endif // CHROME_BROWSER_COCOA_SAD_TAB_VIEW_H_
diff --git a/chrome/browser/cocoa/sad_tab_view.mm b/chrome/browser/cocoa/sad_tab_view.mm
new file mode 100644
index 0000000..b862d53
--- /dev/null
+++ b/chrome/browser/cocoa/sad_tab_view.mm
@@ -0,0 +1,74 @@
+// 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/cocoa/sad_tab_view.h"
+
+static const int kSadTabOffset = -64;
+static const int kIconTitleSpacing = 20;
+static const int kTitleMessageSpacing = 15;
+
+@implementation SadTabView
+
+- (void)drawRect:(NSRect)dirtyRect {
+ NSImage* sadTabImage = [NSImage imageNamed:@"sadtab"];
+ NSString* title = @"Aw, Snap!"; // TODO(avi):localize
+ NSString* message = @"Something went wrong while displaying this webpage. "
+ "To continue, press Reload or go to another page.";
+
+ NSColor* textColor = [NSColor whiteColor];
+ NSColor* backgroundColor = [NSColor colorWithCalibratedRed:(35.0f/255.0f)
+ green:(48.0f/255.0f)
+ blue:(64.0f/255.0f)
+ alpha:1.0];
+
+ // Layout
+ NSFont* titleFont = [NSFont boldSystemFontOfSize:[NSFont systemFontSize]];
+ NSFont* messageFont = [NSFont systemFontOfSize:[NSFont smallSystemFontSize]];
+
+ NSDictionary* titleAttrs = [NSDictionary dictionaryWithObjectsAndKeys:
+ titleFont, NSFontAttributeName,
+ textColor, NSForegroundColorAttributeName,
+ nil];
+ NSDictionary* messageAttrs = [NSDictionary dictionaryWithObjectsAndKeys:
+ messageFont, NSFontAttributeName,
+ textColor, NSForegroundColorAttributeName,
+ nil];
+
+ NSAttributedString* titleString =
+ [[[NSAttributedString alloc] initWithString:title
+ attributes:titleAttrs] autorelease];
+ NSAttributedString* messageString =
+ [[[NSAttributedString alloc] initWithString:message
+ attributes:messageAttrs] autorelease];
+
+ NSRect viewBounds = [self bounds];
+
+ NSSize sadTabImageSize = [sadTabImage size];
+ CGFloat iconWidth = sadTabImageSize.width;
+ CGFloat iconHeight = sadTabImageSize.height;
+ CGFloat iconX = (viewBounds.size.width - iconWidth) / 2;
+ CGFloat iconY =
+ ((viewBounds.size.height - iconHeight) / 2) - kSadTabOffset;
+
+ NSSize titleSize = [titleString size];
+ CGFloat titleX = (viewBounds.size.width - titleSize.width) / 2;
+ CGFloat titleY = iconY - kIconTitleSpacing - titleSize.height;
+
+ NSSize messageSize = [messageString size];
+ CGFloat messageX = (viewBounds.size.width - messageSize.width) / 2;
+ CGFloat messageY = titleY - kTitleMessageSpacing - messageSize.height;
+
+ // Paint
+ [backgroundColor set];
+ NSRectFill(viewBounds);
+
+ [sadTabImage drawAtPoint:NSMakePoint(iconX, iconY)
+ fromRect:NSZeroRect
+ operation:NSCompositeSourceOver
+ fraction:1.0f];
+ [titleString drawAtPoint:NSMakePoint(titleX, titleY)];
+ [messageString drawAtPoint:NSMakePoint(messageX, messageY)];
+}
+
+@end
diff --git a/chrome/browser/tab_contents/web_contents_view_mac.h b/chrome/browser/tab_contents/web_contents_view_mac.h
index ec3b613..1ea5144 100644
--- a/chrome/browser/tab_contents/web_contents_view_mac.h
+++ b/chrome/browser/tab_contents/web_contents_view_mac.h
@@ -10,8 +10,10 @@
#include "base/gfx/size.h"
#include "base/scoped_cftyperef.h"
#include "chrome/browser/tab_contents/web_contents_view.h"
+#include "chrome/common/notification_registrar.h"
class FindBarMac;
+@class SadTabView;
@interface WebContentsViewCocoa : NSView {
}
@@ -20,7 +22,8 @@ class FindBarMac;
// Mac-specific implementation of the WebContentsView. It owns an NSView that
// contains all of the contents of the tab and associated child views.
-class WebContentsViewMac : public WebContentsView {
+class WebContentsViewMac : public WebContentsView,
+ public NotificationObserver {
public:
// The corresponding WebContents is passed in the constructor, and manages our
// lifetime. This doesn't need to be the case, but is this way currently
@@ -70,6 +73,12 @@ class WebContentsViewMac : public WebContentsView {
int active_match_ordinal,
bool final_update);
+ // NotificationObserver implementation ---------------------------------------
+
+ virtual void Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details);
+
private:
// ---------------------------------------------------------------------------
@@ -82,6 +91,13 @@ class WebContentsViewMac : public WebContentsView {
// non-NULL, it may or may not be visible.
scoped_ptr<FindBarMac> find_bar_;
+ // Used to get notifications about renderers coming and going.
+ NotificationRegistrar registrar_;
+
+ // Used to render the sad tab. This will be non-NULL only when the sad tab is
+ // visible.
+ scoped_cftyperef<SadTabView*> sad_tab_;
+
DISALLOW_COPY_AND_ASSIGN(WebContentsViewMac);
};
diff --git a/chrome/browser/tab_contents/web_contents_view_mac.mm b/chrome/browser/tab_contents/web_contents_view_mac.mm
index 2026b00..e59338a 100644
--- a/chrome/browser/tab_contents/web_contents_view_mac.mm
+++ b/chrome/browser/tab_contents/web_contents_view_mac.mm
@@ -5,6 +5,7 @@
#include "chrome/browser/tab_contents/web_contents_view_mac.h"
#include "chrome/browser/browser.h" // TODO(beng): this dependency is awful.
+#include "chrome/browser/cocoa/sad_tab_view.h"
#include "chrome/browser/renderer_host/render_widget_host.h"
#include "chrome/browser/renderer_host/render_widget_host_view_mac.h"
#include "chrome/browser/tab_contents/web_contents.h"
@@ -18,6 +19,10 @@ WebContentsView* WebContentsView::Create(WebContents* web_contents) {
WebContentsViewMac::WebContentsViewMac(WebContents* web_contents)
: web_contents_(web_contents) {
+ registrar_.Add(this, NotificationType::WEB_CONTENTS_CONNECTED,
+ Source<WebContents>(web_contents));
+ registrar_.Add(this, NotificationType::WEB_CONTENTS_DISCONNECTED,
+ Source<WebContents>(web_contents));
}
WebContentsViewMac::~WebContentsViewMac() {
@@ -232,6 +237,34 @@ void WebContentsViewMac::ShowCreatedWidgetInternal(
widget_host->Init();
}
+void WebContentsViewMac::Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details) {
+ switch (type.value) {
+ case NotificationType::WEB_CONTENTS_CONNECTED: {
+ if (sad_tab_.get()) {
+ [sad_tab_.get() removeFromSuperview];
+ sad_tab_.reset();
+ }
+ break;
+ }
+ case NotificationType::WEB_CONTENTS_DISCONNECTED: {
+ SadTabView* view = [[SadTabView alloc] initWithFrame:NSZeroRect];
+ CFRetain(view);
+ [view release];
+ sad_tab_.reset(view);
+
+ // Set as the dominant child.
+ [cocoa_view_.get() addSubview:view];
+ [view setFrame:[cocoa_view_.get() bounds]];
+ [view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
+ break;
+ }
+ default:
+ NOTREACHED() << "Got a notification we didn't register for.";
+ }
+}
+
@implementation WebContentsViewCocoa
// Tons of stuff goes here, where we grab events going on in Cocoaland and send
diff --git a/chrome/chrome.xcodeproj/project.pbxproj b/chrome/chrome.xcodeproj/project.pbxproj
index 733ae0f..91f106e 100644
--- a/chrome/chrome.xcodeproj/project.pbxproj
+++ b/chrome/chrome.xcodeproj/project.pbxproj
@@ -253,6 +253,8 @@
7F84A3FF0F6102F46E0E5155 /* history_publisher.cc in Sources */ = {isa = PBXBuildFile; fileRef = 269003C4E493789D82B6B0F9 /* history_publisher.cc */; };
81B6908E490BFDF37C4BA7CE /* v8_unit_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 759B3A1B81E261598122B03B /* v8_unit_test.cc */; };
81E4783DE6F497B9BCC5B9F6 /* bookmark_model.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3D00CDB6C665E7ED1A1090D7 /* bookmark_model.cc */; };
+ 824FC14F0F44C56A000299E5 /* sadtab.png in Resources */ = {isa = PBXBuildFile; fileRef = 824FC14E0F44C56A000299E5 /* sadtab.png */; };
+ 824FC1560F44C59C000299E5 /* sad_tab_view.mm in Sources */ = {isa = PBXBuildFile; fileRef = 824FC1540F44C59C000299E5 /* sad_tab_view.mm */; };
8268477E0F2F69C8009F6555 /* profile_manager_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D7BF8E60E9D4839009A6919 /* profile_manager_unittest.cc */; };
8268477F0F2F69D1009F6555 /* profile_manager.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D7BF8E40E9D4839009A6919 /* profile_manager.cc */; };
826847800F2F69D1009F6555 /* profile.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D7BF8E20E9D4839009A6919 /* profile.cc */; };
@@ -2407,6 +2409,9 @@
778D7927798B7E3FAA498D3D /* url_fetcher.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = url_fetcher.cc; sourceTree = "<group>"; };
7849CCC221723C1BC14D6384 /* history_publisher_none.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = history_publisher_none.cc; sourceTree = "<group>"; };
8104B4AFD95DCA06B2F37551 /* chrome_paths_internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = chrome_paths_internal.h; sourceTree = "<group>"; };
+ 824FC14E0F44C56A000299E5 /* sadtab.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = sadtab.png; path = theme/sadtab.png; sourceTree = "<group>"; };
+ 824FC1540F44C59C000299E5 /* sad_tab_view.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = sad_tab_view.mm; path = cocoa/sad_tab_view.mm; sourceTree = "<group>"; };
+ 824FC1550F44C59C000299E5 /* sad_tab_view.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = sad_tab_view.h; path = cocoa/sad_tab_view.h; sourceTree = "<group>"; };
82684C5F0F2FAE68009F6555 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };
82684CCF0F2FAEC2009F6555 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; };
82684D050F2FB101009F6555 /* sdch.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = sdch.xcodeproj; path = sdch/sdch.xcodeproj; sourceTree = "<group>"; };
@@ -4354,6 +4359,7 @@
E46C51230F2A14A300B393B8 /* go.pdf */,
E46C50570F291C3B00B393B8 /* newtab.pdf */,
E46C50540F291C1E00B393B8 /* reload.pdf */,
+ 824FC14E0F44C56A000299E5 /* sadtab.png */,
E46C504F0F291C0600B393B8 /* star.pdf */,
E43D096D0F44C7BA003F39CA /* starred.pdf */,
);
@@ -4365,6 +4371,8 @@
children = (
82BB33080F44B57C00761F43 /* event_view.h */,
82BB33090F44B57C00761F43 /* event_view.mm */,
+ 824FC1550F44C59C000299E5 /* sad_tab_view.h */,
+ 824FC1540F44C59C000299E5 /* sad_tab_view.mm */,
A7CBAD370F322A7E00360BF5 /* shell_dialogs_mac.mm */,
E46C50D70F292EAA00B393B8 /* tab_cell.h */,
E46C50D80F292EAA00B393B8 /* tab_cell.mm */,
@@ -5148,6 +5156,7 @@
E43A7A070F1D192000ABD5D1 /* notAllowedCursor.png in Resources */,
E43A7A080F1D192000ABD5D1 /* progressCursor.png in Resources */,
E46C50560F291C1E00B393B8 /* reload.pdf in Resources */,
+ 824FC14F0F44C56A000299E5 /* sadtab.png in Resources */,
E43A7A090F1D192000ABD5D1 /* southEastResizeCursor.png in Resources */,
E43A7A0A0F1D192000ABD5D1 /* southResizeCursor.png in Resources */,
E43A7A0B0F1D192000ABD5D1 /* southWestResizeCursor.png in Resources */,
@@ -5433,6 +5442,7 @@
B0AC9501DED2809AC208AEEA /* resolve_proxy_msg_helper.cc in Sources */,
BADB8B710F3A35AC00989B26 /* resource_dispatcher_host.cc in Sources */,
A7A214A00F3B91B100F62B4D /* resource_message_filter.cc in Sources */,
+ 824FC1560F44C59C000299E5 /* sad_tab_view.mm in Sources */,
4D7BFAF30E9D49EF009A6919 /* safe_browsing_database.cc in Sources */,
E48FB9590EC4E9C10052B72B /* safe_browsing_database_bloom.cc in Sources */,
E48FB95C0EC4E9DD0052B72B /* safe_browsing_database_impl.cc in Sources */,
diff --git a/chrome/common/temp_scaffolding_stubs.h b/chrome/common/temp_scaffolding_stubs.h
index c9202e0..0520df2 100644
--- a/chrome/common/temp_scaffolding_stubs.h
+++ b/chrome/common/temp_scaffolding_stubs.h
@@ -786,7 +786,7 @@ class PrintViewManager {
void Destroy() { NOTIMPLEMENTED(); }
bool OnRendererGone(RenderViewHost*) {
NOTIMPLEMENTED();
- return false;
+ return true; // Assume for now that all renderer crashes are important.
}
void DidGetPrintedPagesCount(int, int) { NOTIMPLEMENTED(); }
void DidPrintPage(const ViewHostMsg_DidPrintPage_Params&) {