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"
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/profiles/profile.h"
21 #include "chrome/browser/shell_integration.h"
22 #include "chrome/browser/signin/signin_header_helper.h"
23 #include "chrome/browser/translate/chrome_translate_client.h"
24 #include "chrome/browser/ui/browser.h"
25 #include "chrome/browser/ui/browser_command_controller.h"
26 #include "chrome/browser/ui/browser_commands_mac.h"
27 #include "chrome/browser/ui/browser_list.h"
28 #include "chrome/browser/ui/browser_window_state.h"
29 #import "chrome/browser/ui/cocoa/browser/edit_search_engine_cocoa_controller.h"
30 #import "chrome/browser/ui/cocoa/browser_window_controller.h"
31 #import "chrome/browser/ui/cocoa/browser_window_utils.h"
32 #import "chrome/browser/ui/cocoa/chrome_event_processing_window.h"
33 #import "chrome/browser/ui/cocoa/download/download_shelf_controller.h"
34 #include "chrome/browser/ui/cocoa/find_bar/find_bar_bridge.h"
35 #import "chrome/browser/ui/cocoa/info_bubble_view.h"
36 #import "chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h"
37 #import "chrome/browser/ui/cocoa/nsmenuitem_additions.h"
38 #import "chrome/browser/ui/cocoa/profiles/avatar_base_controller.h"
39 #import "chrome/browser/ui/cocoa/profiles/avatar_menu_bubble_controller.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/website_settings_bubble_controller.h"
46 #include "chrome/browser/ui/fullscreen/fullscreen_controller.h"
47 #include "chrome/browser/ui/search/search_model.h"
48 #include "chrome/browser/ui/tabs/tab_strip_model.h"
49 #include "chrome/browser/web_applications/web_app.h"
50 #include "chrome/common/chrome_switches.h"
51 #include "chrome/common/pref_names.h"
52 #include "components/translate/core/browser/language_state.h"
53 #include "content/public/browser/native_web_keyboard_event.h"
54 #include "content/public/browser/notification_details.h"
55 #include "content/public/browser/notification_source.h"
56 #include "content/public/browser/web_contents.h"
57 #include "ui/base/l10n/l10n_util_mac.h"
58 #include "ui/gfx/rect.h"
60 #if defined(ENABLE_ONE_CLICK_SIGNIN)
61 #import "chrome/browser/ui/cocoa/one_click_signin_bubble_controller.h"
62 #import "chrome/browser/ui/cocoa/one_click_signin_dialog_controller.h"
65 using content::NativeWebKeyboardEvent;
66 using content::SSLStatus;
67 using content::WebContents;
71 NSPoint GetPointForBubble(content::WebContents* web_contents,
74 NSView* view = web_contents->GetNativeView();
75 NSRect bounds = [view bounds];
77 point.x = NSMinX(bounds) + x_offset;
78 // The view's origin is at the bottom but |rect|'s origin is at the top.
79 point.y = NSMaxY(bounds) - y_offset;
80 point = [view convertPoint:point toView:nil];
81 point = [[view window] convertBaseToScreen:point];
87 BrowserWindowCocoa::BrowserWindowCocoa(Browser* browser,
88 BrowserWindowController* controller)
90 controller_(controller),
91 initial_show_state_(ui::SHOW_STATE_DEFAULT),
92 attention_request_id_(0) {
95 chrome::GetSavedWindowBoundsAndShowState(browser_,
97 &initial_show_state_);
99 browser_->search_model()->AddObserver(this);
102 BrowserWindowCocoa::~BrowserWindowCocoa() {
103 browser_->search_model()->RemoveObserver(this);
106 void BrowserWindowCocoa::Show() {
107 // The Browser associated with this browser window must become the active
108 // browser at the time |Show()| is called. This is the natural behaviour under
109 // Windows, but |-makeKeyAndOrderFront:| won't send |-windowDidBecomeMain:|
110 // until we return to the runloop. Therefore any calls to
111 // |chrome::FindLastActiveWithHostDesktopType| will return the previous
112 // browser instead if we don't explicitly set it here.
113 BrowserList::SetLastActive(browser_);
115 bool is_session_restore = browser_->is_session_restore();
116 NSWindowAnimationBehavior saved_animation_behavior =
117 NSWindowAnimationBehaviorDefault;
118 bool did_save_animation_behavior = false;
119 // Turn off swishing when restoring windows.
120 if (is_session_restore &&
121 [window() respondsToSelector:@selector(animationBehavior)] &&
122 [window() respondsToSelector:@selector(setAnimationBehavior:)]) {
123 did_save_animation_behavior = true;
124 saved_animation_behavior = [window() animationBehavior];
125 [window() setAnimationBehavior:NSWindowAnimationBehaviorNone];
129 TRACE_EVENT0("ui", "BrowserWindowCocoa::Show makeKeyAndOrderFront");
130 // This call takes up a substantial part of startup time, and an even more
131 // substantial part of startup time when any CALayers are part of the
132 // window's NSView heirarchy.
133 [window() makeKeyAndOrderFront:controller_];
136 // When creating windows from nibs it is necessary to |makeKeyAndOrderFront:|
137 // prior to |orderOut:| then |miniaturize:| when restoring windows in the
139 if (initial_show_state_ == ui::SHOW_STATE_MINIMIZED) {
140 [window() orderOut:controller_];
141 [window() miniaturize:controller_];
142 } else if (initial_show_state_ == ui::SHOW_STATE_FULLSCREEN) {
143 chrome::ToggleFullscreenWithChromeOrFallback(browser_);
145 initial_show_state_ = ui::SHOW_STATE_DEFAULT;
147 // Restore window animation behavior.
148 if (did_save_animation_behavior)
149 [window() setAnimationBehavior:saved_animation_behavior];
151 browser_->OnWindowDidShow();
154 void BrowserWindowCocoa::ShowInactive() {
155 [window() orderFront:controller_];
158 void BrowserWindowCocoa::Hide() {
162 void BrowserWindowCocoa::SetBounds(const gfx::Rect& bounds) {
163 gfx::Rect real_bounds = [controller_ enforceMinWindowSize:bounds];
166 NSRect cocoa_bounds = NSMakeRect(real_bounds.x(), 0,
168 real_bounds.height());
169 // Flip coordinates based on the primary screen.
170 NSScreen* screen = [[NSScreen screens] objectAtIndex:0];
171 cocoa_bounds.origin.y =
172 NSHeight([screen frame]) - real_bounds.height() - real_bounds.y();
174 [window() setFrame:cocoa_bounds display:YES];
177 // Callers assume that this doesn't immediately delete the Browser object.
178 // The controller implementing the window delegate methods called from
179 // |-performClose:| must take precautions to ensure that.
180 void BrowserWindowCocoa::Close() {
181 // If there is an overlay window, we contain a tab being dragged between
182 // windows. Don't hide the window as it makes the UI extra confused. We can
183 // still close the window, as that will happen when the drag completes.
184 if ([controller_ overlayWindow]) {
185 [controller_ deferPerformClose];
187 // Using |-performClose:| can prevent the window from actually closing if
188 // a JavaScript beforeunload handler opens an alert during shutdown, as
189 // documented at <http://crbug.com/118424>. Re-implement
190 // -[NSWindow performClose:] as closely as possible to how Apple documents
193 // Before calling |-close|, hide the window immediately. |-performClose:|
194 // would do something similar, and this ensures that the window is removed
195 // from AppKit's display list. Not doing so can lead to crashes like
196 // <http://crbug.com/156101>.
197 id<NSWindowDelegate> delegate = [window() delegate];
198 SEL window_should_close = @selector(windowShouldClose:);
199 if ([delegate respondsToSelector:window_should_close]) {
200 if ([delegate windowShouldClose:window()]) {
201 [window() orderOut:nil];
204 } else if ([window() respondsToSelector:window_should_close]) {
205 if ([window() performSelector:window_should_close withObject:window()]) {
206 [window() orderOut:nil];
210 [window() orderOut:nil];
216 void BrowserWindowCocoa::Activate() {
217 [controller_ activate];
220 void BrowserWindowCocoa::Deactivate() {
221 // TODO(jcivelli): http://crbug.com/51364 Implement me.
225 void BrowserWindowCocoa::FlashFrame(bool flash) {
227 attention_request_id_ = [NSApp requestUserAttention:NSInformationalRequest];
229 [NSApp cancelUserAttentionRequest:attention_request_id_];
230 attention_request_id_ = 0;
234 bool BrowserWindowCocoa::IsAlwaysOnTop() const {
238 void BrowserWindowCocoa::SetAlwaysOnTop(bool always_on_top) {
239 // Not implemented for browser windows.
243 bool BrowserWindowCocoa::IsActive() const {
244 return [window() isKeyWindow];
247 gfx::NativeWindow BrowserWindowCocoa::GetNativeWindow() {
251 BrowserWindowTesting* BrowserWindowCocoa::GetBrowserWindowTesting() {
255 StatusBubble* BrowserWindowCocoa::GetStatusBubble() {
256 return [controller_ statusBubble];
259 void BrowserWindowCocoa::UpdateTitleBar() {
261 base::SysUTF16ToNSString(browser_->GetWindowTitleForCurrentTab());
263 pending_window_title_.reset(
264 [BrowserWindowUtils scheduleReplaceOldTitle:pending_window_title_.get()
265 withNewTitle:newTitle
266 forWindow:window()]);
269 void BrowserWindowCocoa::BookmarkBarStateChanged(
270 BookmarkBar::AnimateChangeType change_type) {
271 [[controller_ bookmarkBarController]
272 updateState:browser_->bookmark_bar_state()
273 changeType:change_type];
276 void BrowserWindowCocoa::UpdateDevTools() {
277 [controller_ updateDevToolsForContents:
278 browser_->tab_strip_model()->GetActiveWebContents()];
281 void BrowserWindowCocoa::UpdateLoadingAnimations(bool should_animate) {
282 // Do nothing on Mac.
285 void BrowserWindowCocoa::SetStarredState(bool is_starred) {
286 [controller_ setStarredState:is_starred];
289 void BrowserWindowCocoa::SetTranslateIconToggled(bool is_lit) {
290 [controller_ setCurrentPageIsTranslated:is_lit];
293 void BrowserWindowCocoa::OnActiveTabChanged(content::WebContents* old_contents,
294 content::WebContents* new_contents,
297 // TODO(pkasting): Perhaps the code in
298 // TabStripController::activateTabWithContents should move here? Or this
299 // should call that (instead of TabStripModelObserverBridge doing so)? It's
300 // not obvious to me why Mac doesn't handle tab changes in BrowserWindow the
301 // way views and GTK do.
304 void BrowserWindowCocoa::ZoomChangedForActiveTab(bool can_show_bubble) {
305 [controller_ zoomChangedForActiveTab:can_show_bubble ? YES : NO];
308 gfx::Rect BrowserWindowCocoa::GetRestoredBounds() const {
309 // Flip coordinates based on the primary screen.
310 NSScreen* screen = [[NSScreen screens] objectAtIndex:0];
311 NSRect frame = [controller_ regularWindowFrame];
312 gfx::Rect bounds(frame.origin.x, 0, NSWidth(frame), NSHeight(frame));
313 bounds.set_y(NSHeight([screen frame]) - NSMaxY(frame));
317 ui::WindowShowState BrowserWindowCocoa::GetRestoredState() const {
319 return ui::SHOW_STATE_MAXIMIZED;
321 return ui::SHOW_STATE_MINIMIZED;
322 return ui::SHOW_STATE_NORMAL;
325 gfx::Rect BrowserWindowCocoa::GetBounds() const {
326 return GetRestoredBounds();
329 bool BrowserWindowCocoa::IsMaximized() const {
330 return [window() isZoomed];
333 bool BrowserWindowCocoa::IsMinimized() const {
334 return [window() isMiniaturized];
337 void BrowserWindowCocoa::Maximize() {
338 // Zoom toggles so only call if not already maximized.
340 [window() zoom:controller_];
343 void BrowserWindowCocoa::Minimize() {
344 [window() miniaturize:controller_];
347 void BrowserWindowCocoa::Restore() {
349 [window() zoom:controller_]; // Toggles zoom mode.
350 else if (IsMinimized())
351 [window() deminiaturize:controller_];
354 // See browser_window_controller.h for a detailed explanation of the logic in
356 void BrowserWindowCocoa::EnterFullscreen(const GURL& url,
357 FullscreenExitBubbleType bubble_type) {
358 if (browser_->fullscreen_controller()->IsWindowFullscreenForTabOrPending()) {
359 [controller_ enterWebContentFullscreenForURL:url bubbleType:bubble_type];
363 if (url.is_empty()) {
364 [controller_ enterPresentationMode];
366 [controller_ enterExtensionFullscreenForURL:url bubbleType:bubble_type];
370 void BrowserWindowCocoa::ExitFullscreen() {
371 [controller_ exitAnyFullscreen];
374 void BrowserWindowCocoa::UpdateFullscreenExitBubbleContent(
376 FullscreenExitBubbleType bubble_type) {
377 [controller_ updateFullscreenExitBubbleURL:url bubbleType:bubble_type];
380 bool BrowserWindowCocoa::ShouldHideUIForFullscreen() const {
381 // On Mac, fullscreen mode has most normal things (in a slide-down panel).
385 bool BrowserWindowCocoa::IsFullscreen() const {
386 return [controller_ isInAnyFullscreenMode];
389 bool BrowserWindowCocoa::IsFullscreenBubbleVisible() const {
393 void BrowserWindowCocoa::ConfirmAddSearchProvider(
394 TemplateURL* template_url,
396 // The controller will release itself when the window closes.
397 EditSearchEngineCocoaController* editor =
398 [[EditSearchEngineCocoaController alloc] initWithProfile:profile
400 templateURL:template_url];
401 [NSApp beginSheet:[editor window]
402 modalForWindow:window()
403 modalDelegate:controller_
404 didEndSelector:@selector(sheetDidEnd:returnCode:context:)
408 LocationBar* BrowserWindowCocoa::GetLocationBar() const {
409 return [controller_ locationBarBridge];
412 void BrowserWindowCocoa::SetFocusToLocationBar(bool select_all) {
413 [controller_ focusLocationBar:select_all ? YES : NO];
416 void BrowserWindowCocoa::UpdateReloadStopState(bool is_loading, bool force) {
417 [controller_ setIsLoading:is_loading force:force];
420 void BrowserWindowCocoa::UpdateToolbar(content::WebContents* contents) {
421 [controller_ updateToolbarWithContents:contents];
424 void BrowserWindowCocoa::FocusToolbar() {
425 // Not needed on the Mac.
428 void BrowserWindowCocoa::FocusAppMenu() {
429 // Chrome uses the standard Mac OS X menu bar, so this isn't needed.
432 void BrowserWindowCocoa::RotatePaneFocus(bool forwards) {
433 // Not needed on the Mac.
436 void BrowserWindowCocoa::FocusBookmarksToolbar() {
437 // Not needed on the Mac.
440 void BrowserWindowCocoa::FocusInfobars() {
441 // Not needed on the Mac.
444 bool BrowserWindowCocoa::IsBookmarkBarVisible() const {
445 return browser_->profile()->GetPrefs()->GetBoolean(
446 bookmarks::prefs::kShowBookmarkBar);
449 bool BrowserWindowCocoa::IsBookmarkBarAnimating() const {
450 return [controller_ isBookmarkBarAnimating];
453 bool BrowserWindowCocoa::IsTabStripEditable() const {
454 return ![controller_ isDragSessionActive];
457 bool BrowserWindowCocoa::IsToolbarVisible() const {
458 return browser_->SupportsWindowFeature(Browser::FEATURE_TOOLBAR) ||
459 browser_->SupportsWindowFeature(Browser::FEATURE_LOCATIONBAR);
462 gfx::Rect BrowserWindowCocoa::GetRootWindowResizerRect() const {
463 if (IsDownloadShelfVisible())
465 NSRect tabRect = [controller_ selectedTabGrowBoxRect];
466 return gfx::Rect(NSRectToCGRect(tabRect));
469 void BrowserWindowCocoa::AddFindBar(
470 FindBarCocoaController* find_bar_cocoa_controller) {
471 [controller_ addFindBar:find_bar_cocoa_controller];
474 void BrowserWindowCocoa::ShowUpdateChromeDialog() {
475 restart_browser::RequestRestart(window());
478 void BrowserWindowCocoa::ShowBookmarkBubble(const GURL& url,
479 bool already_bookmarked) {
480 [controller_ showBookmarkBubbleForURL:url
481 alreadyBookmarked:(already_bookmarked ? YES : NO)];
484 void BrowserWindowCocoa::ShowBookmarkAppBubble(
485 const WebApplicationInfo& web_app_info,
486 const std::string& extension_id) {
490 void BrowserWindowCocoa::ShowTranslateBubble(
491 content::WebContents* contents,
492 translate::TranslateStep step,
493 translate::TranslateErrors::Type error_type,
494 bool is_user_gesture) {
495 ChromeTranslateClient* chrome_translate_client =
496 ChromeTranslateClient::FromWebContents(contents);
497 translate::LanguageState& language_state =
498 chrome_translate_client->GetLanguageState();
499 language_state.SetTranslateEnabled(true);
501 [controller_ showTranslateBubbleForWebContents:contents
503 errorType:error_type];
506 #if defined(ENABLE_ONE_CLICK_SIGNIN)
507 void BrowserWindowCocoa::ShowOneClickSigninBubble(
508 OneClickSigninBubbleType type,
509 const base::string16& email,
510 const base::string16& error_message,
511 const StartSyncCallback& start_sync_callback) {
512 WebContents* web_contents =
513 browser_->tab_strip_model()->GetActiveWebContents();
514 if (type == ONE_CLICK_SIGNIN_BUBBLE_TYPE_BUBBLE) {
515 base::scoped_nsobject<OneClickSigninBubbleController> bubble_controller([
516 [OneClickSigninBubbleController alloc]
517 initWithBrowserWindowController:cocoa_controller()
518 webContents:web_contents
519 errorMessage:base::SysUTF16ToNSString(error_message)
520 callback:start_sync_callback]);
521 [bubble_controller showWindow:nil];
523 // Deletes itself when the dialog closes.
524 new OneClickSigninDialogController(
525 web_contents, start_sync_callback, email);
530 bool BrowserWindowCocoa::IsDownloadShelfVisible() const {
531 return [controller_ isDownloadShelfVisible] != NO;
534 DownloadShelf* BrowserWindowCocoa::GetDownloadShelf() {
535 [controller_ createAndAddDownloadShelf];
536 DownloadShelfController* shelfController = [controller_ downloadShelf];
537 return [shelfController bridge];
540 // We allow closing the window here since the real quit decision on Mac is made
541 // in [AppController quit:].
542 void BrowserWindowCocoa::ConfirmBrowserCloseWithPendingDownloads(
544 Browser::DownloadClosePreventionType dialog_type,
546 const base::Callback<void(bool)>& callback) {
550 void BrowserWindowCocoa::UserChangedTheme() {
551 [controller_ userChangedTheme];
554 int BrowserWindowCocoa::GetExtraRenderViewHeight() const {
555 // Currently this is only used on linux.
559 void BrowserWindowCocoa::WebContentsFocused(WebContents* contents) {
563 void BrowserWindowCocoa::ShowWebsiteSettings(
565 content::WebContents* web_contents,
567 const content::SSLStatus& ssl) {
568 WebsiteSettingsUIBridge::Show(window(), profile, web_contents, url, ssl);
571 void BrowserWindowCocoa::ShowAppMenu() {
572 // No-op. Mac doesn't support showing the menus via alt keys.
575 bool BrowserWindowCocoa::PreHandleKeyboardEvent(
576 const NativeWebKeyboardEvent& event, bool* is_keyboard_shortcut) {
577 if (![BrowserWindowUtils shouldHandleKeyboardEvent:event])
580 if (event.type == blink::WebInputEvent::RawKeyDown &&
582 handledByExtensionCommand:event.os_event
583 priority:ui::AcceleratorManager::kHighPriority])
586 int id = [BrowserWindowUtils getCommandId:event];
590 if (browser_->command_controller()->IsReservedCommandOrKey(id, event)) {
591 return [BrowserWindowUtils handleKeyboardEvent:event.os_event
595 DCHECK(is_keyboard_shortcut);
596 *is_keyboard_shortcut = true;
600 void BrowserWindowCocoa::HandleKeyboardEvent(
601 const NativeWebKeyboardEvent& event) {
602 if ([BrowserWindowUtils shouldHandleKeyboardEvent:event])
603 [BrowserWindowUtils handleKeyboardEvent:event.os_event inWindow:window()];
606 void BrowserWindowCocoa::Cut() {
607 [NSApp sendAction:@selector(cut:) to:nil from:nil];
610 void BrowserWindowCocoa::Copy() {
611 [NSApp sendAction:@selector(copy:) to:nil from:nil];
614 void BrowserWindowCocoa::Paste() {
615 [NSApp sendAction:@selector(paste:) to:nil from:nil];
618 void BrowserWindowCocoa::EnterFullscreenWithChrome() {
619 CHECK(chrome::mac::SupportsSystemFullscreen());
620 [controller_ enterFullscreenWithChrome];
623 bool BrowserWindowCocoa::IsFullscreenWithChrome() {
624 return IsFullscreen() && ![controller_ inPresentationMode];
627 bool BrowserWindowCocoa::IsFullscreenWithoutChrome() {
628 return IsFullscreen() && [controller_ inPresentationMode];
631 WindowOpenDisposition BrowserWindowCocoa::GetDispositionForPopupBounds(
632 const gfx::Rect& bounds) {
633 // When using Cocoa's System Fullscreen mode, convert popups into tabs.
634 if ([controller_ isInAppKitFullscreen])
635 return NEW_FOREGROUND_TAB;
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());
649 web_modal::WebContentsModalDialogHost*
650 BrowserWindowCocoa::GetWebContentsModalDialogHost() {
654 extensions::ActiveTabPermissionGranter*
655 BrowserWindowCocoa::GetActiveTabPermissionGranter() {
656 WebContents* web_contents =
657 browser_->tab_strip_model()->GetActiveWebContents();
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_
688 [[menu bubble] setAlignment:info_bubble::kAlignEdgeToAnchorEdge];
689 [menu showWindow:nil];
692 void BrowserWindowCocoa::ShowAvatarBubbleFromAvatarButton(
693 AvatarBubbleMode mode,
694 const signin::ManageAccountsParams& manage_accounts_params) {
695 AvatarBaseController* controller = [controller_ avatarButtonController];
696 NSView* anchor = [controller buttonView];
697 if ([anchor isHiddenOrHasHiddenAncestor])
698 anchor = [[controller_ toolbarController] wrenchButton];
699 [controller showAvatarBubbleAnchoredAt:anchor
701 withServiceType:manage_accounts_params.service_type];
705 BrowserWindowCocoa::GetRenderViewHeightInsetWithDetachedBookmarkBar() {
706 if (browser_->bookmark_bar_state() != BookmarkBar::DETACHED)
711 void BrowserWindowCocoa::ExecuteExtensionCommand(
712 const extensions::Extension* extension,
713 const extensions::Command& command) {
714 [cocoa_controller() executeExtensionCommand:extension->id() command:command];