Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / ui / cocoa / browser_window_cocoa.mm
blob982d06805b8cc49bf53bf61323be6196a60d4c76
1 // Copyright (c) 2012 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 "chrome/browser/ui/cocoa/browser_window_cocoa.h"
7 #include "base/bind.h"
8 #include "base/command_line.h"
9 #include "base/logging.h"
10 #include "base/mac/mac_util.h"
11 #import "base/mac/sdk_forward_declarations.h"
12 #include "base/message_loop/message_loop.h"
13 #include "base/prefs/pref_service.h"
14 #include "base/strings/sys_string_conversions.h"
15 #include "chrome/app/chrome_command_ids.h"
16 #include "chrome/browser/chrome_notification_types.h"
17 #include "chrome/browser/download/download_shelf.h"
18 #include "chrome/browser/extensions/tab_helper.h"
19 #include "chrome/browser/fullscreen.h"
20 #include "chrome/browser/password_manager/password_manager.h"
21 #include "chrome/browser/profiles/profile.h"
22 #include "chrome/browser/shell_integration.h"
23 #include "chrome/browser/ui/browser.h"
24 #include "chrome/browser/ui/browser_command_controller.h"
25 #include "chrome/browser/ui/browser_commands.h"
26 #include "chrome/browser/ui/browser_list.h"
27 #include "chrome/browser/ui/browser_window_state.h"
28 #import "chrome/browser/ui/cocoa/browser/avatar_button_controller.h"
29 #import "chrome/browser/ui/cocoa/browser/avatar_menu_bubble_controller.h"
30 #import "chrome/browser/ui/cocoa/browser/edit_search_engine_cocoa_controller.h"
31 #import "chrome/browser/ui/cocoa/browser/password_generation_bubble_controller.h"
32 #import "chrome/browser/ui/cocoa/browser_window_controller.h"
33 #import "chrome/browser/ui/cocoa/browser_window_utils.h"
34 #import "chrome/browser/ui/cocoa/chrome_event_processing_window.h"
35 #import "chrome/browser/ui/cocoa/download/download_shelf_controller.h"
36 #include "chrome/browser/ui/cocoa/find_bar/find_bar_bridge.h"
37 #import "chrome/browser/ui/cocoa/info_bubble_view.h"
38 #import "chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h"
39 #import "chrome/browser/ui/cocoa/nsmenuitem_additions.h"
40 #include "chrome/browser/ui/cocoa/restart_browser.h"
41 #include "chrome/browser/ui/cocoa/status_bubble_mac.h"
42 #include "chrome/browser/ui/cocoa/task_manager_mac.h"
43 #import "chrome/browser/ui/cocoa/toolbar/toolbar_controller.h"
44 #import "chrome/browser/ui/cocoa/web_dialog_window_controller.h"
45 #import "chrome/browser/ui/cocoa/website_settings_bubble_controller.h"
46 #include "chrome/browser/ui/search/search_model.h"
47 #include "chrome/browser/ui/tabs/tab_strip_model.h"
48 #include "chrome/browser/web_applications/web_app.h"
49 #include "chrome/common/chrome_switches.h"
50 #include "chrome/common/pref_names.h"
51 #include "components/autofill/core/common/password_form.h"
52 #include "content/public/browser/native_web_keyboard_event.h"
53 #include "content/public/browser/notification_details.h"
54 #include "content/public/browser/notification_source.h"
55 #include "content/public/browser/web_contents.h"
56 #include "content/public/browser/web_contents_view.h"
57 #include "grit/chromium_strings.h"
58 #include "grit/generated_resources.h"
59 #include "ui/base/l10n/l10n_util_mac.h"
60 #include "ui/gfx/rect.h"
62 #if defined(ENABLE_ONE_CLICK_SIGNIN)
63 #import "chrome/browser/ui/cocoa/one_click_signin_bubble_controller.h"
64 #import "chrome/browser/ui/cocoa/one_click_signin_dialog_controller.h"
65 #endif
67 using content::NativeWebKeyboardEvent;
68 using content::SSLStatus;
69 using content::WebContents;
71 namespace {
73 NSPoint GetPointForBubble(content::WebContents* web_contents,
74                           int x_offset,
75                           int y_offset) {
76   NSView* view = web_contents->GetView()->GetNativeView();
77   NSRect bounds = [view bounds];
78   NSPoint point;
79   point.x = NSMinX(bounds) + x_offset;
80   // The view's origin is at the bottom but |rect|'s origin is at the top.
81   point.y = NSMaxY(bounds) - y_offset;
82   point = [view convertPoint:point toView:nil];
83   point = [[view window] convertBaseToScreen:point];
84   return point;
87 }  // namespace
89 BrowserWindowCocoa::BrowserWindowCocoa(Browser* browser,
90                                        BrowserWindowController* controller)
91   : browser_(browser),
92     controller_(controller),
93     initial_show_state_(ui::SHOW_STATE_DEFAULT),
94     attention_request_id_(0) {
96   gfx::Rect bounds;
97   chrome::GetSavedWindowBoundsAndShowState(browser_,
98                                            &bounds,
99                                            &initial_show_state_);
101   browser_->search_model()->AddObserver(this);
104 BrowserWindowCocoa::~BrowserWindowCocoa() {
105   browser_->search_model()->RemoveObserver(this);
108 void BrowserWindowCocoa::Show() {
109   // The Browser associated with this browser window must become the active
110   // browser at the time |Show()| is called. This is the natural behaviour under
111   // Windows, but |-makeKeyAndOrderFront:| won't send |-windowDidBecomeMain:|
112   // until we return to the runloop. Therefore any calls to
113   // |chrome::FindLastActiveWithHostDesktopType| will return the previous
114   // browser instead if we don't explicitly set it here.
115   BrowserList::SetLastActive(browser_);
117   bool is_session_restore = browser_->is_session_restore();
118   NSWindowAnimationBehavior saved_animation_behavior =
119       NSWindowAnimationBehaviorDefault;
120   bool did_save_animation_behavior = false;
121   // Turn off swishing when restoring windows.
122   if (is_session_restore &&
123       [window() respondsToSelector:@selector(animationBehavior)] &&
124       [window() respondsToSelector:@selector(setAnimationBehavior:)]) {
125     did_save_animation_behavior = true;
126     saved_animation_behavior = [window() animationBehavior];
127     [window() setAnimationBehavior:NSWindowAnimationBehaviorNone];
128   }
130   [window() makeKeyAndOrderFront:controller_];
132   // When creating windows from nibs it is necessary to |makeKeyAndOrderFront:|
133   // prior to |orderOut:| then |miniaturize:| when restoring windows in the
134   // minimized state.
135   if (initial_show_state_ == ui::SHOW_STATE_MINIMIZED) {
136     [window() orderOut:controller_];
137     [window() miniaturize:controller_];
138   } else if (initial_show_state_ == ui::SHOW_STATE_FULLSCREEN) {
139     chrome::ToggleFullscreenMode(browser_);
140   }
141   initial_show_state_ = ui::SHOW_STATE_DEFAULT;
143   // Restore window animation behavior.
144   if (did_save_animation_behavior)
145     [window() setAnimationBehavior:saved_animation_behavior];
147   browser_->OnWindowDidShow();
150 void BrowserWindowCocoa::ShowInactive() {
151   [window() orderFront:controller_];
154 void BrowserWindowCocoa::Hide() {
155   // Not implemented.
158 void BrowserWindowCocoa::SetBounds(const gfx::Rect& bounds) {
159   gfx::Rect real_bounds = [controller_ enforceMinWindowSize:bounds];
161   ExitFullscreen();
162   NSRect cocoa_bounds = NSMakeRect(real_bounds.x(), 0,
163                                    real_bounds.width(),
164                                    real_bounds.height());
165   // Flip coordinates based on the primary screen.
166   NSScreen* screen = [[NSScreen screens] objectAtIndex:0];
167   cocoa_bounds.origin.y =
168       NSHeight([screen frame]) - real_bounds.height() - real_bounds.y();
170   [window() setFrame:cocoa_bounds display:YES];
173 // Callers assume that this doesn't immediately delete the Browser object.
174 // The controller implementing the window delegate methods called from
175 // |-performClose:| must take precautions to ensure that.
176 void BrowserWindowCocoa::Close() {
177   // If there is an overlay window, we contain a tab being dragged between
178   // windows. Don't hide the window as it makes the UI extra confused. We can
179   // still close the window, as that will happen when the drag completes.
180   if ([controller_ overlayWindow]) {
181     [controller_ deferPerformClose];
182   } else {
183     // Using |-performClose:| can prevent the window from actually closing if
184     // a JavaScript beforeunload handler opens an alert during shutdown, as
185     // documented at <http://crbug.com/118424>. Re-implement
186     // -[NSWindow performClose:] as closely as possible to how Apple documents
187     // it.
188     //
189     // Before calling |-close|, hide the window immediately. |-performClose:|
190     // would do something similar, and this ensures that the window is removed
191     // from AppKit's display list. Not doing so can lead to crashes like
192     // <http://crbug.com/156101>.
193     id<NSWindowDelegate> delegate = [window() delegate];
194     SEL window_should_close = @selector(windowShouldClose:);
195     if ([delegate respondsToSelector:window_should_close]) {
196       if ([delegate windowShouldClose:window()]) {
197         [window() orderOut:nil];
198         [window() close];
199       }
200     } else if ([window() respondsToSelector:window_should_close]) {
201       if ([window() performSelector:window_should_close withObject:window()]) {
202         [window() orderOut:nil];
203         [window() close];
204       }
205     } else {
206       [window() orderOut:nil];
207       [window() close];
208     }
209   }
212 void BrowserWindowCocoa::Activate() {
213   [controller_ activate];
216 void BrowserWindowCocoa::Deactivate() {
217   // TODO(jcivelli): http://crbug.com/51364 Implement me.
218   NOTIMPLEMENTED();
221 void BrowserWindowCocoa::FlashFrame(bool flash) {
222   if (flash) {
223     attention_request_id_ = [NSApp requestUserAttention:NSInformationalRequest];
224   } else {
225     [NSApp cancelUserAttentionRequest:attention_request_id_];
226     attention_request_id_ = 0;
227   }
230 bool BrowserWindowCocoa::IsAlwaysOnTop() const {
231   return false;
234 void BrowserWindowCocoa::SetAlwaysOnTop(bool always_on_top) {
235   // Not implemented for browser windows.
236   NOTIMPLEMENTED();
239 bool BrowserWindowCocoa::IsActive() const {
240   return [window() isKeyWindow];
243 gfx::NativeWindow BrowserWindowCocoa::GetNativeWindow() {
244   return window();
247 BrowserWindowTesting* BrowserWindowCocoa::GetBrowserWindowTesting() {
248   return NULL;
251 StatusBubble* BrowserWindowCocoa::GetStatusBubble() {
252   return [controller_ statusBubble];
255 void BrowserWindowCocoa::UpdateTitleBar() {
256   NSString* newTitle =
257       base::SysUTF16ToNSString(browser_->GetWindowTitleForCurrentTab());
259   pending_window_title_.reset(
260       [BrowserWindowUtils scheduleReplaceOldTitle:pending_window_title_.get()
261                                      withNewTitle:newTitle
262                                         forWindow:window()]);
265 void BrowserWindowCocoa::BookmarkBarStateChanged(
266     BookmarkBar::AnimateChangeType change_type) {
267   [[controller_ bookmarkBarController]
268       updateState:browser_->bookmark_bar_state()
269        changeType:change_type];
272 void BrowserWindowCocoa::UpdateDevTools() {
273   [controller_ updateDevToolsForContents:
274       browser_->tab_strip_model()->GetActiveWebContents()];
277 void BrowserWindowCocoa::UpdateLoadingAnimations(bool should_animate) {
278   // Do nothing on Mac.
281 void BrowserWindowCocoa::SetStarredState(bool is_starred) {
282   [controller_ setStarredState:is_starred ? YES : NO];
285 void BrowserWindowCocoa::SetTranslateIconToggled(bool is_lit) {
286   NOTIMPLEMENTED();
289 void BrowserWindowCocoa::OnActiveTabChanged(content::WebContents* old_contents,
290                                             content::WebContents* new_contents,
291                                             int index,
292                                             int reason) {
293   // TODO(pkasting): Perhaps the code in
294   // TabStripController::activateTabWithContents should move here?  Or this
295   // should call that (instead of TabStripModelObserverBridge doing so)?  It's
296   // not obvious to me why Mac doesn't handle tab changes in BrowserWindow the
297   // way views and GTK do.
300 void BrowserWindowCocoa::ZoomChangedForActiveTab(bool can_show_bubble) {
301   [controller_ zoomChangedForActiveTab:can_show_bubble ? YES : NO];
304 gfx::Rect BrowserWindowCocoa::GetRestoredBounds() const {
305   // Flip coordinates based on the primary screen.
306   NSScreen* screen = [[NSScreen screens] objectAtIndex:0];
307   NSRect frame = [controller_ regularWindowFrame];
308   gfx::Rect bounds(frame.origin.x, 0, NSWidth(frame), NSHeight(frame));
309   bounds.set_y(NSHeight([screen frame]) - NSMaxY(frame));
310   return bounds;
313 ui::WindowShowState BrowserWindowCocoa::GetRestoredState() const {
314   if (IsMaximized())
315     return ui::SHOW_STATE_MAXIMIZED;
316   if (IsMinimized())
317     return ui::SHOW_STATE_MINIMIZED;
318   return ui::SHOW_STATE_NORMAL;
321 gfx::Rect BrowserWindowCocoa::GetBounds() const {
322   return GetRestoredBounds();
325 bool BrowserWindowCocoa::IsMaximized() const {
326   return [window() isZoomed];
329 bool BrowserWindowCocoa::IsMinimized() const {
330   return [window() isMiniaturized];
333 void BrowserWindowCocoa::Maximize() {
334   // Zoom toggles so only call if not already maximized.
335   if (!IsMaximized())
336     [window() zoom:controller_];
339 void BrowserWindowCocoa::Minimize() {
340   [window() miniaturize:controller_];
343 void BrowserWindowCocoa::Restore() {
344   if (IsMaximized())
345     [window() zoom:controller_];  // Toggles zoom mode.
346   else if (IsMinimized())
347     [window() deminiaturize:controller_];
350 void BrowserWindowCocoa::EnterFullscreen(
351       const GURL& url, FullscreenExitBubbleType bubble_type) {
352   // When simplified fullscreen is enabled, always enter normal fullscreen.
353   const CommandLine* command_line = CommandLine::ForCurrentProcess();
354   if (command_line->HasSwitch(switches::kEnableSimplifiedFullscreen)) {
355     if (url.is_empty())
356       [controller_ enterFullscreen];
357     else
358       [controller_ enterFullscreenForURL:url bubbleType:bubble_type];
359     return;
360   }
362   [controller_ enterPresentationModeForURL:url
363                                 bubbleType:bubble_type];
366 void BrowserWindowCocoa::ExitFullscreen() {
367   [controller_ exitFullscreen];
370 void BrowserWindowCocoa::UpdateFullscreenExitBubbleContent(
371       const GURL& url,
372       FullscreenExitBubbleType bubble_type) {
373   [controller_ updateFullscreenExitBubbleURL:url bubbleType:bubble_type];
376 bool BrowserWindowCocoa::ShouldHideUIForFullscreen() const {
377   // On Mac, fullscreen mode has most normal things (in a slide-down panel).
378   return false;
381 bool BrowserWindowCocoa::IsFullscreen() const {
382   if ([controller_ inPresentationMode])
383     CHECK([controller_ isFullscreen]);  // Presentation mode must be fullscreen.
384   return [controller_ isFullscreen];
387 bool BrowserWindowCocoa::IsFullscreenBubbleVisible() const {
388   return false;
391 void BrowserWindowCocoa::ConfirmAddSearchProvider(
392     TemplateURL* template_url,
393     Profile* profile) {
394   // The controller will release itself when the window closes.
395   EditSearchEngineCocoaController* editor =
396       [[EditSearchEngineCocoaController alloc] initWithProfile:profile
397                                                       delegate:NULL
398                                                    templateURL:template_url];
399   [NSApp beginSheet:[editor window]
400      modalForWindow:window()
401       modalDelegate:controller_
402      didEndSelector:@selector(sheetDidEnd:returnCode:context:)
403         contextInfo:NULL];
406 LocationBar* BrowserWindowCocoa::GetLocationBar() const {
407   return [controller_ locationBarBridge];
410 void BrowserWindowCocoa::SetFocusToLocationBar(bool select_all) {
411   [controller_ focusLocationBar:select_all ? YES : NO];
414 void BrowserWindowCocoa::UpdateReloadStopState(bool is_loading, bool force) {
415   [controller_ setIsLoading:is_loading force:force];
418 void BrowserWindowCocoa::UpdateToolbar(content::WebContents* contents) {
419   [controller_ updateToolbarWithContents:contents];
422 void BrowserWindowCocoa::FocusToolbar() {
423   // Not needed on the Mac.
426 void BrowserWindowCocoa::FocusAppMenu() {
427   // Chrome uses the standard Mac OS X menu bar, so this isn't needed.
430 void BrowserWindowCocoa::RotatePaneFocus(bool forwards) {
431   // Not needed on the Mac.
434 void BrowserWindowCocoa::FocusBookmarksToolbar() {
435   // Not needed on the Mac.
438 void BrowserWindowCocoa::FocusInfobars() {
439   // Not needed on the Mac.
442 bool BrowserWindowCocoa::IsBookmarkBarVisible() const {
443   return browser_->profile()->GetPrefs()->GetBoolean(prefs::kShowBookmarkBar);
446 bool BrowserWindowCocoa::IsBookmarkBarAnimating() const {
447   return [controller_ isBookmarkBarAnimating];
450 bool BrowserWindowCocoa::IsTabStripEditable() const {
451   return ![controller_ isDragSessionActive];
454 bool BrowserWindowCocoa::IsToolbarVisible() const {
455   return browser_->SupportsWindowFeature(Browser::FEATURE_TOOLBAR) ||
456          browser_->SupportsWindowFeature(Browser::FEATURE_LOCATIONBAR);
459 gfx::Rect BrowserWindowCocoa::GetRootWindowResizerRect() const {
460   if (IsDownloadShelfVisible())
461     return gfx::Rect();
462   NSRect tabRect = [controller_ selectedTabGrowBoxRect];
463   return gfx::Rect(NSRectToCGRect(tabRect));
466 void BrowserWindowCocoa::AddFindBar(
467     FindBarCocoaController* find_bar_cocoa_controller) {
468   [controller_ addFindBar:find_bar_cocoa_controller];
471 void BrowserWindowCocoa::ShowUpdateChromeDialog() {
472   restart_browser::RequestRestart(window());
475 void BrowserWindowCocoa::ShowBookmarkBubble(const GURL& url,
476                                             bool already_bookmarked) {
477   [controller_ showBookmarkBubbleForURL:url
478                       alreadyBookmarked:(already_bookmarked ? YES : NO)];
481 void BrowserWindowCocoa::ShowTranslateBubble(
482       content::WebContents* contents,
483       TranslateBubbleModel::ViewState view_state,
484       TranslateErrors::Type error_type) {
485   NOTIMPLEMENTED();
488 #if defined(ENABLE_ONE_CLICK_SIGNIN)
489 void BrowserWindowCocoa::ShowOneClickSigninBubble(
490     OneClickSigninBubbleType type,
491     const base::string16& email,
492     const base::string16& error_message,
493     const StartSyncCallback& start_sync_callback) {
494   WebContents* web_contents =
495         browser_->tab_strip_model()->GetActiveWebContents();
496   if (type == ONE_CLICK_SIGNIN_BUBBLE_TYPE_BUBBLE) {
497     base::scoped_nsobject<OneClickSigninBubbleController> bubble_controller([
498             [OneClickSigninBubbleController alloc]
499         initWithBrowserWindowController:cocoa_controller()
500                             webContents:web_contents
501                            errorMessage:base::SysUTF16ToNSString(error_message)
502                                callback:start_sync_callback]);
503     [bubble_controller showWindow:nil];
504   } else {
505     // Deletes itself when the dialog closes.
506     new OneClickSigninDialogController(
507         web_contents, start_sync_callback, email);
508   }
510 #endif
512 bool BrowserWindowCocoa::IsDownloadShelfVisible() const {
513   return [controller_ isDownloadShelfVisible] != NO;
516 DownloadShelf* BrowserWindowCocoa::GetDownloadShelf() {
517   DownloadShelfController* shelfController = [controller_ downloadShelf];
518   return [shelfController bridge];
521 // We allow closing the window here since the real quit decision on Mac is made
522 // in [AppController quit:].
523 void BrowserWindowCocoa::ConfirmBrowserCloseWithPendingDownloads(
524       int download_count,
525       Browser::DownloadClosePreventionType dialog_type,
526       bool app_modal,
527       const base::Callback<void(bool)>& callback) {
528   callback.Run(true);
531 void BrowserWindowCocoa::UserChangedTheme() {
532   [controller_ userChangedTheme];
535 int BrowserWindowCocoa::GetExtraRenderViewHeight() const {
536   // Currently this is only used on linux.
537   return 0;
540 void BrowserWindowCocoa::WebContentsFocused(WebContents* contents) {
541   NOTIMPLEMENTED();
544 void BrowserWindowCocoa::ShowWebsiteSettings(
545     Profile* profile,
546     content::WebContents* web_contents,
547     const GURL& url,
548     const content::SSLStatus& ssl) {
549   WebsiteSettingsUIBridge::Show(window(), profile, web_contents, url, ssl);
552 void BrowserWindowCocoa::ShowAppMenu() {
553   // No-op. Mac doesn't support showing the menus via alt keys.
556 bool BrowserWindowCocoa::PreHandleKeyboardEvent(
557     const NativeWebKeyboardEvent& event, bool* is_keyboard_shortcut) {
558   if (![BrowserWindowUtils shouldHandleKeyboardEvent:event])
559     return false;
561   if (event.type == blink::WebInputEvent::RawKeyDown &&
562       [controller_ handledByExtensionCommand:event.os_event])
563     return true;
565   int id = [BrowserWindowUtils getCommandId:event];
566   if (id == -1)
567     return false;
569   if (browser_->command_controller()->IsReservedCommandOrKey(id, event)) {
570       return [BrowserWindowUtils handleKeyboardEvent:event.os_event
571                                             inWindow:window()];
572   }
574   DCHECK(is_keyboard_shortcut);
575   *is_keyboard_shortcut = true;
576   return false;
579 void BrowserWindowCocoa::HandleKeyboardEvent(
580     const NativeWebKeyboardEvent& event) {
581   if ([BrowserWindowUtils shouldHandleKeyboardEvent:event])
582     [BrowserWindowUtils handleKeyboardEvent:event.os_event inWindow:window()];
585 void BrowserWindowCocoa::Cut() {
586   [NSApp sendAction:@selector(cut:) to:nil from:nil];
589 void BrowserWindowCocoa::Copy() {
590   [NSApp sendAction:@selector(copy:) to:nil from:nil];
593 void BrowserWindowCocoa::Paste() {
594   [NSApp sendAction:@selector(paste:) to:nil from:nil];
597 void BrowserWindowCocoa::OpenTabpose() {
598   [controller_ openTabpose];
601 void BrowserWindowCocoa::EnterFullscreenWithChrome() {
602   // This method cannot be called if simplified fullscreen is enabled.
603   const CommandLine* command_line = CommandLine::ForCurrentProcess();
604   DCHECK(!command_line->HasSwitch(switches::kEnableSimplifiedFullscreen));
606   CHECK(chrome::mac::SupportsSystemFullscreen());
607   if ([controller_ inPresentationMode])
608     [controller_ exitPresentationMode];
609   else
610     [controller_ enterFullscreen];
613 bool BrowserWindowCocoa::IsFullscreenWithChrome() {
614   // The WithChrome mode does not exist when simplified fullscreen is enabled.
615   const CommandLine* command_line = CommandLine::ForCurrentProcess();
616   if (command_line->HasSwitch(switches::kEnableSimplifiedFullscreen))
617     return false;
618   return IsFullscreen() && ![controller_ inPresentationMode];
621 bool BrowserWindowCocoa::IsFullscreenWithoutChrome() {
622   // Presentation mode does not exist if simplified fullscreen is enabled.  The
623   // WithoutChrome mode simply maps to whether or not the window is fullscreen.
624   const CommandLine* command_line = CommandLine::ForCurrentProcess();
625   if (command_line->HasSwitch(switches::kEnableSimplifiedFullscreen))
626     return IsFullscreen();
628   return IsFullscreen() && [controller_ inPresentationMode];
631 WindowOpenDisposition BrowserWindowCocoa::GetDispositionForPopupBounds(
632     const gfx::Rect& bounds) {
633   // In Lion fullscreen mode, convert popups into tabs.
634   if (chrome::mac::SupportsSystemFullscreen() && IsFullscreen())
635     return NEW_FOREGROUND_TAB;
636   return NEW_POPUP;
639 FindBar* BrowserWindowCocoa::CreateFindBar() {
640   // We could push the AddFindBar() call into the FindBarBridge
641   // constructor or the FindBarCocoaController init, but that makes
642   // unit testing difficult, since we would also require a
643   // BrowserWindow object.
644   FindBarBridge* bridge = new FindBarBridge(browser_);
645   AddFindBar(bridge->find_bar_cocoa_controller());
646   return bridge;
649 web_modal::WebContentsModalDialogHost*
650     BrowserWindowCocoa::GetWebContentsModalDialogHost() {
651   return NULL;
654 extensions::ActiveTabPermissionGranter*
655     BrowserWindowCocoa::GetActiveTabPermissionGranter() {
656   WebContents* web_contents =
657       browser_->tab_strip_model()->GetActiveWebContents();
658   if (!web_contents)
659     return NULL;
660   extensions::TabHelper* tab_helper =
661       extensions::TabHelper::FromWebContents(web_contents);
662   return tab_helper ? tab_helper->active_tab_permission_granter() : NULL;
665 void BrowserWindowCocoa::ModelChanged(const SearchModel::State& old_state,
666                                       const SearchModel::State& new_state) {
669 void BrowserWindowCocoa::DestroyBrowser() {
670   [controller_ destroyBrowser];
672   // at this point the controller is dead (autoreleased), so
673   // make sure we don't try to reference it any more.
676 NSWindow* BrowserWindowCocoa::window() const {
677   return [controller_ window];
680 void BrowserWindowCocoa::ShowAvatarBubble(WebContents* web_contents,
681                                           const gfx::Rect& rect) {
682   NSPoint point = GetPointForBubble(web_contents, rect.right(), rect.bottom());
684   // |menu| will automatically release itself on close.
685   AvatarMenuBubbleController* menu =
686       [[AvatarMenuBubbleController alloc] initWithBrowser:browser_
687                                                anchoredAt:point];
688   [[menu bubble] setAlignment:info_bubble::kAlignEdgeToAnchorEdge];
689   [menu showWindow:nil];
692 void BrowserWindowCocoa::ShowAvatarBubbleFromAvatarButton() {
693   AvatarButtonController* controller = [controller_ avatarButtonController];
694   [controller showAvatarBubble:[controller buttonView]];
697 void BrowserWindowCocoa::ShowPasswordGenerationBubble(
698     const gfx::Rect& rect,
699     const autofill::PasswordForm& form,
700     autofill::PasswordGenerator* password_generator) {
701   WebContents* web_contents =
702       browser_->tab_strip_model()->GetActiveWebContents();
703   // We want to point to the middle of the rect instead of the right side.
704   NSPoint point = GetPointForBubble(web_contents,
705                                     rect.x() + rect.width()/2,
706                                     rect.bottom());
708   PasswordGenerationBubbleController* controller =
709       [[PasswordGenerationBubbleController alloc]
710         initWithWindow:browser_->window()->GetNativeWindow()
711             anchoredAt:point
712         renderViewHost:web_contents->GetRenderViewHost()
713         passwordManager:PasswordManager::FromWebContents(web_contents)
714         usingGenerator:password_generator
715                forForm:form];
716   [controller showWindow:nil];
720 BrowserWindowCocoa::GetRenderViewHeightInsetWithDetachedBookmarkBar() {
721   if (browser_->bookmark_bar_state() != BookmarkBar::DETACHED)
722     return 0;
723   // TODO(sail): please make this work with cocoa, then enable
724   // BrowserTest.GetSizeForNewRenderView and
725   // WebContentsImplBrowserTest.GetSizeForNewRenderView.
726   // This function should return the extra height of the render view when
727   // detached bookmark bar is hidden.
728   // However, I (kuan) return 0 for now to retain the original behavior,
729   // because I encountered the following problem on cocoa:
730   // 1) When a navigation is requested,
731   //    WebContentsImpl::CreateRenderViewForRenderManager creates the new
732   //    RenderWidgetHostView at the size specified by
733   //    WebContentsDelegate::GetSizeForNewRenderView implemented by Browser.
734   // 2) When the pending navigation entry is committed,
735   //    WebContentsImpl::UpdateRenderViewSizeForRenderManager udpates the size
736   //    of WebContentsView to the size in (1).
737   // 3) WebContentsImpl::DidNavigateMainFramePostCommit() is called, where
738   //    the detached bookmark bar is hidden, resulting in relayout of tab
739   //    contents area.
740   // On cocoa, (2) causes RenderWidgetHostView to resize (enlarge) further.
741   // e.g. if size in (1) is size A, and this function returns height H, height
742   // of RenderWidgetHostView after (2) becomes A.height() + H; it's supposed to
743   // stay at A.height().
744   // Then, in (3), WebContentsView and RenderWidgetHostView enlarge even
745   // further, both by another H, i.e. WebContentsView's height becomes
746   // A.height() + H and RenderWidgetHostView's height becomes A.height() + 2H.
747   // Strangely, the RenderWidgetHostView for the previous navigation entry also
748   // gets enlarged by H.
749   // I believe these "automatic" resizing are caused by setAutoresizingMask of
750   // of the cocoa view in WebContentsViewMac, which defeats the purpose of
751   // WebContentsDelegate::GetSizeForNewRenderView i.e. to prevent resizing of
752   // RenderWidgetHostView in (2) and (3).
753   return 0;