blob: f2da8b5f27cac65618d77c41bfdff99caf09dbb4 [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"
[email protected]7d791652010-12-01 16:34:4914#include "chrome/browser/download/download_shelf.h"
[email protected]78ce3022012-09-24 01:48:4815#include "chrome/browser/extensions/tab_helper.h"
[email protected]f5d230b32012-12-11 02:04:1116#include "chrome/browser/password_manager/password_manager.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]25ebfd362013-01-16 05:41:5519#include "chrome/browser/shell_integration.h"
[email protected]03020ff2012-11-29 12:08:1720#include "chrome/browser/ui/bookmarks/bookmark_utils.h"
[email protected]7d791652010-12-01 16:34:4921#include "chrome/browser/ui/browser.h"
[email protected]5d98294912012-06-27 22:57:4022#include "chrome/browser/ui/browser_command_controller.h"
[email protected]3f32b9b2012-07-09 16:59:2823#include "chrome/browser/ui/browser_commands.h"
[email protected]7d791652010-12-01 16:34:4924#include "chrome/browser/ui/browser_list.h"
[email protected]1f0b50b2012-06-22 20:37:1625#include "chrome/browser/ui/browser_window_state.h"
[email protected]7d2d08152011-10-25 22:58:4726#import "chrome/browser/ui/cocoa/browser/avatar_button_controller.h"
[email protected]2f733a02011-10-06 15:17:3427#import "chrome/browser/ui/cocoa/browser/avatar_menu_bubble_controller.h"
[email protected]464f0012011-07-07 02:12:5128#import "chrome/browser/ui/cocoa/browser/edit_search_engine_cocoa_controller.h"
[email protected]f5d230b32012-12-11 02:04:1129#import "chrome/browser/ui/cocoa/browser/password_generation_bubble_controller.h"
[email protected]7d791652010-12-01 16:34:4930#import "chrome/browser/ui/cocoa/browser_window_controller.h"
[email protected]3a1381d2011-08-26 18:12:1331#import "chrome/browser/ui/cocoa/browser_window_utils.h"
[email protected]7d791652010-12-01 16:34:4932#import "chrome/browser/ui/cocoa/chrome_event_processing_window.h"
[email protected]7d791652010-12-01 16:34:4933#import "chrome/browser/ui/cocoa/download/download_shelf_controller.h"
[email protected]632983f2011-08-08 22:51:2434#include "chrome/browser/ui/cocoa/find_bar/find_bar_bridge.h"
[email protected]51152d6d2011-11-07 01:55:1235#import "chrome/browser/ui/cocoa/info_bubble_view.h"
[email protected]7d791652010-12-01 16:34:4936#import "chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h"
[email protected]a7d83ca2011-03-06 14:41:0737#import "chrome/browser/ui/cocoa/nsmenuitem_additions.h"
[email protected]7d791652010-12-01 16:34:4938#include "chrome/browser/ui/cocoa/restart_browser.h"
39#include "chrome/browser/ui/cocoa/status_bubble_mac.h"
40#include "chrome/browser/ui/cocoa/task_manager_mac.h"
[email protected]8450c4f2011-01-19 22:16:2241#import "chrome/browser/ui/cocoa/toolbar/toolbar_controller.h"
[email protected]684dace42012-07-01 14:30:4142#import "chrome/browser/ui/cocoa/web_dialog_window_controller.h"
[email protected]5436c8fd2012-07-02 11:30:4643#import "chrome/browser/ui/cocoa/website_settings_bubble_controller.h"
[email protected]e2395da2013-01-23 22:05:3544#include "chrome/browser/ui/search/search_model.h"
[email protected]617ee962013-01-29 20:49:1245#include "chrome/browser/ui/tabs/tab_strip_model.h"
[email protected]25ebfd362013-01-16 05:41:5546#include "chrome/browser/ui/web_applications/web_app_ui.h"
47#include "chrome/browser/web_applications/web_app.h"
[email protected]432115822011-07-10 15:52:2748#include "chrome/common/chrome_notification_types.h"
[email protected]7d791652010-12-01 16:34:4949#include "chrome/common/pref_names.h"
[email protected]8bc38d22011-10-14 20:39:2050#include "content/public/browser/native_web_keyboard_event.h"
[email protected]6c2381d2011-10-19 02:52:5351#include "content/public/browser/notification_details.h"
[email protected]684dace42012-07-01 14:30:4152#include "content/public/browser/notification_source.h"
[email protected]e8558cf22012-01-10 03:10:5153#include "content/public/browser/web_contents.h"
[email protected]f5d230b32012-12-11 02:04:1154#include "content/public/common/password_form.h"
[email protected]7d791652010-12-01 16:34:4955#include "grit/chromium_strings.h"
56#include "grit/generated_resources.h"
[email protected]c051a1b2011-01-21 23:30:1757#include "ui/base/l10n/l10n_util_mac.h"
[email protected]08397d52011-02-05 01:53:3858#include "ui/gfx/rect.h"
[email protected]7d791652010-12-01 16:34:4959
[email protected]fe54b4a2012-03-28 16:11:0460#if defined(ENABLE_ONE_CLICK_SIGNIN)
61#import "chrome/browser/ui/cocoa/one_click_signin_bubble_controller.h"
[email protected]8aa690c2013-02-06 22:33:1262#import "chrome/browser/ui/cocoa/one_click_signin_dialog_controller.h"
[email protected]fe54b4a2012-03-28 16:11:0463#endif
64
[email protected]b87ee522012-05-18 15:16:5465using content::NativeWebKeyboardEvent;
[email protected]d583e3f22011-12-27 21:38:1766using content::SSLStatus;
[email protected]2a6bc3e2011-12-28 23:51:3367using content::WebContents;
[email protected]d583e3f22011-12-27 21:38:1768
[email protected]400eaf82011-08-22 15:47:3969// Replicate specific 10.7 SDK declarations for building with prior SDKs.
70#if !defined(MAC_OS_X_VERSION_10_7) || \
71 MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7
72
73enum {
74 NSWindowAnimationBehaviorDefault = 0,
75 NSWindowAnimationBehaviorNone = 2,
76 NSWindowAnimationBehaviorDocumentWindow = 3,
77 NSWindowAnimationBehaviorUtilityWindow = 4,
78 NSWindowAnimationBehaviorAlertPanel = 5
79};
80typedef NSInteger NSWindowAnimationBehavior;
81
82@interface NSWindow (LionSDKDeclarations)
83- (NSWindowAnimationBehavior)animationBehavior;
84- (void)setAnimationBehavior:(NSWindowAnimationBehavior)newAnimationBehavior;
85@end
86
87#endif // MAC_OS_X_VERSION_10_7
88
[email protected]f5d230b32012-12-11 02:04:1189namespace {
90
91NSPoint GetPointForBubble(content::WebContents* web_contents,
92 int x_offset,
93 int y_offset) {
94 NSView* view = web_contents->GetNativeView();
95 NSRect bounds = [view bounds];
96 NSPoint point;
97 point.x = NSMinX(bounds) + x_offset;
98 // The view's origin is at the bottom but |rect|'s origin is at the top.
99 point.y = NSMaxY(bounds) - y_offset;
100 point = [view convertPoint:point toView:nil];
101 point = [[view window] convertBaseToScreen:point];
102 return point;
103}
104
105} // namespace
106
[email protected]7d791652010-12-01 16:34:49107BrowserWindowCocoa::BrowserWindowCocoa(Browser* browser,
[email protected]400eaf82011-08-22 15:47:39108 BrowserWindowController* controller)
[email protected]7d791652010-12-01 16:34:49109 : browser_(browser),
110 controller_(controller),
[email protected]ad996342012-01-14 00:29:59111 confirm_close_factory_(browser),
[email protected]6a9b53a22012-10-09 02:43:34112 initial_show_state_(ui::SHOW_STATE_DEFAULT),
[email protected]ad996342012-01-14 00:29:59113 attention_request_id_(0) {
[email protected]cfecf9432011-09-27 17:10:08114
[email protected]6a9b53a22012-10-09 02:43:34115 gfx::Rect bounds;
116 chrome::GetSavedWindowBoundsAndShowState(browser_,
117 &bounds,
118 &initial_show_state_);
[email protected]e2395da2013-01-23 22:05:35119
120 browser_->search_model()->AddObserver(this);
[email protected]7d791652010-12-01 16:34:49121}
122
123BrowserWindowCocoa::~BrowserWindowCocoa() {
[email protected]e2395da2013-01-23 22:05:35124 browser_->search_model()->RemoveObserver(this);
[email protected]7d791652010-12-01 16:34:49125}
126
127void BrowserWindowCocoa::Show() {
128 // The Browser associated with this browser window must become the active
129 // browser at the time |Show()| is called. This is the natural behaviour under
130 // Windows, but |-makeKeyAndOrderFront:| won't send |-windowDidBecomeMain:|
131 // until we return to the runloop. Therefore any calls to
[email protected]4d900252012-11-20 20:37:11132 // |chrome::FindLastActiveWithHostDesktopType| will return the previous
133 // browser instead if we don't explicitly set it here.
[email protected]7d791652010-12-01 16:34:49134 BrowserList::SetLastActive(browser_);
135
[email protected]8bc061f2011-08-31 22:46:23136 bool is_session_restore = browser_->is_session_restore();
[email protected]b5cc93c2011-09-02 02:33:42137 NSWindowAnimationBehavior saved_animation_behavior =
138 NSWindowAnimationBehaviorDefault;
[email protected]8bc061f2011-08-31 22:46:23139 bool did_save_animation_behavior = false;
140 // Turn off swishing when restoring windows.
141 if (is_session_restore &&
142 [window() respondsToSelector:@selector(animationBehavior)] &&
143 [window() respondsToSelector:@selector(setAnimationBehavior:)]) {
144 did_save_animation_behavior = true;
145 saved_animation_behavior = [window() animationBehavior];
146 [window() setAnimationBehavior:NSWindowAnimationBehaviorNone];
147 }
[email protected]400eaf82011-08-22 15:47:39148
[email protected]8bc061f2011-08-31 22:46:23149 [window() makeKeyAndOrderFront:controller_];
[email protected]400eaf82011-08-22 15:47:39150
[email protected]8bc061f2011-08-31 22:46:23151 // When creating windows from nibs it is necessary to |makeKeyAndOrderFront:|
152 // prior to |orderOut:| then |miniaturize:| when restoring windows in the
153 // minimized state.
[email protected]cfecf9432011-09-27 17:10:08154 if (initial_show_state_ == ui::SHOW_STATE_MINIMIZED) {
[email protected]400eaf82011-08-22 15:47:39155 [window() orderOut:controller_];
156 [window() miniaturize:controller_];
[email protected]85b0ac62012-02-09 01:57:43157 } else if (initial_show_state_ == ui::SHOW_STATE_FULLSCREEN) {
[email protected]3f32b9b2012-07-09 16:59:28158 chrome::ToggleFullscreenMode(browser_);
[email protected]400eaf82011-08-22 15:47:39159 }
[email protected]cfecf9432011-09-27 17:10:08160 initial_show_state_ = ui::SHOW_STATE_DEFAULT;
[email protected]8bc061f2011-08-31 22:46:23161
162 // Restore window animation behavior.
163 if (did_save_animation_behavior)
164 [window() setAnimationBehavior:saved_animation_behavior];
[email protected]2f516c792011-09-19 22:22:09165
166 browser_->OnWindowDidShow();
[email protected]7d791652010-12-01 16:34:49167}
168
[email protected]d4db6c702011-03-28 21:49:14169void BrowserWindowCocoa::ShowInactive() {
[email protected]400eaf82011-08-22 15:47:39170 [window() orderFront:controller_];
[email protected]d4db6c702011-03-28 21:49:14171}
172
[email protected]7d412f72012-10-25 04:59:15173void BrowserWindowCocoa::Hide() {
174 // Not implemented.
175}
176
[email protected]7d791652010-12-01 16:34:49177void BrowserWindowCocoa::SetBounds(const gfx::Rect& bounds) {
[email protected]ccb5895f2011-06-09 21:16:14178 gfx::Rect real_bounds = [controller_ enforceMinWindowSize:bounds];
179
[email protected]55c87fa2011-10-15 07:28:28180 ExitFullscreen();
[email protected]ccb5895f2011-06-09 21:16:14181 NSRect cocoa_bounds = NSMakeRect(real_bounds.x(), 0,
182 real_bounds.width(),
183 real_bounds.height());
[email protected]7d791652010-12-01 16:34:49184 // Flip coordinates based on the primary screen.
185 NSScreen* screen = [[NSScreen screens] objectAtIndex:0];
186 cocoa_bounds.origin.y =
[email protected]03e0f5f1e2012-06-07 21:35:39187 NSHeight([screen frame]) - real_bounds.height() - real_bounds.y();
[email protected]7d791652010-12-01 16:34:49188
189 [window() setFrame:cocoa_bounds display:YES];
190}
191
192// Callers assume that this doesn't immediately delete the Browser object.
193// The controller implementing the window delegate methods called from
194// |-performClose:| must take precautions to ensure that.
195void BrowserWindowCocoa::Close() {
196 // If there is an overlay window, we contain a tab being dragged between
197 // windows. Don't hide the window as it makes the UI extra confused. We can
198 // still close the window, as that will happen when the drag completes.
[email protected]60f94292012-03-12 22:24:27199 if ([controller_ overlayWindow]) {
[email protected]7d791652010-12-01 16:34:49200 [controller_ deferPerformClose];
[email protected]60f94292012-03-12 22:24:27201 } else {
[email protected]5ea51972012-10-15 16:45:47202 // Using |-performClose:| can prevent the window from actually closing if
203 // a JavaScript beforeunload handler opens an alert during shutdown, as
204 // documented at <http://crbug.com/118424>. Re-implement
205 // -[NSWindow performClose:] as closely as possible to how Apple documents
206 // it.
[email protected]d1136ca2012-10-18 23:35:55207 //
208 // Before calling |-close|, hide the window immediately. |-performClose:|
209 // would do something similar, and this ensures that the window is removed
210 // from AppKit's display list. Not doing so can lead to crashes like
211 // <http://crbug.com/156101>.
[email protected]5ea51972012-10-15 16:45:47212 id<NSWindowDelegate> delegate = [window() delegate];
213 SEL window_should_close = @selector(windowShouldClose:);
214 if ([delegate respondsToSelector:window_should_close]) {
[email protected]d1136ca2012-10-18 23:35:55215 if ([delegate windowShouldClose:window()]) {
216 [window() orderOut:nil];
[email protected]5ea51972012-10-15 16:45:47217 [window() close];
[email protected]d1136ca2012-10-18 23:35:55218 }
[email protected]5ea51972012-10-15 16:45:47219 } else if ([window() respondsToSelector:window_should_close]) {
[email protected]d1136ca2012-10-18 23:35:55220 if ([window() performSelector:window_should_close withObject:window()]) {
221 [window() orderOut:nil];
[email protected]5ea51972012-10-15 16:45:47222 [window() close];
[email protected]d1136ca2012-10-18 23:35:55223 }
[email protected]5ea51972012-10-15 16:45:47224 } else {
[email protected]d1136ca2012-10-18 23:35:55225 [window() orderOut:nil];
[email protected]5ea51972012-10-15 16:45:47226 [window() close];
227 }
[email protected]60f94292012-03-12 22:24:27228 }
[email protected]7d791652010-12-01 16:34:49229}
230
231void BrowserWindowCocoa::Activate() {
232 [controller_ activate];
233}
234
235void BrowserWindowCocoa::Deactivate() {
236 // TODO(jcivelli): http://crbug.com/51364 Implement me.
237 NOTIMPLEMENTED();
238}
239
[email protected]ad996342012-01-14 00:29:59240void BrowserWindowCocoa::FlashFrame(bool flash) {
241 if (flash) {
242 attention_request_id_ = [NSApp requestUserAttention:NSInformationalRequest];
243 } else {
244 [NSApp cancelUserAttentionRequest:attention_request_id_];
245 attention_request_id_ = 0;
246 }
[email protected]7d791652010-12-01 16:34:49247}
248
[email protected]d101b0c2012-03-16 00:30:57249bool BrowserWindowCocoa::IsAlwaysOnTop() const {
250 return false;
251}
252
[email protected]7d791652010-12-01 16:34:49253bool BrowserWindowCocoa::IsActive() const {
254 return [window() isKeyWindow];
255}
256
[email protected]90556dd2012-06-07 20:26:18257gfx::NativeWindow BrowserWindowCocoa::GetNativeWindow() {
[email protected]7d791652010-12-01 16:34:49258 return window();
259}
260
261BrowserWindowTesting* BrowserWindowCocoa::GetBrowserWindowTesting() {
262 return NULL;
263}
264
265StatusBubble* BrowserWindowCocoa::GetStatusBubble() {
266 return [controller_ statusBubble];
267}
268
[email protected]7d791652010-12-01 16:34:49269void BrowserWindowCocoa::UpdateTitleBar() {
270 NSString* newTitle =
271 base::SysUTF16ToNSString(browser_->GetWindowTitleForCurrentTab());
272
[email protected]d78e615e2011-09-06 21:46:03273 pending_window_title_.reset(
274 [BrowserWindowUtils scheduleReplaceOldTitle:pending_window_title_.get()
275 withNewTitle:newTitle
276 forWindow:window()]);
[email protected]7d791652010-12-01 16:34:49277}
278
[email protected]09b29342011-06-24 19:18:48279void BrowserWindowCocoa::BookmarkBarStateChanged(
280 BookmarkBar::AnimateChangeType change_type) {
[email protected]1eeccb92012-12-06 20:31:24281 [[controller_ bookmarkBarController]
282 updateState:browser_->bookmark_bar_state()
283 changeType:change_type];
[email protected]7d791652010-12-01 16:34:49284}
285
286void BrowserWindowCocoa::UpdateDevTools() {
287 [controller_ updateDevToolsForContents:
[email protected]617ee962013-01-29 20:49:12288 browser_->tab_strip_model()->GetActiveWebContents()];
[email protected]7d791652010-12-01 16:34:49289}
290
291void BrowserWindowCocoa::UpdateLoadingAnimations(bool should_animate) {
292 // Do nothing on Mac.
293}
294
295void BrowserWindowCocoa::SetStarredState(bool is_starred) {
296 [controller_ setStarredState:is_starred ? YES : NO];
297}
298
[email protected]5423c372012-08-22 05:50:16299void BrowserWindowCocoa::ZoomChangedForActiveTab(bool can_show_bubble) {
300 [controller_ zoomChangedForActiveTab:can_show_bubble ? YES : NO];
[email protected]6f80e932012-06-04 19:00:07301}
302
[email protected]7d791652010-12-01 16:34:49303gfx::Rect BrowserWindowCocoa::GetRestoredBounds() const {
304 // Flip coordinates based on the primary screen.
305 NSScreen* screen = [[NSScreen screens] objectAtIndex:0];
306 NSRect frame = [controller_ regularWindowFrame];
[email protected]03e0f5f1e2012-06-07 21:35:39307 gfx::Rect bounds(frame.origin.x, 0, NSWidth(frame), NSHeight(frame));
308 bounds.set_y(NSHeight([screen frame]) - NSMaxY(frame));
[email protected]7d791652010-12-01 16:34:49309 return bounds;
310}
311
[email protected]d479b8e22011-02-09 05:19:49312gfx::Rect BrowserWindowCocoa::GetBounds() const {
313 return GetRestoredBounds();
314}
315
[email protected]7d791652010-12-01 16:34:49316bool BrowserWindowCocoa::IsMaximized() const {
317 return [window() isZoomed];
318}
319
[email protected]400eaf82011-08-22 15:47:39320bool BrowserWindowCocoa::IsMinimized() const {
321 return [window() isMiniaturized];
322}
323
[email protected]541e3ee2011-11-22 01:31:10324void BrowserWindowCocoa::Maximize() {
325 // Zoom toggles so only call if not already maximized.
326 if (!IsMaximized())
327 [window() zoom:controller_];
328}
329
330void BrowserWindowCocoa::Minimize() {
331 [window() miniaturize:controller_];
332}
333
334void BrowserWindowCocoa::Restore() {
335 if (IsMaximized())
336 [window() zoom:controller_]; // Toggles zoom mode.
337 else if (IsMinimized())
338 [window() deminiaturize:controller_];
339}
340
[email protected]8d944b32011-10-17 06:11:53341void BrowserWindowCocoa::EnterFullscreen(
[email protected]22d74a6b2011-10-17 20:30:31342 const GURL& url, FullscreenExitBubbleType bubble_type) {
[email protected]34337d32013-01-29 20:29:01343 [controller_ enterPresentationModeForURL:url
344 bubbleType:bubble_type];
[email protected]55c87fa2011-10-15 07:28:28345}
346
347void BrowserWindowCocoa::ExitFullscreen() {
[email protected]22d74a6b2011-10-17 20:30:31348 [controller_ exitFullscreen];
[email protected]8d944b32011-10-17 06:11:53349}
350
351void BrowserWindowCocoa::UpdateFullscreenExitBubbleContent(
352 const GURL& url,
353 FullscreenExitBubbleType bubble_type) {
[email protected]22d74a6b2011-10-17 20:30:31354 [controller_ updateFullscreenExitBubbleURL:url bubbleType:bubble_type];
[email protected]7d791652010-12-01 16:34:49355}
356
357bool BrowserWindowCocoa::IsFullscreen() const {
[email protected]34337d32013-01-29 20:29:01358 if ([controller_ inPresentationMode])
359 CHECK([controller_ isFullscreen]); // Presentation mode must be fullscreen.
[email protected]8d944b32011-10-17 06:11:53360 return [controller_ isFullscreen];
[email protected]7d791652010-12-01 16:34:49361}
362
363bool BrowserWindowCocoa::IsFullscreenBubbleVisible() const {
364 return false;
365}
366
367void BrowserWindowCocoa::ConfirmAddSearchProvider(
[email protected]3613347d2012-04-27 20:27:37368 TemplateURL* template_url,
[email protected]7d791652010-12-01 16:34:49369 Profile* profile) {
[email protected]464f0012011-07-07 02:12:51370 // The controller will release itself when the window closes.
371 EditSearchEngineCocoaController* editor =
372 [[EditSearchEngineCocoaController alloc] initWithProfile:profile
373 delegate:NULL
374 templateURL:template_url];
375 [NSApp beginSheet:[editor window]
376 modalForWindow:window()
377 modalDelegate:controller_
378 didEndSelector:@selector(sheetDidEnd:returnCode:context:)
379 contextInfo:NULL];
[email protected]7d791652010-12-01 16:34:49380}
381
382LocationBar* BrowserWindowCocoa::GetLocationBar() const {
383 return [controller_ locationBarBridge];
384}
385
386void BrowserWindowCocoa::SetFocusToLocationBar(bool select_all) {
387 [controller_ focusLocationBar:select_all ? YES : NO];
388}
389
390void BrowserWindowCocoa::UpdateReloadStopState(bool is_loading, bool force) {
391 [controller_ setIsLoading:is_loading force:force];
392}
393
[email protected]36ad4aa82012-11-21 19:20:48394void BrowserWindowCocoa::UpdateToolbar(content::WebContents* contents,
[email protected]7d791652010-12-01 16:34:49395 bool should_restore_state) {
[email protected]36ad4aa82012-11-21 19:20:48396 [controller_ updateToolbarWithContents:contents
[email protected]7d791652010-12-01 16:34:49397 shouldRestoreState:should_restore_state ? YES : NO];
398}
399
400void BrowserWindowCocoa::FocusToolbar() {
401 // Not needed on the Mac.
402}
403
404void BrowserWindowCocoa::FocusAppMenu() {
405 // Chrome uses the standard Mac OS X menu bar, so this isn't needed.
406}
407
408void BrowserWindowCocoa::RotatePaneFocus(bool forwards) {
409 // Not needed on the Mac.
410}
411
412void BrowserWindowCocoa::FocusBookmarksToolbar() {
413 // Not needed on the Mac.
414}
415
[email protected]7d791652010-12-01 16:34:49416
417bool BrowserWindowCocoa::IsBookmarkBarVisible() const {
[email protected]a007e732011-08-05 13:32:19418 return browser_->profile()->GetPrefs()->GetBoolean(prefs::kShowBookmarkBar);
[email protected]7d791652010-12-01 16:34:49419}
420
421bool BrowserWindowCocoa::IsBookmarkBarAnimating() const {
422 return [controller_ isBookmarkBarAnimating];
423}
424
[email protected]95bf8a5b2010-12-22 16:04:07425bool BrowserWindowCocoa::IsTabStripEditable() const {
426 return ![controller_ isDragSessionActive];
427}
428
[email protected]7d791652010-12-01 16:34:49429bool BrowserWindowCocoa::IsToolbarVisible() const {
430 return browser_->SupportsWindowFeature(Browser::FEATURE_TOOLBAR) ||
431 browser_->SupportsWindowFeature(Browser::FEATURE_LOCATIONBAR);
432}
433
[email protected]b7a756d42012-01-23 18:08:17434gfx::Rect BrowserWindowCocoa::GetRootWindowResizerRect() const {
[email protected]9f8727092012-02-08 01:38:18435 if (IsDownloadShelfVisible())
436 return gfx::Rect();
[email protected]b7a756d42012-01-23 18:08:17437 NSRect tabRect = [controller_ selectedTabGrowBoxRect];
438 return gfx::Rect(NSRectToCGRect(tabRect));
439}
440
[email protected]5f58c2af2012-01-11 17:55:29441bool BrowserWindowCocoa::IsPanel() const {
442 return false;
443}
444
[email protected]7d791652010-12-01 16:34:49445// This is called from Browser, which in turn is called directly from
446// a menu option. All we do here is set a preference. The act of
447// setting the preference sends notifications to all windows who then
448// know what to do.
449void BrowserWindowCocoa::ToggleBookmarkBar() {
[email protected]03020ff2012-11-29 12:08:17450 chrome::ToggleBookmarkBarWhenVisible(browser_->profile());
[email protected]7d791652010-12-01 16:34:49451}
452
453void BrowserWindowCocoa::AddFindBar(
454 FindBarCocoaController* find_bar_cocoa_controller) {
[email protected]632983f2011-08-08 22:51:24455 [controller_ addFindBar:find_bar_cocoa_controller];
[email protected]7d791652010-12-01 16:34:49456}
457
[email protected]7d791652010-12-01 16:34:49458void BrowserWindowCocoa::ShowUpdateChromeDialog() {
[email protected]678dae82011-02-11 20:03:08459 restart_browser::RequestRestart(window());
[email protected]7d791652010-12-01 16:34:49460}
461
[email protected]a316e572013-01-18 21:23:55462void BrowserWindowCocoa::ShowTaskManager() {
[email protected]898febec2012-05-31 18:15:48463 TaskManagerMac::Show(false);
[email protected]adb6a84d2011-02-07 16:58:40464}
465
[email protected]a316e572013-01-18 21:23:55466void BrowserWindowCocoa::ShowBackgroundPages() {
[email protected]898febec2012-05-31 18:15:48467 TaskManagerMac::Show(true);
[email protected]7d791652010-12-01 16:34:49468}
469
470void BrowserWindowCocoa::ShowBookmarkBubble(const GURL& url,
471 bool already_bookmarked) {
472 [controller_ showBookmarkBubbleForURL:url
473 alreadyBookmarked:(already_bookmarked ? YES : NO)];
474}
475
[email protected]b106ca52012-03-13 06:08:46476void BrowserWindowCocoa::ShowChromeToMobileBubble() {
[email protected]24bbcdd2012-03-27 03:14:17477 [controller_ showChromeToMobileBubble];
[email protected]b106ca52012-03-13 06:08:46478}
479
[email protected]235a0562012-03-26 22:22:35480#if defined(ENABLE_ONE_CLICK_SIGNIN)
[email protected]fe54b4a2012-03-28 16:11:04481void BrowserWindowCocoa::ShowOneClickSigninBubble(
[email protected]265c9272013-01-25 19:18:45482 OneClickSigninBubbleType type,
483 const StartSyncCallback& start_sync_callback) {
[email protected]8aa690c2013-02-06 22:33:12484 if (type == ONE_CLICK_SIGNIN_BUBBLE_TYPE_BUBBLE) {
485 scoped_nsobject<OneClickSigninBubbleController> bubble_controller(
486 [[OneClickSigninBubbleController alloc]
487 initWithBrowserWindowController:cocoa_controller()
488 callback:start_sync_callback]);
489 [bubble_controller showWindow:nil];
490 } else {
491 WebContents* web_contents =
492 browser_->tab_strip_model()->GetActiveWebContents();
493 // Deletes itself when the dialog closes.
494 new OneClickSigninDialogController(web_contents, start_sync_callback);
495 }
[email protected]235a0562012-03-26 22:22:35496}
497#endif
498
[email protected]7d791652010-12-01 16:34:49499bool BrowserWindowCocoa::IsDownloadShelfVisible() const {
500 return [controller_ isDownloadShelfVisible] != NO;
501}
502
503DownloadShelf* BrowserWindowCocoa::GetDownloadShelf() {
504 DownloadShelfController* shelfController = [controller_ downloadShelf];
505 return [shelfController bridge];
506}
507
[email protected]7d791652010-12-01 16:34:49508// We allow closing the window here since the real quit decision on Mac is made
509// in [AppController quit:].
510void BrowserWindowCocoa::ConfirmBrowserCloseWithPendingDownloads() {
511 // Call InProgressDownloadResponse asynchronously to avoid a crash when the
512 // browser window is closed here (http://crbug.com/44454).
[email protected]a932d9e2011-09-29 01:14:34513 MessageLoop::current()->PostTask(FROM_HERE,
514 base::Bind(&Browser::InProgressDownloadResponse,
515 confirm_close_factory_.GetWeakPtr(), true));
[email protected]7d791652010-12-01 16:34:49516}
517
[email protected]7d791652010-12-01 16:34:49518void BrowserWindowCocoa::UserChangedTheme() {
519 [controller_ userChangedTheme];
520}
521
522int BrowserWindowCocoa::GetExtraRenderViewHeight() const {
523 // Currently this is only used on linux.
524 return 0;
525}
526
[email protected]2a6bc3e2011-12-28 23:51:33527void BrowserWindowCocoa::WebContentsFocused(WebContents* contents) {
[email protected]7d791652010-12-01 16:34:49528 NOTIMPLEMENTED();
529}
530
[email protected]b8e681e82012-02-20 10:18:47531void BrowserWindowCocoa::ShowWebsiteSettings(
532 Profile* profile,
[email protected]36ad4aa82012-11-21 19:20:48533 content::WebContents* web_contents,
[email protected]b8e681e82012-02-20 10:18:47534 const GURL& url,
535 const content::SSLStatus& ssl,
536 bool show_history) {
[email protected]5436c8fd2012-07-02 11:30:46537 WebsiteSettingsUIBridge::Show(
[email protected]36ad4aa82012-11-21 19:20:48538 window(), profile, web_contents, url, ssl);
[email protected]b8e681e82012-02-20 10:18:47539}
540
[email protected]7d791652010-12-01 16:34:49541void BrowserWindowCocoa::ShowAppMenu() {
542 // No-op. Mac doesn't support showing the menus via alt keys.
543}
544
545bool BrowserWindowCocoa::PreHandleKeyboardEvent(
546 const NativeWebKeyboardEvent& event, bool* is_keyboard_shortcut) {
[email protected]3a1381d2011-08-26 18:12:13547 if (![BrowserWindowUtils shouldHandleKeyboardEvent:event])
[email protected]7d791652010-12-01 16:34:49548 return false;
549
[email protected]d2885ba2012-08-17 10:23:12550 if (event.type == WebKit::WebInputEvent::RawKeyDown &&
551 [controller_ handledByExtensionCommand:event.os_event])
552 return true;
553
[email protected]3a1381d2011-08-26 18:12:13554 int id = [BrowserWindowUtils getCommandId:event];
[email protected]7d791652010-12-01 16:34:49555 if (id == -1)
556 return false;
557
[email protected]5d98294912012-06-27 22:57:40558 if (browser_->command_controller()->IsReservedCommandOrKey(id, event)) {
[email protected]3a1381d2011-08-26 18:12:13559 return [BrowserWindowUtils handleKeyboardEvent:event.os_event
560 inWindow:window()];
561 }
[email protected]7d791652010-12-01 16:34:49562
[email protected]3a1381d2011-08-26 18:12:13563 DCHECK(is_keyboard_shortcut);
[email protected]7d791652010-12-01 16:34:49564 *is_keyboard_shortcut = true;
[email protected]7d791652010-12-01 16:34:49565 return false;
566}
567
568void BrowserWindowCocoa::HandleKeyboardEvent(
569 const NativeWebKeyboardEvent& event) {
[email protected]3a1381d2011-08-26 18:12:13570 if ([BrowserWindowUtils shouldHandleKeyboardEvent:event])
571 [BrowserWindowUtils handleKeyboardEvent:event.os_event inWindow:window()];
[email protected]7d791652010-12-01 16:34:49572}
573
[email protected]7d791652010-12-01 16:34:49574void BrowserWindowCocoa::ShowCreateChromeAppShortcutsDialog(
[email protected]1c321ee2012-05-21 03:02:34575 Profile* profile, const extensions::Extension* app) {
[email protected]25ebfd362013-01-16 05:41:55576 // Normally we would show a dialog, but since we always create the app
577 // shortcut in /Applications there are no options for the user to choose.
[email protected]4fd2ab52013-02-05 23:20:50578 web_app::UpdateShortcutInfoAndIconForApp(*app, profile,
579 base::Bind(&web_app::CreateShortcuts));
[email protected]7d791652010-12-01 16:34:49580}
581
582void BrowserWindowCocoa::Cut() {
583 [NSApp sendAction:@selector(cut:) to:nil from:nil];
584}
585
586void BrowserWindowCocoa::Copy() {
587 [NSApp sendAction:@selector(copy:) to:nil from:nil];
588}
589
590void BrowserWindowCocoa::Paste() {
591 [NSApp sendAction:@selector(paste:) to:nil from:nil];
592}
593
[email protected]7d791652010-12-01 16:34:49594void BrowserWindowCocoa::OpenTabpose() {
595 [controller_ openTabpose];
596}
597
[email protected]34337d32013-01-29 20:29:01598void BrowserWindowCocoa::EnterFullscreenWithChrome() {
599 CHECK(base::mac::IsOSLionOrLater());
600 if ([controller_ inPresentationMode])
601 [controller_ exitPresentationMode];
602 else
603 [controller_ enterFullscreen];
[email protected]8d944b32011-10-17 06:11:53604}
605
[email protected]34337d32013-01-29 20:29:01606bool BrowserWindowCocoa::IsFullscreenWithChrome() {
607 return IsFullscreen() && ![controller_ inPresentationMode];
[email protected]d3766932011-08-04 22:18:23608}
609
[email protected]34337d32013-01-29 20:29:01610bool BrowserWindowCocoa::IsFullscreenWithoutChrome() {
611 return IsFullscreen() && [controller_ inPresentationMode];
[email protected]d3766932011-08-04 22:18:23612}
613
[email protected]7d791652010-12-01 16:34:49614gfx::Rect BrowserWindowCocoa::GetInstantBounds() {
615 // Flip coordinates based on the primary screen.
616 NSScreen* screen = [[NSScreen screens] objectAtIndex:0];
617 NSRect monitorFrame = [screen frame];
618 NSRect frame = [controller_ instantFrame];
619 gfx::Rect bounds(NSRectToCGRect(frame));
620 bounds.set_y(NSHeight(monitorFrame) - bounds.y() - bounds.height());
621 return bounds;
622}
623
[email protected]588300d2011-04-28 21:06:35624WindowOpenDisposition BrowserWindowCocoa::GetDispositionForPopupBounds(
625 const gfx::Rect& bounds) {
[email protected]d82a3c9f2012-02-22 04:46:00626 // In Lion fullscreen mode, convert popups into tabs.
627 if (base::mac::IsOSLionOrLater() && IsFullscreen())
628 return NEW_FOREGROUND_TAB;
[email protected]588300d2011-04-28 21:06:35629 return NEW_POPUP;
630}
631
[email protected]632983f2011-08-08 22:51:24632FindBar* BrowserWindowCocoa::CreateFindBar() {
633 // We could push the AddFindBar() call into the FindBarBridge
634 // constructor or the FindBarCocoaController init, but that makes
635 // unit testing difficult, since we would also require a
636 // BrowserWindow object.
637 FindBarBridge* bridge = new FindBarBridge();
638 AddFindBar(bridge->find_bar_cocoa_controller());
639 return bridge;
640}
641
[email protected]d3afce92012-10-07 05:47:36642bool BrowserWindowCocoa::GetConstrainedWindowTopY(int* top_y) {
643 return false;
[email protected]6a151762012-10-03 22:33:19644}
645
[email protected]78ce3022012-09-24 01:48:48646extensions::ActiveTabPermissionGranter*
647 BrowserWindowCocoa::GetActiveTabPermissionGranter() {
[email protected]852934842012-12-10 16:50:13648 WebContents* web_contents =
649 browser_->tab_strip_model()->GetActiveWebContents();
650 if (!web_contents)
[email protected]78ce3022012-09-24 01:48:48651 return NULL;
652 extensions::TabHelper* tab_helper =
[email protected]852934842012-12-10 16:50:13653 extensions::TabHelper::FromWebContents(web_contents);
[email protected]78ce3022012-09-24 01:48:48654 return tab_helper ? tab_helper->active_tab_permission_granter() : NULL;
655}
656
[email protected]e2395da2013-01-23 22:05:35657void BrowserWindowCocoa::ModeChanged(
658 const chrome::search::Mode& old_mode,
659 const chrome::search::Mode& new_mode) {
660 [controller_ updateBookmarkBarStateForInstantPreview];
661}
662
[email protected]7d791652010-12-01 16:34:49663void BrowserWindowCocoa::DestroyBrowser() {
664 [controller_ destroyBrowser];
665
666 // at this point the controller is dead (autoreleased), so
667 // make sure we don't try to reference it any more.
668}
669
670NSWindow* BrowserWindowCocoa::window() const {
671 return [controller_ window];
672}
673
[email protected]0ec4898e2011-12-30 21:09:24674void BrowserWindowCocoa::ShowAvatarBubble(WebContents* web_contents,
[email protected]2f733a02011-10-06 15:17:34675 const gfx::Rect& rect) {
[email protected]f5d230b32012-12-11 02:04:11676 NSPoint point = GetPointForBubble(web_contents, rect.right(), rect.bottom());
[email protected]2f733a02011-10-06 15:17:34677
678 // |menu| will automatically release itself on close.
679 AvatarMenuBubbleController* menu =
680 [[AvatarMenuBubbleController alloc] initWithBrowser:browser_
681 anchoredAt:point];
[email protected]51152d6d2011-11-07 01:55:12682 [[menu bubble] setAlignment:info_bubble::kAlignEdgeToAnchorEdge];
[email protected]2f733a02011-10-06 15:17:34683 [menu showWindow:nil];
684}
[email protected]7d2d08152011-10-25 22:58:47685
686void BrowserWindowCocoa::ShowAvatarBubbleFromAvatarButton() {
687 [[controller_ avatarButtonController] showAvatarBubble];
688}
[email protected]f5d230b32012-12-11 02:04:11689
690void BrowserWindowCocoa::ShowPasswordGenerationBubble(
691 const gfx::Rect& rect,
692 const content::PasswordForm& form,
693 autofill::PasswordGenerator* password_generator) {
[email protected]617ee962013-01-29 20:49:12694 WebContents* web_contents =
695 browser_->tab_strip_model()->GetActiveWebContents();
[email protected]f5d230b32012-12-11 02:04:11696 // We want to point to the middle of the rect instead of the right side.
697 NSPoint point = GetPointForBubble(web_contents,
698 rect.x() + rect.width()/2,
699 rect.bottom());
700
701 PasswordGenerationBubbleController* controller =
702 [[PasswordGenerationBubbleController alloc]
703 initWithWindow:browser_->window()->GetNativeWindow()
704 anchoredAt:point
705 renderViewHost:web_contents->GetRenderViewHost()
706 passwordManager:PasswordManager::FromWebContents(web_contents)
707 usingGenerator:password_generator
708 forForm:form];
709 [controller showWindow:nil];
710}