Add unit test for the Settings API Bubble.
[chromium-blink-merge.git] / chrome / browser / ui / cocoa / browser_window_cocoa.mm
blob63731fe55d9f9284041600a68aea54e37980166d
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/chrome_password_manager_client.h"
21 #include "chrome/browser/profiles/profile.h"
22 #include "chrome/browser/shell_integration.h"
23 #include "chrome/browser/translate/translate_tab_helper.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/avatar_base_controller.h"
30 #import "chrome/browser/ui/cocoa/browser/avatar_menu_bubble_controller.h"
31 #import "chrome/browser/ui/cocoa/browser/edit_search_engine_cocoa_controller.h"
32 #import "chrome/browser/ui/cocoa/browser/password_generation_bubble_controller.h"
33 #import "chrome/browser/ui/cocoa/browser_window_controller.h"
34 #import "chrome/browser/ui/cocoa/browser_window_utils.h"
35 #import "chrome/browser/ui/cocoa/chrome_event_processing_window.h"
36 #import "chrome/browser/ui/cocoa/download/download_shelf_controller.h"
37 #include "chrome/browser/ui/cocoa/find_bar/find_bar_bridge.h"
38 #import "chrome/browser/ui/cocoa/info_bubble_view.h"
39 #import "chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h"
40 #import "chrome/browser/ui/cocoa/nsmenuitem_additions.h"
41 #include "chrome/browser/ui/cocoa/restart_browser.h"
42 #include "chrome/browser/ui/cocoa/status_bubble_mac.h"
43 #include "chrome/browser/ui/cocoa/task_manager_mac.h"
44 #import "chrome/browser/ui/cocoa/toolbar/toolbar_controller.h"
45 #import "chrome/browser/ui/cocoa/web_dialog_window_controller.h"
46 #import "chrome/browser/ui/cocoa/website_settings_bubble_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/autofill/core/common/password_form.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 "content/public/browser/web_contents_view.h"
58 #include "grit/chromium_strings.h"
59 #include "grit/generated_resources.h"
60 #include "ui/base/l10n/l10n_util_mac.h"
61 #include "ui/gfx/rect.h"
63 #if defined(ENABLE_ONE_CLICK_SIGNIN)
64 #import "chrome/browser/ui/cocoa/one_click_signin_bubble_controller.h"
65 #import "chrome/browser/ui/cocoa/one_click_signin_dialog_controller.h"
66 #endif
68 using content::NativeWebKeyboardEvent;
69 using content::SSLStatus;
70 using content::WebContents;
72 namespace {
74 NSPoint GetPointForBubble(content::WebContents* web_contents,
75                           int x_offset,
76                           int y_offset) {
77   NSView* view = web_contents->GetView()->GetNativeView();
78   NSRect bounds = [view bounds];
79   NSPoint point;
80   point.x = NSMinX(bounds) + x_offset;
81   // The view's origin is at the bottom but |rect|'s origin is at the top.
82   point.y = NSMaxY(bounds) - y_offset;
83   point = [view convertPoint:point toView:nil];
84   point = [[view window] convertBaseToScreen:point];
85   return point;
88 }  // namespace
90 BrowserWindowCocoa::BrowserWindowCocoa(Browser* browser,
91                                        BrowserWindowController* controller)
92   : browser_(browser),
93     controller_(controller),
94     initial_show_state_(ui::SHOW_STATE_DEFAULT),
95     attention_request_id_(0) {
97   gfx::Rect bounds;
98   chrome::GetSavedWindowBoundsAndShowState(browser_,
99                                            &bounds,
100                                            &initial_show_state_);
102   browser_->search_model()->AddObserver(this);
105 BrowserWindowCocoa::~BrowserWindowCocoa() {
106   browser_->search_model()->RemoveObserver(this);
109 void BrowserWindowCocoa::Show() {
110   // The Browser associated with this browser window must become the active
111   // browser at the time |Show()| is called. This is the natural behaviour under
112   // Windows, but |-makeKeyAndOrderFront:| won't send |-windowDidBecomeMain:|
113   // until we return to the runloop. Therefore any calls to
114   // |chrome::FindLastActiveWithHostDesktopType| will return the previous
115   // browser instead if we don't explicitly set it here.
116   BrowserList::SetLastActive(browser_);
118   bool is_session_restore = browser_->is_session_restore();
119   NSWindowAnimationBehavior saved_animation_behavior =
120       NSWindowAnimationBehaviorDefault;
121   bool did_save_animation_behavior = false;
122   // Turn off swishing when restoring windows.
123   if (is_session_restore &&
124       [window() respondsToSelector:@selector(animationBehavior)] &&
125       [window() respondsToSelector:@selector(setAnimationBehavior:)]) {
126     did_save_animation_behavior = true;
127     saved_animation_behavior = [window() animationBehavior];
128     [window() setAnimationBehavior:NSWindowAnimationBehaviorNone];
129   }
131   {
132     TRACE_EVENT0("ui", "BrowserWindowCocoa::Show makeKeyAndOrderFront");
133     // This call takes up a substantial part of startup time, and an even more
134     // substantial part of startup time when any CALayers are part of the
135     // window's NSView heirarchy.
136     [window() makeKeyAndOrderFront:controller_];
137   }
139   // When creating windows from nibs it is necessary to |makeKeyAndOrderFront:|
140   // prior to |orderOut:| then |miniaturize:| when restoring windows in the
141   // minimized state.
142   if (initial_show_state_ == ui::SHOW_STATE_MINIMIZED) {
143     [window() orderOut:controller_];
144     [window() miniaturize:controller_];
145   } else if (initial_show_state_ == ui::SHOW_STATE_FULLSCREEN) {
146     chrome::ToggleFullscreenWithChromeOrFallback(browser_);
147   }
148   initial_show_state_ = ui::SHOW_STATE_DEFAULT;
150   // Restore window animation behavior.
151   if (did_save_animation_behavior)
152     [window() setAnimationBehavior:saved_animation_behavior];
154   browser_->OnWindowDidShow();
157 void BrowserWindowCocoa::ShowInactive() {
158   [window() orderFront:controller_];
161 void BrowserWindowCocoa::Hide() {
162   // Not implemented.
165 void BrowserWindowCocoa::SetBounds(const gfx::Rect& bounds) {
166   gfx::Rect real_bounds = [controller_ enforceMinWindowSize:bounds];
168   ExitFullscreen();
169   NSRect cocoa_bounds = NSMakeRect(real_bounds.x(), 0,
170                                    real_bounds.width(),
171                                    real_bounds.height());
172   // Flip coordinates based on the primary screen.
173   NSScreen* screen = [[NSScreen screens] objectAtIndex:0];
174   cocoa_bounds.origin.y =
175       NSHeight([screen frame]) - real_bounds.height() - real_bounds.y();
177   [window() setFrame:cocoa_bounds display:YES];
180 // Callers assume that this doesn't immediately delete the Browser object.
181 // The controller implementing the window delegate methods called from
182 // |-performClose:| must take precautions to ensure that.
183 void BrowserWindowCocoa::Close() {
184   // If there is an overlay window, we contain a tab being dragged between
185   // windows. Don't hide the window as it makes the UI extra confused. We can
186   // still close the window, as that will happen when the drag completes.
187   if ([controller_ overlayWindow]) {
188     [controller_ deferPerformClose];
189   } else {
190     // Using |-performClose:| can prevent the window from actually closing if
191     // a JavaScript beforeunload handler opens an alert during shutdown, as
192     // documented at <http://crbug.com/118424>. Re-implement
193     // -[NSWindow performClose:] as closely as possible to how Apple documents
194     // it.
195     //
196     // Before calling |-close|, hide the window immediately. |-performClose:|
197     // would do something similar, and this ensures that the window is removed
198     // from AppKit's display list. Not doing so can lead to crashes like
199     // <http://crbug.com/156101>.
200     id<NSWindowDelegate> delegate = [window() delegate];
201     SEL window_should_close = @selector(windowShouldClose:);
202     if ([delegate respondsToSelector:window_should_close]) {
203       if ([delegate windowShouldClose:window()]) {
204         [window() orderOut:nil];
205         [window() close];
206       }
207     } else if ([window() respondsToSelector:window_should_close]) {
208       if ([window() performSelector:window_should_close withObject:window()]) {
209         [window() orderOut:nil];
210         [window() close];
211       }
212     } else {
213       [window() orderOut:nil];
214       [window() close];
215     }
216   }
219 void BrowserWindowCocoa::Activate() {
220   [controller_ activate];
223 void BrowserWindowCocoa::Deactivate() {
224   // TODO(jcivelli): http://crbug.com/51364 Implement me.
225   NOTIMPLEMENTED();
228 void BrowserWindowCocoa::FlashFrame(bool flash) {
229   if (flash) {
230     attention_request_id_ = [NSApp requestUserAttention:NSInformationalRequest];
231   } else {
232     [NSApp cancelUserAttentionRequest:attention_request_id_];
233     attention_request_id_ = 0;
234   }
237 bool BrowserWindowCocoa::IsAlwaysOnTop() const {
238   return false;
241 void BrowserWindowCocoa::SetAlwaysOnTop(bool always_on_top) {
242   // Not implemented for browser windows.
243   NOTIMPLEMENTED();
246 bool BrowserWindowCocoa::IsActive() const {
247   return [window() isKeyWindow];
250 gfx::NativeWindow BrowserWindowCocoa::GetNativeWindow() {
251   return window();
254 BrowserWindowTesting* BrowserWindowCocoa::GetBrowserWindowTesting() {
255   return NULL;
258 StatusBubble* BrowserWindowCocoa::GetStatusBubble() {
259   return [controller_ statusBubble];
262 void BrowserWindowCocoa::UpdateTitleBar() {
263   NSString* newTitle =
264       base::SysUTF16ToNSString(browser_->GetWindowTitleForCurrentTab());
266   pending_window_title_.reset(
267       [BrowserWindowUtils scheduleReplaceOldTitle:pending_window_title_.get()
268                                      withNewTitle:newTitle
269                                         forWindow:window()]);
272 void BrowserWindowCocoa::BookmarkBarStateChanged(
273     BookmarkBar::AnimateChangeType change_type) {
274   [[controller_ bookmarkBarController]
275       updateState:browser_->bookmark_bar_state()
276        changeType:change_type];
279 void BrowserWindowCocoa::UpdateDevTools() {
280   [controller_ updateDevToolsForContents:
281       browser_->tab_strip_model()->GetActiveWebContents()];
284 void BrowserWindowCocoa::UpdateLoadingAnimations(bool should_animate) {
285   // Do nothing on Mac.
288 void BrowserWindowCocoa::SetStarredState(bool is_starred) {
289   [controller_ setStarredState:is_starred];
292 void BrowserWindowCocoa::SetTranslateIconToggled(bool is_lit) {
293   [controller_ setCurrentPageIsTranslated:is_lit];
296 void BrowserWindowCocoa::OnActiveTabChanged(content::WebContents* old_contents,
297                                             content::WebContents* new_contents,
298                                             int index,
299                                             int reason) {
300   // TODO(pkasting): Perhaps the code in
301   // TabStripController::activateTabWithContents should move here?  Or this
302   // should call that (instead of TabStripModelObserverBridge doing so)?  It's
303   // not obvious to me why Mac doesn't handle tab changes in BrowserWindow the
304   // way views and GTK do.
307 void BrowserWindowCocoa::ZoomChangedForActiveTab(bool can_show_bubble) {
308   [controller_ zoomChangedForActiveTab:can_show_bubble ? YES : NO];
311 gfx::Rect BrowserWindowCocoa::GetRestoredBounds() const {
312   // Flip coordinates based on the primary screen.
313   NSScreen* screen = [[NSScreen screens] objectAtIndex:0];
314   NSRect frame = [controller_ regularWindowFrame];
315   gfx::Rect bounds(frame.origin.x, 0, NSWidth(frame), NSHeight(frame));
316   bounds.set_y(NSHeight([screen frame]) - NSMaxY(frame));
317   return bounds;
320 ui::WindowShowState BrowserWindowCocoa::GetRestoredState() const {
321   if (IsMaximized())
322     return ui::SHOW_STATE_MAXIMIZED;
323   if (IsMinimized())
324     return ui::SHOW_STATE_MINIMIZED;
325   return ui::SHOW_STATE_NORMAL;
328 gfx::Rect BrowserWindowCocoa::GetBounds() const {
329   return GetRestoredBounds();
332 bool BrowserWindowCocoa::IsMaximized() const {
333   return [window() isZoomed];
336 bool BrowserWindowCocoa::IsMinimized() const {
337   return [window() isMiniaturized];
340 void BrowserWindowCocoa::Maximize() {
341   // Zoom toggles so only call if not already maximized.
342   if (!IsMaximized())
343     [window() zoom:controller_];
346 void BrowserWindowCocoa::Minimize() {
347   [window() miniaturize:controller_];
350 void BrowserWindowCocoa::Restore() {
351   if (IsMaximized())
352     [window() zoom:controller_];  // Toggles zoom mode.
353   else if (IsMinimized())
354     [window() deminiaturize:controller_];
357 void BrowserWindowCocoa::EnterFullscreen(
358       const GURL& url, FullscreenExitBubbleType bubble_type) {
359   // When simplified fullscreen is enabled, always enter normal fullscreen.
360   const CommandLine* command_line = CommandLine::ForCurrentProcess();
361   if (command_line->HasSwitch(switches::kEnableSimplifiedFullscreen)) {
362     if (url.is_empty())
363       [controller_ enterFullscreen];
364     else
365       [controller_ enterFullscreenForURL:url bubbleType:bubble_type];
366     return;
367   }
369   [controller_ enterPresentationModeForURL:url
370                                 bubbleType:bubble_type];
373 void BrowserWindowCocoa::ExitFullscreen() {
374   [controller_ exitFullscreen];
377 void BrowserWindowCocoa::UpdateFullscreenExitBubbleContent(
378       const GURL& url,
379       FullscreenExitBubbleType bubble_type) {
380   [controller_ updateFullscreenExitBubbleURL:url bubbleType:bubble_type];
383 bool BrowserWindowCocoa::ShouldHideUIForFullscreen() const {
384   // On Mac, fullscreen mode has most normal things (in a slide-down panel).
385   return false;
388 bool BrowserWindowCocoa::IsFullscreen() const {
389   if ([controller_ inPresentationMode])
390     CHECK([controller_ isFullscreen]);  // Presentation mode must be fullscreen.
391   return [controller_ isFullscreen];
394 bool BrowserWindowCocoa::IsFullscreenBubbleVisible() const {
395   return false;
398 void BrowserWindowCocoa::ConfirmAddSearchProvider(
399     TemplateURL* template_url,
400     Profile* profile) {
401   // The controller will release itself when the window closes.
402   EditSearchEngineCocoaController* editor =
403       [[EditSearchEngineCocoaController alloc] initWithProfile:profile
404                                                       delegate:NULL
405                                                    templateURL:template_url];
406   [NSApp beginSheet:[editor window]
407      modalForWindow:window()
408       modalDelegate:controller_
409      didEndSelector:@selector(sheetDidEnd:returnCode:context:)
410         contextInfo:NULL];
413 LocationBar* BrowserWindowCocoa::GetLocationBar() const {
414   return [controller_ locationBarBridge];
417 void BrowserWindowCocoa::SetFocusToLocationBar(bool select_all) {
418   [controller_ focusLocationBar:select_all ? YES : NO];
421 void BrowserWindowCocoa::UpdateReloadStopState(bool is_loading, bool force) {
422   [controller_ setIsLoading:is_loading force:force];
425 void BrowserWindowCocoa::UpdateToolbar(content::WebContents* contents) {
426   [controller_ updateToolbarWithContents:contents];
429 void BrowserWindowCocoa::FocusToolbar() {
430   // Not needed on the Mac.
433 void BrowserWindowCocoa::FocusAppMenu() {
434   // Chrome uses the standard Mac OS X menu bar, so this isn't needed.
437 void BrowserWindowCocoa::RotatePaneFocus(bool forwards) {
438   // Not needed on the Mac.
441 void BrowserWindowCocoa::FocusBookmarksToolbar() {
442   // Not needed on the Mac.
445 void BrowserWindowCocoa::FocusInfobars() {
446   // Not needed on the Mac.
449 bool BrowserWindowCocoa::IsBookmarkBarVisible() const {
450   return browser_->profile()->GetPrefs()->GetBoolean(prefs::kShowBookmarkBar);
453 bool BrowserWindowCocoa::IsBookmarkBarAnimating() const {
454   return [controller_ isBookmarkBarAnimating];
457 bool BrowserWindowCocoa::IsTabStripEditable() const {
458   return ![controller_ isDragSessionActive];
461 bool BrowserWindowCocoa::IsToolbarVisible() const {
462   return browser_->SupportsWindowFeature(Browser::FEATURE_TOOLBAR) ||
463          browser_->SupportsWindowFeature(Browser::FEATURE_LOCATIONBAR);
466 gfx::Rect BrowserWindowCocoa::GetRootWindowResizerRect() const {
467   if (IsDownloadShelfVisible())
468     return gfx::Rect();
469   NSRect tabRect = [controller_ selectedTabGrowBoxRect];
470   return gfx::Rect(NSRectToCGRect(tabRect));
473 void BrowserWindowCocoa::AddFindBar(
474     FindBarCocoaController* find_bar_cocoa_controller) {
475   [controller_ addFindBar:find_bar_cocoa_controller];
478 void BrowserWindowCocoa::ShowUpdateChromeDialog() {
479   restart_browser::RequestRestart(window());
482 void BrowserWindowCocoa::ShowBookmarkBubble(const GURL& url,
483                                             bool already_bookmarked) {
484   [controller_ showBookmarkBubbleForURL:url
485                       alreadyBookmarked:(already_bookmarked ? YES : NO)];
488 void BrowserWindowCocoa::ShowBookmarkAppBubble(
489     const WebApplicationInfo& web_app_info,
490     const std::string& extension_id) {
491   NOTIMPLEMENTED();
494 void BrowserWindowCocoa::ShowTranslateBubble(
495     content::WebContents* contents,
496     TranslateTabHelper::TranslateStep step,
497     TranslateErrors::Type error_type) {
498   TranslateTabHelper* translate_tab_helper =
499       TranslateTabHelper::FromWebContents(contents);
500   LanguageState& language_state = translate_tab_helper->GetLanguageState();
501   language_state.SetTranslateEnabled(true);
503   [controller_ showTranslateBubbleForWebContents:contents
504                                             step:step
505                                        errorType:error_type];
508 #if defined(ENABLE_ONE_CLICK_SIGNIN)
509 void BrowserWindowCocoa::ShowOneClickSigninBubble(
510     OneClickSigninBubbleType type,
511     const base::string16& email,
512     const base::string16& error_message,
513     const StartSyncCallback& start_sync_callback) {
514   WebContents* web_contents =
515         browser_->tab_strip_model()->GetActiveWebContents();
516   if (type == ONE_CLICK_SIGNIN_BUBBLE_TYPE_BUBBLE) {
517     base::scoped_nsobject<OneClickSigninBubbleController> bubble_controller([
518             [OneClickSigninBubbleController alloc]
519         initWithBrowserWindowController:cocoa_controller()
520                             webContents:web_contents
521                            errorMessage:base::SysUTF16ToNSString(error_message)
522                                callback:start_sync_callback]);
523     [bubble_controller showWindow:nil];
524   } else {
525     // Deletes itself when the dialog closes.
526     new OneClickSigninDialogController(
527         web_contents, start_sync_callback, email);
528   }
530 #endif
532 bool BrowserWindowCocoa::IsDownloadShelfVisible() const {
533   return [controller_ isDownloadShelfVisible] != NO;
536 DownloadShelf* BrowserWindowCocoa::GetDownloadShelf() {
537   DownloadShelfController* shelfController = [controller_ downloadShelf];
538   return [shelfController bridge];
541 // We allow closing the window here since the real quit decision on Mac is made
542 // in [AppController quit:].
543 void BrowserWindowCocoa::ConfirmBrowserCloseWithPendingDownloads(
544       int download_count,
545       Browser::DownloadClosePreventionType dialog_type,
546       bool app_modal,
547       const base::Callback<void(bool)>& callback) {
548   callback.Run(true);
551 void BrowserWindowCocoa::UserChangedTheme() {
552   [controller_ userChangedTheme];
555 int BrowserWindowCocoa::GetExtraRenderViewHeight() const {
556   // Currently this is only used on linux.
557   return 0;
560 void BrowserWindowCocoa::WebContentsFocused(WebContents* contents) {
561   NOTIMPLEMENTED();
564 void BrowserWindowCocoa::ShowWebsiteSettings(
565     Profile* profile,
566     content::WebContents* web_contents,
567     const GURL& url,
568     const content::SSLStatus& ssl) {
569   WebsiteSettingsUIBridge::Show(window(), profile, web_contents, url, ssl);
572 void BrowserWindowCocoa::ShowAppMenu() {
573   // No-op. Mac doesn't support showing the menus via alt keys.
576 bool BrowserWindowCocoa::PreHandleKeyboardEvent(
577     const NativeWebKeyboardEvent& event, bool* is_keyboard_shortcut) {
578   if (![BrowserWindowUtils shouldHandleKeyboardEvent:event])
579     return false;
581   if (event.type == blink::WebInputEvent::RawKeyDown &&
582       [controller_ handledByExtensionCommand:event.os_event])
583     return true;
585   int id = [BrowserWindowUtils getCommandId:event];
586   if (id == -1)
587     return false;
589   if (browser_->command_controller()->IsReservedCommandOrKey(id, event)) {
590       return [BrowserWindowUtils handleKeyboardEvent:event.os_event
591                                             inWindow:window()];
592   }
594   DCHECK(is_keyboard_shortcut);
595   *is_keyboard_shortcut = true;
596   return false;
599 void BrowserWindowCocoa::HandleKeyboardEvent(
600     const NativeWebKeyboardEvent& event) {
601   if ([BrowserWindowUtils shouldHandleKeyboardEvent:event])
602     [BrowserWindowUtils handleKeyboardEvent:event.os_event inWindow:window()];
605 void BrowserWindowCocoa::Cut() {
606   [NSApp sendAction:@selector(cut:) to:nil from:nil];
609 void BrowserWindowCocoa::Copy() {
610   [NSApp sendAction:@selector(copy:) to:nil from:nil];
613 void BrowserWindowCocoa::Paste() {
614   [NSApp sendAction:@selector(paste:) to:nil from:nil];
617 void BrowserWindowCocoa::EnterFullscreenWithChrome() {
618   // This method cannot be called if simplified fullscreen is enabled.
619   const CommandLine* command_line = CommandLine::ForCurrentProcess();
620   DCHECK(!command_line->HasSwitch(switches::kEnableSimplifiedFullscreen));
622   CHECK(chrome::mac::SupportsSystemFullscreen());
623   if ([controller_ inPresentationMode])
624     [controller_ exitPresentationMode];
625   else
626     [controller_ enterFullscreen];
629 bool BrowserWindowCocoa::IsFullscreenWithChrome() {
630   // The WithChrome mode does not exist when simplified fullscreen is enabled.
631   const CommandLine* command_line = CommandLine::ForCurrentProcess();
632   if (command_line->HasSwitch(switches::kEnableSimplifiedFullscreen))
633     return false;
634   return IsFullscreen() && ![controller_ inPresentationMode];
637 bool BrowserWindowCocoa::IsFullscreenWithoutChrome() {
638   // Presentation mode does not exist if simplified fullscreen is enabled.  The
639   // WithoutChrome mode simply maps to whether or not the window is fullscreen.
640   const CommandLine* command_line = CommandLine::ForCurrentProcess();
641   if (command_line->HasSwitch(switches::kEnableSimplifiedFullscreen))
642     return IsFullscreen();
644   return IsFullscreen() && [controller_ inPresentationMode];
647 WindowOpenDisposition BrowserWindowCocoa::GetDispositionForPopupBounds(
648     const gfx::Rect& bounds) {
649   // When using Cocoa's System Fullscreen mode, convert popups into tabs.
650   if ([controller_ isInSystemFullscreen])
651     return NEW_FOREGROUND_TAB;
652   return NEW_POPUP;
655 FindBar* BrowserWindowCocoa::CreateFindBar() {
656   // We could push the AddFindBar() call into the FindBarBridge
657   // constructor or the FindBarCocoaController init, but that makes
658   // unit testing difficult, since we would also require a
659   // BrowserWindow object.
660   FindBarBridge* bridge = new FindBarBridge(browser_);
661   AddFindBar(bridge->find_bar_cocoa_controller());
662   return bridge;
665 web_modal::WebContentsModalDialogHost*
666     BrowserWindowCocoa::GetWebContentsModalDialogHost() {
667   return NULL;
670 extensions::ActiveTabPermissionGranter*
671     BrowserWindowCocoa::GetActiveTabPermissionGranter() {
672   WebContents* web_contents =
673       browser_->tab_strip_model()->GetActiveWebContents();
674   if (!web_contents)
675     return NULL;
676   extensions::TabHelper* tab_helper =
677       extensions::TabHelper::FromWebContents(web_contents);
678   return tab_helper ? tab_helper->active_tab_permission_granter() : NULL;
681 void BrowserWindowCocoa::ModelChanged(const SearchModel::State& old_state,
682                                       const SearchModel::State& new_state) {
685 void BrowserWindowCocoa::DestroyBrowser() {
686   [controller_ destroyBrowser];
688   // at this point the controller is dead (autoreleased), so
689   // make sure we don't try to reference it any more.
692 NSWindow* BrowserWindowCocoa::window() const {
693   return [controller_ window];
696 void BrowserWindowCocoa::ShowAvatarBubble(WebContents* web_contents,
697                                           const gfx::Rect& rect) {
698   NSPoint point = GetPointForBubble(web_contents, rect.right(), rect.bottom());
700   // |menu| will automatically release itself on close.
701   AvatarMenuBubbleController* menu =
702       [[AvatarMenuBubbleController alloc] initWithBrowser:browser_
703                                                anchoredAt:point];
704   [[menu bubble] setAlignment:info_bubble::kAlignEdgeToAnchorEdge];
705   [menu showWindow:nil];
708 void BrowserWindowCocoa::ShowAvatarBubbleFromAvatarButton(
709     AvatarBubbleMode mode) {
710   AvatarBaseController* controller = [controller_ avatarButtonController];
711   [controller showAvatarBubble:[controller buttonView] withMode:mode];
714 void BrowserWindowCocoa::ShowPasswordGenerationBubble(
715     const gfx::Rect& rect,
716     const autofill::PasswordForm& form,
717     autofill::PasswordGenerator* password_generator) {
718   WebContents* web_contents =
719       browser_->tab_strip_model()->GetActiveWebContents();
720   // We want to point to the middle of the rect instead of the right side.
721   NSPoint point = GetPointForBubble(web_contents,
722                                     rect.x() + rect.width()/2,
723                                     rect.bottom());
725   PasswordGenerationBubbleController* controller = [
726           [PasswordGenerationBubbleController alloc]
727        initWithWindow:browser_->window()->GetNativeWindow()
728            anchoredAt:point
729        renderViewHost:web_contents->GetRenderViewHost()
730       passwordManager:ChromePasswordManagerClient::GetManagerFromWebContents(
731                           web_contents)
732        usingGenerator:password_generator
733               forForm:form];
734   [controller showWindow:nil];
738 BrowserWindowCocoa::GetRenderViewHeightInsetWithDetachedBookmarkBar() {
739   if (browser_->bookmark_bar_state() != BookmarkBar::DETACHED)
740     return 0;
741   return 40;
744 void BrowserWindowCocoa::ExecuteExtensionCommand(
745     const extensions::Extension* extension,
746     const extensions::Command& command) {
747   [cocoa_controller() executeExtensionCommand:extension->id() command:command];
750 void BrowserWindowCocoa::ShowPageActionPopup(
751     const extensions::Extension* extension) {
752   [cocoa_controller() activatePageAction:extension->id()];
755 void BrowserWindowCocoa::ShowBrowserActionPopup(
756     const extensions::Extension* extension) {
757   [cocoa_controller() activateBrowserAction:extension->id()];