blob: b15fb7ced4e2a3df4f57e544a28958f5ac1a486d [file] [log] [blame]
[email protected]3a80ea332012-01-09 19:53:291// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]7d791652010-12-01 16:34:492// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/ui/cocoa/browser_window_cocoa.h"
6
[email protected]a932d9e2011-09-29 01:14:347#include "base/bind.h"
[email protected]7d791652010-12-01 16:34:498#include "base/command_line.h"
9#include "base/logging.h"
[email protected]d82a3c9f2012-02-22 04:46:0010#include "base/mac/mac_util.h"
[email protected]7d791652010-12-01 16:34:4911#include "base/message_loop.h"
12#include "base/sys_string_conversions.h"
13#include "chrome/app/chrome_command_ids.h"
14#include "chrome/browser/bookmarks/bookmark_utils.h"
15#include "chrome/browser/download/download_shelf.h"
[email protected]78ce3022012-09-24 01:48:4816#include "chrome/browser/extensions/tab_helper.h"
[email protected]7d791652010-12-01 16:34:4917#include "chrome/browser/prefs/pref_service.h"
[email protected]8ecad5e2010-12-02 21:18:3318#include "chrome/browser/profiles/profile.h"
[email protected]7d791652010-12-01 16:34:4919#include "chrome/browser/ui/browser.h"
[email protected]5d98294912012-06-27 22:57:4020#include "chrome/browser/ui/browser_command_controller.h"
[email protected]3f32b9b2012-07-09 16:59:2821#include "chrome/browser/ui/browser_commands.h"
[email protected]7d791652010-12-01 16:34:4922#include "chrome/browser/ui/browser_list.h"
[email protected]52877dbc62012-06-29 22:22:0323#include "chrome/browser/ui/browser_tabstrip.h"
[email protected]1f0b50b2012-06-22 20:37:1624#include "chrome/browser/ui/browser_window_state.h"
[email protected]7d2d08152011-10-25 22:58:4725#import "chrome/browser/ui/cocoa/browser/avatar_button_controller.h"
[email protected]2f733a02011-10-06 15:17:3426#import "chrome/browser/ui/cocoa/browser/avatar_menu_bubble_controller.h"
[email protected]464f0012011-07-07 02:12:5127#import "chrome/browser/ui/cocoa/browser/edit_search_engine_cocoa_controller.h"
[email protected]7d791652010-12-01 16:34:4928#import "chrome/browser/ui/cocoa/browser_window_controller.h"
[email protected]3a1381d2011-08-26 18:12:1329#import "chrome/browser/ui/cocoa/browser_window_utils.h"
[email protected]7d791652010-12-01 16:34:4930#import "chrome/browser/ui/cocoa/chrome_event_processing_window.h"
[email protected]7d791652010-12-01 16:34:4931#import "chrome/browser/ui/cocoa/download/download_shelf_controller.h"
[email protected]632983f2011-08-08 22:51:2432#include "chrome/browser/ui/cocoa/find_bar/find_bar_bridge.h"
[email protected]51152d6d2011-11-07 01:55:1233#import "chrome/browser/ui/cocoa/info_bubble_view.h"
[email protected]7d791652010-12-01 16:34:4934#import "chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h"
[email protected]a7d83ca2011-03-06 14:41:0735#import "chrome/browser/ui/cocoa/nsmenuitem_additions.h"
[email protected]7d791652010-12-01 16:34:4936#include "chrome/browser/ui/cocoa/restart_browser.h"
37#include "chrome/browser/ui/cocoa/status_bubble_mac.h"
38#include "chrome/browser/ui/cocoa/task_manager_mac.h"
[email protected]8450c4f2011-01-19 22:16:2239#import "chrome/browser/ui/cocoa/toolbar/toolbar_controller.h"
[email protected]684dace42012-07-01 14:30:4140#import "chrome/browser/ui/cocoa/web_dialog_window_controller.h"
[email protected]5436c8fd2012-07-02 11:30:4641#import "chrome/browser/ui/cocoa/website_settings_bubble_controller.h"
[email protected]7e2514c2011-11-28 20:04:4542#include "chrome/browser/ui/page_info_bubble.h"
[email protected]55eed87f2012-06-11 16:47:3243#include "chrome/browser/ui/tab_contents/tab_contents.h"
[email protected]432115822011-07-10 15:52:2744#include "chrome/common/chrome_notification_types.h"
[email protected]7d791652010-12-01 16:34:4945#include "chrome/common/pref_names.h"
[email protected]8bc38d22011-10-14 20:39:2046#include "content/public/browser/native_web_keyboard_event.h"
[email protected]6c2381d2011-10-19 02:52:5347#include "content/public/browser/notification_details.h"
[email protected]684dace42012-07-01 14:30:4148#include "content/public/browser/notification_source.h"
[email protected]e8558cf22012-01-10 03:10:5149#include "content/public/browser/web_contents.h"
[email protected]7d791652010-12-01 16:34:4950#include "grit/chromium_strings.h"
51#include "grit/generated_resources.h"
[email protected]c051a1b2011-01-21 23:30:1752#include "ui/base/l10n/l10n_util_mac.h"
[email protected]08397d52011-02-05 01:53:3853#include "ui/gfx/rect.h"
[email protected]7d791652010-12-01 16:34:4954
[email protected]fe54b4a2012-03-28 16:11:0455#if defined(ENABLE_ONE_CLICK_SIGNIN)
56#import "chrome/browser/ui/cocoa/one_click_signin_bubble_controller.h"
57#endif
58
[email protected]b87ee522012-05-18 15:16:5459using content::NativeWebKeyboardEvent;
[email protected]d583e3f22011-12-27 21:38:1760using content::SSLStatus;
[email protected]2a6bc3e2011-12-28 23:51:3361using content::WebContents;
[email protected]d583e3f22011-12-27 21:38:1762
[email protected]400eaf82011-08-22 15:47:3963// Replicate specific 10.7 SDK declarations for building with prior SDKs.
64#if !defined(MAC_OS_X_VERSION_10_7) || \
65 MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7
66
67enum {
68 NSWindowAnimationBehaviorDefault = 0,
69 NSWindowAnimationBehaviorNone = 2,
70 NSWindowAnimationBehaviorDocumentWindow = 3,
71 NSWindowAnimationBehaviorUtilityWindow = 4,
72 NSWindowAnimationBehaviorAlertPanel = 5
73};
74typedef NSInteger NSWindowAnimationBehavior;
75
76@interface NSWindow (LionSDKDeclarations)
77- (NSWindowAnimationBehavior)animationBehavior;
78- (void)setAnimationBehavior:(NSWindowAnimationBehavior)newAnimationBehavior;
79@end
80
81#endif // MAC_OS_X_VERSION_10_7
82
[email protected]7d791652010-12-01 16:34:4983BrowserWindowCocoa::BrowserWindowCocoa(Browser* browser,
[email protected]400eaf82011-08-22 15:47:3984 BrowserWindowController* controller)
[email protected]7d791652010-12-01 16:34:4985 : browser_(browser),
86 controller_(controller),
[email protected]ad996342012-01-14 00:29:5987 confirm_close_factory_(browser),
[email protected]6a9b53a22012-10-09 02:43:3488 initial_show_state_(ui::SHOW_STATE_DEFAULT),
[email protected]ad996342012-01-14 00:29:5989 attention_request_id_(0) {
[email protected]cfecf9432011-09-27 17:10:0890
[email protected]3710d0002011-10-11 00:35:0091 pref_change_registrar_.Init(browser_->profile()->GetPrefs());
92 pref_change_registrar_.Add(prefs::kShowBookmarkBar, this);
[email protected]6a9b53a22012-10-09 02:43:3493 gfx::Rect bounds;
94 chrome::GetSavedWindowBoundsAndShowState(browser_,
95 &bounds,
96 &initial_show_state_);
[email protected]7d791652010-12-01 16:34:4997}
98
99BrowserWindowCocoa::~BrowserWindowCocoa() {
100}
101
102void BrowserWindowCocoa::Show() {
103 // The Browser associated with this browser window must become the active
104 // browser at the time |Show()| is called. This is the natural behaviour under
105 // Windows, but |-makeKeyAndOrderFront:| won't send |-windowDidBecomeMain:|
106 // until we return to the runloop. Therefore any calls to
107 // |BrowserList::GetLastActive()| (for example, in bookmark_util), will return
108 // the previous browser instead if we don't explicitly set it here.
109 BrowserList::SetLastActive(browser_);
110
[email protected]8bc061f2011-08-31 22:46:23111 bool is_session_restore = browser_->is_session_restore();
[email protected]b5cc93c2011-09-02 02:33:42112 NSWindowAnimationBehavior saved_animation_behavior =
113 NSWindowAnimationBehaviorDefault;
[email protected]8bc061f2011-08-31 22:46:23114 bool did_save_animation_behavior = false;
115 // Turn off swishing when restoring windows.
116 if (is_session_restore &&
117 [window() respondsToSelector:@selector(animationBehavior)] &&
118 [window() respondsToSelector:@selector(setAnimationBehavior:)]) {
119 did_save_animation_behavior = true;
120 saved_animation_behavior = [window() animationBehavior];
121 [window() setAnimationBehavior:NSWindowAnimationBehaviorNone];
122 }
[email protected]400eaf82011-08-22 15:47:39123
[email protected]8bc061f2011-08-31 22:46:23124 [window() makeKeyAndOrderFront:controller_];
[email protected]400eaf82011-08-22 15:47:39125
[email protected]8bc061f2011-08-31 22:46:23126 // When creating windows from nibs it is necessary to |makeKeyAndOrderFront:|
127 // prior to |orderOut:| then |miniaturize:| when restoring windows in the
128 // minimized state.
[email protected]cfecf9432011-09-27 17:10:08129 if (initial_show_state_ == ui::SHOW_STATE_MINIMIZED) {
[email protected]400eaf82011-08-22 15:47:39130 [window() orderOut:controller_];
131 [window() miniaturize:controller_];
[email protected]85b0ac62012-02-09 01:57:43132 } else if (initial_show_state_ == ui::SHOW_STATE_FULLSCREEN) {
[email protected]3f32b9b2012-07-09 16:59:28133 chrome::ToggleFullscreenMode(browser_);
[email protected]400eaf82011-08-22 15:47:39134 }
[email protected]cfecf9432011-09-27 17:10:08135 initial_show_state_ = ui::SHOW_STATE_DEFAULT;
[email protected]8bc061f2011-08-31 22:46:23136
137 // Restore window animation behavior.
138 if (did_save_animation_behavior)
139 [window() setAnimationBehavior:saved_animation_behavior];
[email protected]2f516c792011-09-19 22:22:09140
141 browser_->OnWindowDidShow();
[email protected]7d791652010-12-01 16:34:49142}
143
[email protected]d4db6c702011-03-28 21:49:14144void BrowserWindowCocoa::ShowInactive() {
[email protected]400eaf82011-08-22 15:47:39145 [window() orderFront:controller_];
[email protected]d4db6c702011-03-28 21:49:14146}
147
[email protected]7d412f72012-10-25 04:59:15148void BrowserWindowCocoa::Hide() {
149 // Not implemented.
150}
151
[email protected]7d791652010-12-01 16:34:49152void BrowserWindowCocoa::SetBounds(const gfx::Rect& bounds) {
[email protected]ccb5895f2011-06-09 21:16:14153 gfx::Rect real_bounds = [controller_ enforceMinWindowSize:bounds];
154
[email protected]55c87fa2011-10-15 07:28:28155 ExitFullscreen();
[email protected]ccb5895f2011-06-09 21:16:14156 NSRect cocoa_bounds = NSMakeRect(real_bounds.x(), 0,
157 real_bounds.width(),
158 real_bounds.height());
[email protected]7d791652010-12-01 16:34:49159 // Flip coordinates based on the primary screen.
160 NSScreen* screen = [[NSScreen screens] objectAtIndex:0];
161 cocoa_bounds.origin.y =
[email protected]03e0f5f1e2012-06-07 21:35:39162 NSHeight([screen frame]) - real_bounds.height() - real_bounds.y();
[email protected]7d791652010-12-01 16:34:49163
164 [window() setFrame:cocoa_bounds display:YES];
165}
166
167// Callers assume that this doesn't immediately delete the Browser object.
168// The controller implementing the window delegate methods called from
169// |-performClose:| must take precautions to ensure that.
170void BrowserWindowCocoa::Close() {
171 // If there is an overlay window, we contain a tab being dragged between
172 // windows. Don't hide the window as it makes the UI extra confused. We can
173 // still close the window, as that will happen when the drag completes.
[email protected]60f94292012-03-12 22:24:27174 if ([controller_ overlayWindow]) {
[email protected]7d791652010-12-01 16:34:49175 [controller_ deferPerformClose];
[email protected]60f94292012-03-12 22:24:27176 } else {
[email protected]5ea51972012-10-15 16:45:47177 // Using |-performClose:| can prevent the window from actually closing if
178 // a JavaScript beforeunload handler opens an alert during shutdown, as
179 // documented at <http://crbug.com/118424>. Re-implement
180 // -[NSWindow performClose:] as closely as possible to how Apple documents
181 // it.
[email protected]d1136ca2012-10-18 23:35:55182 //
183 // Before calling |-close|, hide the window immediately. |-performClose:|
184 // would do something similar, and this ensures that the window is removed
185 // from AppKit's display list. Not doing so can lead to crashes like
186 // <http://crbug.com/156101>.
[email protected]5ea51972012-10-15 16:45:47187 id<NSWindowDelegate> delegate = [window() delegate];
188 SEL window_should_close = @selector(windowShouldClose:);
189 if ([delegate respondsToSelector:window_should_close]) {
[email protected]d1136ca2012-10-18 23:35:55190 if ([delegate windowShouldClose:window()]) {
191 [window() orderOut:nil];
[email protected]5ea51972012-10-15 16:45:47192 [window() close];
[email protected]d1136ca2012-10-18 23:35:55193 }
[email protected]5ea51972012-10-15 16:45:47194 } else if ([window() respondsToSelector:window_should_close]) {
[email protected]d1136ca2012-10-18 23:35:55195 if ([window() performSelector:window_should_close withObject:window()]) {
196 [window() orderOut:nil];
[email protected]5ea51972012-10-15 16:45:47197 [window() close];
[email protected]d1136ca2012-10-18 23:35:55198 }
[email protected]5ea51972012-10-15 16:45:47199 } else {
[email protected]d1136ca2012-10-18 23:35:55200 [window() orderOut:nil];
[email protected]5ea51972012-10-15 16:45:47201 [window() close];
202 }
[email protected]60f94292012-03-12 22:24:27203 }
[email protected]7d791652010-12-01 16:34:49204}
205
206void BrowserWindowCocoa::Activate() {
207 [controller_ activate];
208}
209
210void BrowserWindowCocoa::Deactivate() {
211 // TODO(jcivelli): http://crbug.com/51364 Implement me.
212 NOTIMPLEMENTED();
213}
214
[email protected]ad996342012-01-14 00:29:59215void BrowserWindowCocoa::FlashFrame(bool flash) {
216 if (flash) {
217 attention_request_id_ = [NSApp requestUserAttention:NSInformationalRequest];
218 } else {
219 [NSApp cancelUserAttentionRequest:attention_request_id_];
220 attention_request_id_ = 0;
221 }
[email protected]7d791652010-12-01 16:34:49222}
223
[email protected]d101b0c2012-03-16 00:30:57224bool BrowserWindowCocoa::IsAlwaysOnTop() const {
225 return false;
226}
227
[email protected]7d791652010-12-01 16:34:49228bool BrowserWindowCocoa::IsActive() const {
229 return [window() isKeyWindow];
230}
231
[email protected]90556dd2012-06-07 20:26:18232gfx::NativeWindow BrowserWindowCocoa::GetNativeWindow() {
[email protected]7d791652010-12-01 16:34:49233 return window();
234}
235
236BrowserWindowTesting* BrowserWindowCocoa::GetBrowserWindowTesting() {
237 return NULL;
238}
239
240StatusBubble* BrowserWindowCocoa::GetStatusBubble() {
241 return [controller_ statusBubble];
242}
243
[email protected]7d791652010-12-01 16:34:49244void BrowserWindowCocoa::UpdateTitleBar() {
245 NSString* newTitle =
246 base::SysUTF16ToNSString(browser_->GetWindowTitleForCurrentTab());
247
[email protected]d78e615e2011-09-06 21:46:03248 pending_window_title_.reset(
249 [BrowserWindowUtils scheduleReplaceOldTitle:pending_window_title_.get()
250 withNewTitle:newTitle
251 forWindow:window()]);
[email protected]7d791652010-12-01 16:34:49252}
253
[email protected]09b29342011-06-24 19:18:48254void BrowserWindowCocoa::BookmarkBarStateChanged(
255 BookmarkBar::AnimateChangeType change_type) {
256 // TODO: route changes to state through this.
[email protected]7d791652010-12-01 16:34:49257}
258
259void BrowserWindowCocoa::UpdateDevTools() {
260 [controller_ updateDevToolsForContents:
[email protected]52877dbc62012-06-29 22:22:03261 chrome::GetActiveWebContents(browser_)];
[email protected]7d791652010-12-01 16:34:49262}
263
[email protected]7d791652010-12-01 16:34:49264void BrowserWindowCocoa::UpdateLoadingAnimations(bool should_animate) {
265 // Do nothing on Mac.
266}
267
268void BrowserWindowCocoa::SetStarredState(bool is_starred) {
269 [controller_ setStarredState:is_starred ? YES : NO];
270}
271
[email protected]5423c372012-08-22 05:50:16272void BrowserWindowCocoa::ZoomChangedForActiveTab(bool can_show_bubble) {
273 [controller_ zoomChangedForActiveTab:can_show_bubble ? YES : NO];
[email protected]6f80e932012-06-04 19:00:07274}
275
[email protected]7d791652010-12-01 16:34:49276gfx::Rect BrowserWindowCocoa::GetRestoredBounds() const {
277 // Flip coordinates based on the primary screen.
278 NSScreen* screen = [[NSScreen screens] objectAtIndex:0];
279 NSRect frame = [controller_ regularWindowFrame];
[email protected]03e0f5f1e2012-06-07 21:35:39280 gfx::Rect bounds(frame.origin.x, 0, NSWidth(frame), NSHeight(frame));
281 bounds.set_y(NSHeight([screen frame]) - NSMaxY(frame));
[email protected]7d791652010-12-01 16:34:49282 return bounds;
283}
284
[email protected]d479b8e22011-02-09 05:19:49285gfx::Rect BrowserWindowCocoa::GetBounds() const {
286 return GetRestoredBounds();
287}
288
[email protected]7d791652010-12-01 16:34:49289bool BrowserWindowCocoa::IsMaximized() const {
290 return [window() isZoomed];
291}
292
[email protected]400eaf82011-08-22 15:47:39293bool BrowserWindowCocoa::IsMinimized() const {
294 return [window() isMiniaturized];
295}
296
[email protected]541e3ee2011-11-22 01:31:10297void BrowserWindowCocoa::Maximize() {
298 // Zoom toggles so only call if not already maximized.
299 if (!IsMaximized())
300 [window() zoom:controller_];
301}
302
303void BrowserWindowCocoa::Minimize() {
304 [window() miniaturize:controller_];
305}
306
307void BrowserWindowCocoa::Restore() {
308 if (IsMaximized())
309 [window() zoom:controller_]; // Toggles zoom mode.
310 else if (IsMinimized())
311 [window() deminiaturize:controller_];
312}
313
[email protected]8d944b32011-10-17 06:11:53314void BrowserWindowCocoa::EnterFullscreen(
[email protected]22d74a6b2011-10-17 20:30:31315 const GURL& url, FullscreenExitBubbleType bubble_type) {
316 [controller_ enterFullscreenForURL:url
317 bubbleType:bubble_type];
[email protected]55c87fa2011-10-15 07:28:28318}
319
320void BrowserWindowCocoa::ExitFullscreen() {
[email protected]22d74a6b2011-10-17 20:30:31321 [controller_ exitFullscreen];
[email protected]8d944b32011-10-17 06:11:53322}
323
324void BrowserWindowCocoa::UpdateFullscreenExitBubbleContent(
325 const GURL& url,
326 FullscreenExitBubbleType bubble_type) {
[email protected]22d74a6b2011-10-17 20:30:31327 [controller_ updateFullscreenExitBubbleURL:url bubbleType:bubble_type];
[email protected]7d791652010-12-01 16:34:49328}
329
330bool BrowserWindowCocoa::IsFullscreen() const {
[email protected]8d944b32011-10-17 06:11:53331 return [controller_ isFullscreen];
[email protected]7d791652010-12-01 16:34:49332}
333
334bool BrowserWindowCocoa::IsFullscreenBubbleVisible() const {
335 return false;
336}
337
338void BrowserWindowCocoa::ConfirmAddSearchProvider(
[email protected]3613347d2012-04-27 20:27:37339 TemplateURL* template_url,
[email protected]7d791652010-12-01 16:34:49340 Profile* profile) {
[email protected]464f0012011-07-07 02:12:51341 // The controller will release itself when the window closes.
342 EditSearchEngineCocoaController* editor =
343 [[EditSearchEngineCocoaController alloc] initWithProfile:profile
344 delegate:NULL
345 templateURL:template_url];
346 [NSApp beginSheet:[editor window]
347 modalForWindow:window()
348 modalDelegate:controller_
349 didEndSelector:@selector(sheetDidEnd:returnCode:context:)
350 contextInfo:NULL];
[email protected]7d791652010-12-01 16:34:49351}
352
353LocationBar* BrowserWindowCocoa::GetLocationBar() const {
354 return [controller_ locationBarBridge];
355}
356
357void BrowserWindowCocoa::SetFocusToLocationBar(bool select_all) {
358 [controller_ focusLocationBar:select_all ? YES : NO];
359}
360
361void BrowserWindowCocoa::UpdateReloadStopState(bool is_loading, bool force) {
362 [controller_ setIsLoading:is_loading force:force];
363}
364
[email protected]55eed87f2012-06-11 16:47:32365void BrowserWindowCocoa::UpdateToolbar(TabContents* contents,
[email protected]7d791652010-12-01 16:34:49366 bool should_restore_state) {
[email protected]83a2610a2012-01-05 01:00:27367 [controller_ updateToolbarWithContents:contents->web_contents()
[email protected]7d791652010-12-01 16:34:49368 shouldRestoreState:should_restore_state ? YES : NO];
369}
370
371void BrowserWindowCocoa::FocusToolbar() {
372 // Not needed on the Mac.
373}
374
375void BrowserWindowCocoa::FocusAppMenu() {
376 // Chrome uses the standard Mac OS X menu bar, so this isn't needed.
377}
378
379void BrowserWindowCocoa::RotatePaneFocus(bool forwards) {
380 // Not needed on the Mac.
381}
382
383void BrowserWindowCocoa::FocusBookmarksToolbar() {
384 // Not needed on the Mac.
385}
386
[email protected]7d791652010-12-01 16:34:49387
388bool BrowserWindowCocoa::IsBookmarkBarVisible() const {
[email protected]a007e732011-08-05 13:32:19389 return browser_->profile()->GetPrefs()->GetBoolean(prefs::kShowBookmarkBar);
[email protected]7d791652010-12-01 16:34:49390}
391
392bool BrowserWindowCocoa::IsBookmarkBarAnimating() const {
393 return [controller_ isBookmarkBarAnimating];
394}
395
[email protected]95bf8a5b2010-12-22 16:04:07396bool BrowserWindowCocoa::IsTabStripEditable() const {
397 return ![controller_ isDragSessionActive];
398}
399
[email protected]7d791652010-12-01 16:34:49400bool BrowserWindowCocoa::IsToolbarVisible() const {
401 return browser_->SupportsWindowFeature(Browser::FEATURE_TOOLBAR) ||
402 browser_->SupportsWindowFeature(Browser::FEATURE_LOCATIONBAR);
403}
404
[email protected]b7a756d42012-01-23 18:08:17405gfx::Rect BrowserWindowCocoa::GetRootWindowResizerRect() const {
[email protected]9f8727092012-02-08 01:38:18406 if (IsDownloadShelfVisible())
407 return gfx::Rect();
[email protected]b7a756d42012-01-23 18:08:17408 NSRect tabRect = [controller_ selectedTabGrowBoxRect];
409 return gfx::Rect(NSRectToCGRect(tabRect));
410}
411
[email protected]5f58c2af2012-01-11 17:55:29412bool BrowserWindowCocoa::IsPanel() const {
413 return false;
414}
415
[email protected]7d791652010-12-01 16:34:49416// This is called from Browser, which in turn is called directly from
417// a menu option. All we do here is set a preference. The act of
418// setting the preference sends notifications to all windows who then
419// know what to do.
420void BrowserWindowCocoa::ToggleBookmarkBar() {
421 bookmark_utils::ToggleWhenVisible(browser_->profile());
422}
423
424void BrowserWindowCocoa::AddFindBar(
425 FindBarCocoaController* find_bar_cocoa_controller) {
[email protected]632983f2011-08-08 22:51:24426 [controller_ addFindBar:find_bar_cocoa_controller];
[email protected]7d791652010-12-01 16:34:49427}
428
[email protected]7d791652010-12-01 16:34:49429void BrowserWindowCocoa::ShowUpdateChromeDialog() {
[email protected]678dae82011-02-11 20:03:08430 restart_browser::RequestRestart(window());
[email protected]7d791652010-12-01 16:34:49431}
432
433void BrowserWindowCocoa::ShowTaskManager() {
[email protected]898febec2012-05-31 18:15:48434 TaskManagerMac::Show(false);
[email protected]adb6a84d2011-02-07 16:58:40435}
436
437void BrowserWindowCocoa::ShowBackgroundPages() {
[email protected]898febec2012-05-31 18:15:48438 TaskManagerMac::Show(true);
[email protected]7d791652010-12-01 16:34:49439}
440
441void BrowserWindowCocoa::ShowBookmarkBubble(const GURL& url,
442 bool already_bookmarked) {
443 [controller_ showBookmarkBubbleForURL:url
444 alreadyBookmarked:(already_bookmarked ? YES : NO)];
445}
446
[email protected]b106ca52012-03-13 06:08:46447void BrowserWindowCocoa::ShowChromeToMobileBubble() {
[email protected]24bbcdd2012-03-27 03:14:17448 [controller_ showChromeToMobileBubble];
[email protected]b106ca52012-03-13 06:08:46449}
450
[email protected]235a0562012-03-26 22:22:35451#if defined(ENABLE_ONE_CLICK_SIGNIN)
[email protected]fe54b4a2012-03-28 16:11:04452void BrowserWindowCocoa::ShowOneClickSigninBubble(
[email protected]e4b66bf2012-05-29 20:39:51453 const StartSyncCallback& start_sync_callback) {
[email protected]fe54b4a2012-03-28 16:11:04454 OneClickSigninBubbleController* bubble_controller =
455 [[OneClickSigninBubbleController alloc]
456 initWithBrowserWindowController:cocoa_controller()
[email protected]e4b66bf2012-05-29 20:39:51457 start_sync_callback:start_sync_callback];
[email protected]fe54b4a2012-03-28 16:11:04458 [bubble_controller showWindow:nil];
[email protected]235a0562012-03-26 22:22:35459}
460#endif
461
[email protected]7d791652010-12-01 16:34:49462bool BrowserWindowCocoa::IsDownloadShelfVisible() const {
463 return [controller_ isDownloadShelfVisible] != NO;
464}
465
466DownloadShelf* BrowserWindowCocoa::GetDownloadShelf() {
467 DownloadShelfController* shelfController = [controller_ downloadShelf];
468 return [shelfController bridge];
469}
470
[email protected]7d791652010-12-01 16:34:49471// We allow closing the window here since the real quit decision on Mac is made
472// in [AppController quit:].
473void BrowserWindowCocoa::ConfirmBrowserCloseWithPendingDownloads() {
474 // Call InProgressDownloadResponse asynchronously to avoid a crash when the
475 // browser window is closed here (http://crbug.com/44454).
[email protected]a932d9e2011-09-29 01:14:34476 MessageLoop::current()->PostTask(FROM_HERE,
477 base::Bind(&Browser::InProgressDownloadResponse,
478 confirm_close_factory_.GetWeakPtr(), true));
[email protected]7d791652010-12-01 16:34:49479}
480
[email protected]7d791652010-12-01 16:34:49481void BrowserWindowCocoa::UserChangedTheme() {
482 [controller_ userChangedTheme];
483}
484
485int BrowserWindowCocoa::GetExtraRenderViewHeight() const {
486 // Currently this is only used on linux.
487 return 0;
488}
489
[email protected]2a6bc3e2011-12-28 23:51:33490void BrowserWindowCocoa::WebContentsFocused(WebContents* contents) {
[email protected]7d791652010-12-01 16:34:49491 NOTIMPLEMENTED();
492}
493
[email protected]4eb4ec02012-06-19 15:54:21494void BrowserWindowCocoa::ShowPageInfo(WebContents* web_contents,
[email protected]7d791652010-12-01 16:34:49495 const GURL& url,
[email protected]d583e3f22011-12-27 21:38:17496 const SSLStatus& ssl,
[email protected]7d791652010-12-01 16:34:49497 bool show_history) {
[email protected]684dace42012-07-01 14:30:41498 chrome::ShowPageInfoBubble(window(), web_contents, url, ssl, show_history,
499 browser_);
[email protected]7d791652010-12-01 16:34:49500}
501
[email protected]b8e681e82012-02-20 10:18:47502void BrowserWindowCocoa::ShowWebsiteSettings(
503 Profile* profile,
[email protected]55eed87f2012-06-11 16:47:32504 TabContents* tab_contents,
[email protected]b8e681e82012-02-20 10:18:47505 const GURL& url,
506 const content::SSLStatus& ssl,
507 bool show_history) {
[email protected]5436c8fd2012-07-02 11:30:46508 WebsiteSettingsUIBridge::Show(
509 window(), profile, tab_contents, url, ssl);
[email protected]b8e681e82012-02-20 10:18:47510}
511
[email protected]7d791652010-12-01 16:34:49512void BrowserWindowCocoa::ShowAppMenu() {
513 // No-op. Mac doesn't support showing the menus via alt keys.
514}
515
516bool BrowserWindowCocoa::PreHandleKeyboardEvent(
517 const NativeWebKeyboardEvent& event, bool* is_keyboard_shortcut) {
[email protected]3a1381d2011-08-26 18:12:13518 if (![BrowserWindowUtils shouldHandleKeyboardEvent:event])
[email protected]7d791652010-12-01 16:34:49519 return false;
520
[email protected]d2885ba2012-08-17 10:23:12521 if (event.type == WebKit::WebInputEvent::RawKeyDown &&
522 [controller_ handledByExtensionCommand:event.os_event])
523 return true;
524
[email protected]3a1381d2011-08-26 18:12:13525 int id = [BrowserWindowUtils getCommandId:event];
[email protected]7d791652010-12-01 16:34:49526 if (id == -1)
527 return false;
528
[email protected]5d98294912012-06-27 22:57:40529 if (browser_->command_controller()->IsReservedCommandOrKey(id, event)) {
[email protected]3a1381d2011-08-26 18:12:13530 return [BrowserWindowUtils handleKeyboardEvent:event.os_event
531 inWindow:window()];
532 }
[email protected]7d791652010-12-01 16:34:49533
[email protected]3a1381d2011-08-26 18:12:13534 DCHECK(is_keyboard_shortcut);
[email protected]7d791652010-12-01 16:34:49535 *is_keyboard_shortcut = true;
[email protected]7d791652010-12-01 16:34:49536 return false;
537}
538
539void BrowserWindowCocoa::HandleKeyboardEvent(
540 const NativeWebKeyboardEvent& event) {
[email protected]3a1381d2011-08-26 18:12:13541 if ([BrowserWindowUtils shouldHandleKeyboardEvent:event])
542 [BrowserWindowUtils handleKeyboardEvent:event.os_event inWindow:window()];
[email protected]7d791652010-12-01 16:34:49543}
544
[email protected]7d791652010-12-01 16:34:49545void BrowserWindowCocoa::ShowCreateChromeAppShortcutsDialog(
[email protected]1c321ee2012-05-21 03:02:34546 Profile* profile, const extensions::Extension* app) {
[email protected]7d791652010-12-01 16:34:49547 NOTIMPLEMENTED();
548}
549
550void BrowserWindowCocoa::Cut() {
551 [NSApp sendAction:@selector(cut:) to:nil from:nil];
552}
553
554void BrowserWindowCocoa::Copy() {
555 [NSApp sendAction:@selector(copy:) to:nil from:nil];
556}
557
558void BrowserWindowCocoa::Paste() {
559 [NSApp sendAction:@selector(paste:) to:nil from:nil];
560}
561
[email protected]7d791652010-12-01 16:34:49562void BrowserWindowCocoa::OpenTabpose() {
563 [controller_ openTabpose];
564}
565
[email protected]8d944b32011-10-17 06:11:53566void BrowserWindowCocoa::EnterPresentationMode(
567 const GURL& url,
568 FullscreenExitBubbleType bubble_type) {
[email protected]22d74a6b2011-10-17 20:30:31569 [controller_ enterPresentationModeForURL:url
570 bubbleType:bubble_type];
[email protected]8d944b32011-10-17 06:11:53571}
572
573void BrowserWindowCocoa::ExitPresentationMode() {
[email protected]22d74a6b2011-10-17 20:30:31574 [controller_ exitPresentationMode];
[email protected]d3766932011-08-04 22:18:23575}
576
577bool BrowserWindowCocoa::InPresentationMode() {
578 return [controller_ inPresentationMode];
579}
580
[email protected]7d791652010-12-01 16:34:49581gfx::Rect BrowserWindowCocoa::GetInstantBounds() {
582 // Flip coordinates based on the primary screen.
583 NSScreen* screen = [[NSScreen screens] objectAtIndex:0];
584 NSRect monitorFrame = [screen frame];
585 NSRect frame = [controller_ instantFrame];
586 gfx::Rect bounds(NSRectToCGRect(frame));
587 bounds.set_y(NSHeight(monitorFrame) - bounds.y() - bounds.height());
588 return bounds;
589}
590
[email protected]85fd03e2012-09-04 22:50:14591bool BrowserWindowCocoa::IsInstantTabShowing() {
592 return [controller_ isInstantTabShowing];
593}
594
[email protected]588300d2011-04-28 21:06:35595WindowOpenDisposition BrowserWindowCocoa::GetDispositionForPopupBounds(
596 const gfx::Rect& bounds) {
[email protected]d82a3c9f2012-02-22 04:46:00597 // In Lion fullscreen mode, convert popups into tabs.
598 if (base::mac::IsOSLionOrLater() && IsFullscreen())
599 return NEW_FOREGROUND_TAB;
[email protected]588300d2011-04-28 21:06:35600 return NEW_POPUP;
601}
602
[email protected]632983f2011-08-08 22:51:24603FindBar* BrowserWindowCocoa::CreateFindBar() {
604 // We could push the AddFindBar() call into the FindBarBridge
605 // constructor or the FindBarCocoaController init, but that makes
606 // unit testing difficult, since we would also require a
607 // BrowserWindow object.
608 FindBarBridge* bridge = new FindBarBridge();
609 AddFindBar(bridge->find_bar_cocoa_controller());
610 return bridge;
611}
612
[email protected]d3afce92012-10-07 05:47:36613bool BrowserWindowCocoa::GetConstrainedWindowTopY(int* top_y) {
614 return false;
[email protected]6a151762012-10-03 22:33:19615}
616
[email protected]432115822011-07-10 15:52:27617void BrowserWindowCocoa::Observe(int type,
[email protected]6c2381d2011-10-19 02:52:53618 const content::NotificationSource& source,
619 const content::NotificationDetails& details) {
[email protected]432115822011-07-10 15:52:27620 switch (type) {
[email protected]3710d0002011-10-11 00:35:00621 case chrome::NOTIFICATION_PREF_CHANGED: {
[email protected]7ac4b872011-10-19 03:30:42622 const std::string& pref_name =
623 *content::Details<std::string>(details).ptr();
[email protected]3710d0002011-10-11 00:35:00624 DCHECK(pref_name == prefs::kShowBookmarkBar);
625 [controller_ updateBookmarkBarVisibilityWithAnimation:YES];
[email protected]7d791652010-12-01 16:34:49626 break;
[email protected]3710d0002011-10-11 00:35:00627 }
[email protected]7d791652010-12-01 16:34:49628 default:
629 NOTREACHED(); // we don't ask for anything else!
630 break;
631 }
632}
633
[email protected]78ce3022012-09-24 01:48:48634extensions::ActiveTabPermissionGranter*
635 BrowserWindowCocoa::GetActiveTabPermissionGranter() {
636 TabContents* tab_contents =
637 browser_->tab_strip_model()->GetActiveTabContents();
638 if (!tab_contents)
639 return NULL;
640 extensions::TabHelper* tab_helper =
641 extensions::TabHelper::FromWebContents(tab_contents->web_contents());
642 return tab_helper ? tab_helper->active_tab_permission_granter() : NULL;
643}
644
[email protected]7d791652010-12-01 16:34:49645void BrowserWindowCocoa::DestroyBrowser() {
646 [controller_ destroyBrowser];
647
648 // at this point the controller is dead (autoreleased), so
649 // make sure we don't try to reference it any more.
650}
651
652NSWindow* BrowserWindowCocoa::window() const {
653 return [controller_ window];
654}
655
[email protected]0ec4898e2011-12-30 21:09:24656void BrowserWindowCocoa::ShowAvatarBubble(WebContents* web_contents,
[email protected]2f733a02011-10-06 15:17:34657 const gfx::Rect& rect) {
[email protected]0ec4898e2011-12-30 21:09:24658 NSView* view = web_contents->GetNativeView();
[email protected]79ac3cb2011-10-12 17:11:21659 NSRect bounds = [view bounds];
660 NSPoint point;
661 point.x = NSMinX(bounds) + rect.right();
662 // The view's origin is at the bottom but |rect|'s origin is at the top.
663 point.y = NSMaxY(bounds) - rect.bottom();
[email protected]2f733a02011-10-06 15:17:34664 point = [view convertPoint:point toView:nil];
665 point = [[view window] convertBaseToScreen:point];
666
667 // |menu| will automatically release itself on close.
668 AvatarMenuBubbleController* menu =
669 [[AvatarMenuBubbleController alloc] initWithBrowser:browser_
670 anchoredAt:point];
[email protected]51152d6d2011-11-07 01:55:12671 [[menu bubble] setAlignment:info_bubble::kAlignEdgeToAnchorEdge];
[email protected]2f733a02011-10-06 15:17:34672 [menu showWindow:nil];
673}
[email protected]7d2d08152011-10-25 22:58:47674
675void BrowserWindowCocoa::ShowAvatarBubbleFromAvatarButton() {
676 [[controller_ avatarButtonController] showAvatarBubble];
677}