linux_aura: Disable the plugin install infobar.
[chromium-blink-merge.git] / content / shell / browser / shell_mac.mm
blobf332064c5ce2483a568a5042da6fc18a82ae92a8
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/shell/browser/shell.h"
7 #include <algorithm>
9 #include "base/logging.h"
10 #import "base/mac/scoped_nsobject.h"
11 #include "base/strings/string_piece.h"
12 #include "base/strings/sys_string_conversions.h"
13 #include "content/public/browser/native_web_keyboard_event.h"
14 #include "content/public/browser/web_contents.h"
15 #include "content/shell/app/resource.h"
16 #import "ui/base/cocoa/underlay_opengl_hosting_window.h"
17 #include "url/gurl.h"
19 #if !defined(MAC_OS_X_VERSION_10_7) || \
20     MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7
22 enum {
23   NSWindowCollectionBehaviorFullScreenPrimary = 1 << 7,
24   NSWindowCollectionBehaviorFullScreenAuxiliary = 1 << 8
27 #endif // MAC_OS_X_VERSION_10_7
29 // Receives notification that the window is closing so that it can start the
30 // tear-down process. Is responsible for deleting itself when done.
31 @interface ContentShellWindowDelegate : NSObject<NSWindowDelegate> {
32  @private
33   content::Shell* shell_;
35 - (id)initWithShell:(content::Shell*)shell;
36 @end
38 @implementation ContentShellWindowDelegate
40 - (id)initWithShell:(content::Shell*)shell {
41   if ((self = [super init])) {
42     shell_ = shell;
43   }
44   return self;
47 // Called when the window is about to close. Perform the self-destruction
48 // sequence by getting rid of the shell and removing it and the window from
49 // the various global lists. By returning YES, we allow the window to be
50 // removed from the screen.
51 - (BOOL)windowShouldClose:(id)window {
52   [window autorelease];
53   delete shell_;
54   [self release];
56   return YES;
59 - (void)performAction:(id)sender {
60   shell_->ActionPerformed([sender tag]);
63 - (void)takeURLStringValueFrom:(id)sender {
64   shell_->URLEntered(base::SysNSStringToUTF8([sender stringValue]));
67 @end
69 @interface CrShellWindow : UnderlayOpenGLHostingWindow {
70  @private
71   content::Shell* shell_;
73 - (void)setShell:(content::Shell*)shell;
74 - (void)showDevTools:(id)sender;
75 @end
77 @implementation CrShellWindow
79 - (void)setShell:(content::Shell*)shell {
80   shell_ = shell;
83 - (void)showDevTools:(id)sender {
84   shell_->ShowDevTools();
87 @end
89 namespace {
91 NSString* kWindowTitle = @"Content Shell";
93 // Layout constants (in view coordinates)
94 const CGFloat kButtonWidth = 72;
95 const CGFloat kURLBarHeight = 24;
97 // The minimum size of the window's content (in view coordinates)
98 const CGFloat kMinimumWindowWidth = 400;
99 const CGFloat kMinimumWindowHeight = 300;
101 void MakeShellButton(NSRect* rect,
102                      NSString* title,
103                      NSView* parent,
104                      int control,
105                      NSView* target,
106                      NSString* key,
107                      NSUInteger modifier) {
108   base::scoped_nsobject<NSButton> button(
109       [[NSButton alloc] initWithFrame:*rect]);
110   [button setTitle:title];
111   [button setBezelStyle:NSSmallSquareBezelStyle];
112   [button setAutoresizingMask:(NSViewMaxXMargin | NSViewMinYMargin)];
113   [button setTarget:target];
114   [button setAction:@selector(performAction:)];
115   [button setTag:control];
116   [button setKeyEquivalent:key];
117   [button setKeyEquivalentModifierMask:modifier];
118   [parent addSubview:button];
119   rect->origin.x += kButtonWidth;
122 }  // namespace
124 namespace content {
126 void Shell::PlatformInitialize(const gfx::Size& default_window_size) {
129 void Shell::PlatformExit() {
132 void Shell::PlatformCleanUp() {
135 void Shell::PlatformEnableUIControl(UIControl control, bool is_enabled) {
136   if (headless_)
137     return;
139   int id;
140   switch (control) {
141     case BACK_BUTTON:
142       id = IDC_NAV_BACK;
143       break;
144     case FORWARD_BUTTON:
145       id = IDC_NAV_FORWARD;
146       break;
147     case STOP_BUTTON:
148       id = IDC_NAV_STOP;
149       break;
150     default:
151       NOTREACHED() << "Unknown UI control";
152       return;
153   }
154   [[[window_ contentView] viewWithTag:id] setEnabled:is_enabled];
157 void Shell::PlatformSetAddressBarURL(const GURL& url) {
158   if (headless_)
159     return;
161   NSString* url_string = base::SysUTF8ToNSString(url.spec());
162   [url_edit_view_ setStringValue:url_string];
165 void Shell::PlatformSetIsLoading(bool loading) {
168 void Shell::PlatformCreateWindow(int width, int height) {
169   if (headless_) {
170     content_size_ = gfx::Size(width, height);
171     return;
172   }
174   NSRect initial_window_bounds =
175       NSMakeRect(0, 0, width, height + kURLBarHeight);
176   NSRect content_rect = initial_window_bounds;
177   NSUInteger style_mask = NSTitledWindowMask |
178                           NSClosableWindowMask |
179                           NSMiniaturizableWindowMask |
180                           NSResizableWindowMask;
181   CrShellWindow* window =
182       [[CrShellWindow alloc] initWithContentRect:content_rect
183                                        styleMask:style_mask
184                                          backing:NSBackingStoreBuffered
185                                            defer:NO];
186   window_ = window;
187   [window setShell:this];
188   [window_ setTitle:kWindowTitle];
189   NSView* content = [window_ contentView];
191   // If the window is allowed to get too small, it will wreck the view bindings.
192   NSSize min_size = NSMakeSize(kMinimumWindowWidth, kMinimumWindowHeight);
193   min_size = [content convertSize:min_size toView:nil];
194   // Note that this takes window coordinates.
195   [window_ setContentMinSize:min_size];
197   // Set the shell window to participate in Lion Fullscreen mode. Set
198   // Setting this flag has no effect on Snow Leopard or earlier.
199   NSUInteger collectionBehavior = [window_ collectionBehavior];
200   collectionBehavior |= NSWindowCollectionBehaviorFullScreenPrimary;
201   [window_ setCollectionBehavior:collectionBehavior];
203   // Rely on the window delegate to clean us up rather than immediately
204   // releasing when the window gets closed. We use the delegate to do
205   // everything from the autorelease pool so the shell isn't on the stack
206   // during cleanup (ie, a window close from javascript).
207   [window_ setReleasedWhenClosed:NO];
209   // Create a window delegate to watch for when it's asked to go away. It will
210   // clean itself up so we don't need to hold a reference.
211   ContentShellWindowDelegate* delegate =
212       [[ContentShellWindowDelegate alloc] initWithShell:this];
213   [window_ setDelegate:delegate];
215   NSRect button_frame =
216       NSMakeRect(0, NSMaxY(initial_window_bounds) - kURLBarHeight,
217                  kButtonWidth, kURLBarHeight);
219   MakeShellButton(&button_frame, @"Back", content, IDC_NAV_BACK,
220                   (NSView*)delegate, @"[", NSCommandKeyMask);
221   MakeShellButton(&button_frame, @"Forward", content, IDC_NAV_FORWARD,
222                   (NSView*)delegate, @"]", NSCommandKeyMask);
223   MakeShellButton(&button_frame, @"Reload", content, IDC_NAV_RELOAD,
224                   (NSView*)delegate, @"r", NSCommandKeyMask);
225   MakeShellButton(&button_frame, @"Stop", content, IDC_NAV_STOP,
226                   (NSView*)delegate, @".", NSCommandKeyMask);
228   button_frame.size.width =
229       NSWidth(initial_window_bounds) - NSMinX(button_frame);
230   base::scoped_nsobject<NSTextField> url_edit_view(
231       [[NSTextField alloc] initWithFrame:button_frame]);
232   [content addSubview:url_edit_view];
233   [url_edit_view setAutoresizingMask:(NSViewWidthSizable | NSViewMinYMargin)];
234   [url_edit_view setTarget:delegate];
235   [url_edit_view setAction:@selector(takeURLStringValueFrom:)];
236   [[url_edit_view cell] setWraps:NO];
237   [[url_edit_view cell] setScrollable:YES];
238   url_edit_view_ = url_edit_view.get();
240   // show the window
241   [window_ makeKeyAndOrderFront:nil];
244 void Shell::PlatformSetContents() {
245   NSView* web_view = web_contents_->GetNativeView();
246   [web_view setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)];
248   if (headless_) {
249     SizeTo(content_size_);
250     return;
251   }
253   NSView* content = [window_ contentView];
254   [content addSubview:web_view];
256   NSRect frame = [content bounds];
257   frame.size.height -= kURLBarHeight;
258   [web_view setFrame:frame];
259   [web_view setNeedsDisplay:YES];
262 void Shell::SizeTo(const gfx::Size& content_size) {
263   if (!headless_) {
264     NSRect frame = NSMakeRect(
265         0, 0, content_size.width(), content_size.height() + kURLBarHeight);
266     [window().contentView setFrame:frame];
267     return;
268   }
269   NSView* web_view = web_contents_->GetNativeView();
270   NSRect frame = NSMakeRect(0, 0, content_size.width(), content_size.height());
271   [web_view setFrame:frame];
274 void Shell::PlatformResizeSubViews() {
275   // Not needed; subviews are bound.
278 void Shell::PlatformSetTitle(const base::string16& title) {
279   if (headless_)
280     return;
282   NSString* title_string = base::SysUTF16ToNSString(title);
283   [window_ setTitle:title_string];
286 bool Shell::PlatformHandleContextMenu(
287     const content::ContextMenuParams& params) {
288   return false;
291 void Shell::Close() {
292   if (headless_)
293     delete this;
294   else
295     [window_ performClose:nil];
298 void Shell::ActionPerformed(int control) {
299   switch (control) {
300     case IDC_NAV_BACK:
301       GoBackOrForward(-1);
302       break;
303     case IDC_NAV_FORWARD:
304       GoBackOrForward(1);
305       break;
306     case IDC_NAV_RELOAD:
307       Reload();
308       break;
309     case IDC_NAV_STOP:
310       Stop();
311       break;
312   }
315 void Shell::URLEntered(std::string url_string) {
316   if (!url_string.empty()) {
317     GURL url(url_string);
318     if (!url.has_scheme())
319       url = GURL("http://" + url_string);
320     LoadURL(url);
321   }
324 void Shell::HandleKeyboardEvent(WebContents* source,
325                                 const NativeWebKeyboardEvent& event) {
326   if (event.skip_in_browser)
327     return;
329   // The event handling to get this strictly right is a tangle; cheat here a bit
330   // by just letting the menus have a chance at it.
331   if ([event.os_event type] == NSKeyDown) {
332     if (([event.os_event modifierFlags] & NSCommandKeyMask) &&
333         [[event.os_event characters] isEqual:@"l"]) {
334       [window_ makeFirstResponder:url_edit_view_];
335       return;
336     }
338     [[NSApp mainMenu] performKeyEquivalent:event.os_event];
339   }
342 }  // namespace content