blob: 69da9615dff8b90993ae22b19319f5f560eb1d91 [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"
62#endif
63
[email protected]b87ee522012-05-18 15:16:5464using content::NativeWebKeyboardEvent;
[email protected]d583e3f22011-12-27 21:38:1765using content::SSLStatus;
[email protected]2a6bc3e2011-12-28 23:51:3366using content::WebContents;
[email protected]d583e3f22011-12-27 21:38:1767
[email protected]400eaf82011-08-22 15:47:3968// Replicate specific 10.7 SDK declarations for building with prior SDKs.
69#if !defined(MAC_OS_X_VERSION_10_7) || \
70 MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7
71
72enum {
73 NSWindowAnimationBehaviorDefault = 0,
74 NSWindowAnimationBehaviorNone = 2,
75 NSWindowAnimationBehaviorDocumentWindow = 3,
76 NSWindowAnimationBehaviorUtilityWindow = 4,
77 NSWindowAnimationBehaviorAlertPanel = 5
78};
79typedef NSInteger NSWindowAnimationBehavior;
80
81@interface NSWindow (LionSDKDeclarations)
82- (NSWindowAnimationBehavior)animationBehavior;
83- (void)setAnimationBehavior:(NSWindowAnimationBehavior)newAnimationBehavior;
84@end
85
86#endif // MAC_OS_X_VERSION_10_7
87
[email protected]f5d230b32012-12-11 02:04:1188namespace {
89
90NSPoint GetPointForBubble(content::WebContents* web_contents,
91 int x_offset,
92 int y_offset) {
93 NSView* view = web_contents->GetNativeView();
94 NSRect bounds = [view bounds];
95 NSPoint point;
96 point.x = NSMinX(bounds) + x_offset;
97 // The view's origin is at the bottom but |rect|'s origin is at the top.
98 point.y = NSMaxY(bounds) - y_offset;
99 point = [view convertPoint:point toView:nil];
100 point = [[view window] convertBaseToScreen:point];
101 return point;
102}
103
104} // namespace
105
[email protected]7d791652010-12-01 16:34:49106BrowserWindowCocoa::BrowserWindowCocoa(Browser* browser,
[email protected]400eaf82011-08-22 15:47:39107 BrowserWindowController* controller)
[email protected]7d791652010-12-01 16:34:49108 : browser_(browser),
109 controller_(controller),
[email protected]ad996342012-01-14 00:29:59110 confirm_close_factory_(browser),
[email protected]6a9b53a22012-10-09 02:43:34111 initial_show_state_(ui::SHOW_STATE_DEFAULT),
[email protected]ad996342012-01-14 00:29:59112 attention_request_id_(0) {
[email protected]cfecf9432011-09-27 17:10:08113
[email protected]6a9b53a22012-10-09 02:43:34114 gfx::Rect bounds;
115 chrome::GetSavedWindowBoundsAndShowState(browser_,
116 &bounds,
117 &initial_show_state_);
[email protected]e2395da2013-01-23 22:05:35118
119 browser_->search_model()->AddObserver(this);
[email protected]7d791652010-12-01 16:34:49120}
121
122BrowserWindowCocoa::~BrowserWindowCocoa() {
[email protected]e2395da2013-01-23 22:05:35123 browser_->search_model()->RemoveObserver(this);
[email protected]7d791652010-12-01 16:34:49124}
125
126void BrowserWindowCocoa::Show() {
127 // The Browser associated with this browser window must become the active
128 // browser at the time |Show()| is called. This is the natural behaviour under
129 // Windows, but |-makeKeyAndOrderFront:| won't send |-windowDidBecomeMain:|
130 // until we return to the runloop. Therefore any calls to
[email protected]4d900252012-11-20 20:37:11131 // |chrome::FindLastActiveWithHostDesktopType| will return the previous
132 // browser instead if we don't explicitly set it here.
[email protected]7d791652010-12-01 16:34:49133 BrowserList::SetLastActive(browser_);
134
[email protected]8bc061f2011-08-31 22:46:23135 bool is_session_restore = browser_->is_session_restore();
[email protected]b5cc93c2011-09-02 02:33:42136 NSWindowAnimationBehavior saved_animation_behavior =
137 NSWindowAnimationBehaviorDefault;
[email protected]8bc061f2011-08-31 22:46:23138 bool did_save_animation_behavior = false;
139 // Turn off swishing when restoring windows.
140 if (is_session_restore &&
141 [window() respondsToSelector:@selector(animationBehavior)] &&
142 [window() respondsToSelector:@selector(setAnimationBehavior:)]) {
143 did_save_animation_behavior = true;
144 saved_animation_behavior = [window() animationBehavior];
145 [window() setAnimationBehavior:NSWindowAnimationBehaviorNone];
146 }
[email protected]400eaf82011-08-22 15:47:39147
[email protected]8bc061f2011-08-31 22:46:23148 [window() makeKeyAndOrderFront:controller_];
[email protected]400eaf82011-08-22 15:47:39149
[email protected]8bc061f2011-08-31 22:46:23150 // When creating windows from nibs it is necessary to |makeKeyAndOrderFront:|
151 // prior to |orderOut:| then |miniaturize:| when restoring windows in the
152 // minimized state.
[email protected]cfecf9432011-09-27 17:10:08153 if (initial_show_state_ == ui::SHOW_STATE_MINIMIZED) {
[email protected]400eaf82011-08-22 15:47:39154 [window() orderOut:controller_];
155 [window() miniaturize:controller_];
[email protected]85b0ac62012-02-09 01:57:43156 } else if (initial_show_state_ == ui::SHOW_STATE_FULLSCREEN) {
[email protected]3f32b9b2012-07-09 16:59:28157 chrome::ToggleFullscreenMode(browser_);
[email protected]400eaf82011-08-22 15:47:39158 }
[email protected]cfecf9432011-09-27 17:10:08159 initial_show_state_ = ui::SHOW_STATE_DEFAULT;
[email protected]8bc061f2011-08-31 22:46:23160
161 // Restore window animation behavior.
162 if (did_save_animation_behavior)
163 [window() setAnimationBehavior:saved_animation_behavior];
[email protected]2f516c792011-09-19 22:22:09164
165 browser_->OnWindowDidShow();
[email protected]7d791652010-12-01 16:34:49166}
167
[email protected]d4db6c702011-03-28 21:49:14168void BrowserWindowCocoa::ShowInactive() {
[email protected]400eaf82011-08-22 15:47:39169 [window() orderFront:controller_];
[email protected]d4db6c702011-03-28 21:49:14170}
171
[email protected]7d412f72012-10-25 04:59:15172void BrowserWindowCocoa::Hide() {
173 // Not implemented.
174}
175
[email protected]7d791652010-12-01 16:34:49176void BrowserWindowCocoa::SetBounds(const gfx::Rect& bounds) {
[email protected]ccb5895f2011-06-09 21:16:14177 gfx::Rect real_bounds = [controller_ enforceMinWindowSize:bounds];
178
[email protected]55c87fa2011-10-15 07:28:28179 ExitFullscreen();
[email protected]ccb5895f2011-06-09 21:16:14180 NSRect cocoa_bounds = NSMakeRect(real_bounds.x(), 0,
181 real_bounds.width(),
182 real_bounds.height());
[email protected]7d791652010-12-01 16:34:49183 // Flip coordinates based on the primary screen.
184 NSScreen* screen = [[NSScreen screens] objectAtIndex:0];
185 cocoa_bounds.origin.y =
[email protected]03e0f5f1e2012-06-07 21:35:39186 NSHeight([screen frame]) - real_bounds.height() - real_bounds.y();
[email protected]7d791652010-12-01 16:34:49187
188 [window() setFrame:cocoa_bounds display:YES];
189}
190
191// Callers assume that this doesn't immediately delete the Browser object.
192// The controller implementing the window delegate methods called from
193// |-performClose:| must take precautions to ensure that.
194void BrowserWindowCocoa::Close() {
195 // If there is an overlay window, we contain a tab being dragged between
196 // windows. Don't hide the window as it makes the UI extra confused. We can
197 // still close the window, as that will happen when the drag completes.
[email protected]60f94292012-03-12 22:24:27198 if ([controller_ overlayWindow]) {
[email protected]7d791652010-12-01 16:34:49199 [controller_ deferPerformClose];
[email protected]60f94292012-03-12 22:24:27200 } else {
[email protected]5ea51972012-10-15 16:45:47201 // Using |-performClose:| can prevent the window from actually closing if
202 // a JavaScript beforeunload handler opens an alert during shutdown, as
203 // documented at <http://crbug.com/118424>. Re-implement
204 // -[NSWindow performClose:] as closely as possible to how Apple documents
205 // it.
[email protected]d1136ca2012-10-18 23:35:55206 //
207 // Before calling |-close|, hide the window immediately. |-performClose:|
208 // would do something similar, and this ensures that the window is removed
209 // from AppKit's display list. Not doing so can lead to crashes like
210 // <http://crbug.com/156101>.
[email protected]5ea51972012-10-15 16:45:47211 id<NSWindowDelegate> delegate = [window() delegate];
212 SEL window_should_close = @selector(windowShouldClose:);
213 if ([delegate respondsToSelector:window_should_close]) {
[email protected]d1136ca2012-10-18 23:35:55214 if ([delegate windowShouldClose:window()]) {
215 [window() orderOut:nil];
[email protected]5ea51972012-10-15 16:45:47216 [window() close];
[email protected]d1136ca2012-10-18 23:35:55217 }
[email protected]5ea51972012-10-15 16:45:47218 } else if ([window() respondsToSelector:window_should_close]) {
[email protected]d1136ca2012-10-18 23:35:55219 if ([window() performSelector:window_should_close withObject:window()]) {
220 [window() orderOut:nil];
[email protected]5ea51972012-10-15 16:45:47221 [window() close];
[email protected]d1136ca2012-10-18 23:35:55222 }
[email protected]5ea51972012-10-15 16:45:47223 } else {
[email protected]d1136ca2012-10-18 23:35:55224 [window() orderOut:nil];
[email protected]5ea51972012-10-15 16:45:47225 [window() close];
226 }
[email protected]60f94292012-03-12 22:24:27227 }
[email protected]7d791652010-12-01 16:34:49228}
229
230void BrowserWindowCocoa::Activate() {
231 [controller_ activate];
232}
233
234void BrowserWindowCocoa::Deactivate() {
235 // TODO(jcivelli): http://crbug.com/51364 Implement me.
236 NOTIMPLEMENTED();
237}
238
[email protected]ad996342012-01-14 00:29:59239void BrowserWindowCocoa::FlashFrame(bool flash) {
240 if (flash) {
241 attention_request_id_ = [NSApp requestUserAttention:NSInformationalRequest];
242 } else {
243 [NSApp cancelUserAttentionRequest:attention_request_id_];
244 attention_request_id_ = 0;
245 }
[email protected]7d791652010-12-01 16:34:49246}
247
[email protected]d101b0c2012-03-16 00:30:57248bool BrowserWindowCocoa::IsAlwaysOnTop() const {
249 return false;
250}
251
[email protected]7d791652010-12-01 16:34:49252bool BrowserWindowCocoa::IsActive() const {
253 return [window() isKeyWindow];
254}
255
[email protected]90556dd2012-06-07 20:26:18256gfx::NativeWindow BrowserWindowCocoa::GetNativeWindow() {
[email protected]7d791652010-12-01 16:34:49257 return window();
258}
259
260BrowserWindowTesting* BrowserWindowCocoa::GetBrowserWindowTesting() {
261 return NULL;
262}
263
264StatusBubble* BrowserWindowCocoa::GetStatusBubble() {
265 return [controller_ statusBubble];
266}
267
[email protected]7d791652010-12-01 16:34:49268void BrowserWindowCocoa::UpdateTitleBar() {
269 NSString* newTitle =
270 base::SysUTF16ToNSString(browser_->GetWindowTitleForCurrentTab());
271
[email protected]d78e615e2011-09-06 21:46:03272 pending_window_title_.reset(
273 [BrowserWindowUtils scheduleReplaceOldTitle:pending_window_title_.get()
274 withNewTitle:newTitle
275 forWindow:window()]);
[email protected]7d791652010-12-01 16:34:49276}
277
[email protected]09b29342011-06-24 19:18:48278void BrowserWindowCocoa::BookmarkBarStateChanged(
279 BookmarkBar::AnimateChangeType change_type) {
[email protected]1eeccb92012-12-06 20:31:24280 [[controller_ bookmarkBarController]
281 updateState:browser_->bookmark_bar_state()
282 changeType:change_type];
[email protected]7d791652010-12-01 16:34:49283}
284
285void BrowserWindowCocoa::UpdateDevTools() {
286 [controller_ updateDevToolsForContents:
[email protected]617ee962013-01-29 20:49:12287 browser_->tab_strip_model()->GetActiveWebContents()];
[email protected]7d791652010-12-01 16:34:49288}
289
290void BrowserWindowCocoa::UpdateLoadingAnimations(bool should_animate) {
291 // Do nothing on Mac.
292}
293
294void BrowserWindowCocoa::SetStarredState(bool is_starred) {
295 [controller_ setStarredState:is_starred ? YES : NO];
296}
297
[email protected]5423c372012-08-22 05:50:16298void BrowserWindowCocoa::ZoomChangedForActiveTab(bool can_show_bubble) {
299 [controller_ zoomChangedForActiveTab:can_show_bubble ? YES : NO];
[email protected]6f80e932012-06-04 19:00:07300}
301
[email protected]7d791652010-12-01 16:34:49302gfx::Rect BrowserWindowCocoa::GetRestoredBounds() const {
303 // Flip coordinates based on the primary screen.
304 NSScreen* screen = [[NSScreen screens] objectAtIndex:0];
305 NSRect frame = [controller_ regularWindowFrame];
[email protected]03e0f5f1e2012-06-07 21:35:39306 gfx::Rect bounds(frame.origin.x, 0, NSWidth(frame), NSHeight(frame));
307 bounds.set_y(NSHeight([screen frame]) - NSMaxY(frame));
[email protected]7d791652010-12-01 16:34:49308 return bounds;
309}
310
[email protected]d479b8e22011-02-09 05:19:49311gfx::Rect BrowserWindowCocoa::GetBounds() const {
312 return GetRestoredBounds();
313}
314
[email protected]7d791652010-12-01 16:34:49315bool BrowserWindowCocoa::IsMaximized() const {
316 return [window() isZoomed];
317}
318
[email protected]400eaf82011-08-22 15:47:39319bool BrowserWindowCocoa::IsMinimized() const {
320 return [window() isMiniaturized];
321}
322
[email protected]541e3ee2011-11-22 01:31:10323void BrowserWindowCocoa::Maximize() {
324 // Zoom toggles so only call if not already maximized.
325 if (!IsMaximized())
326 [window() zoom:controller_];
327}
328
329void BrowserWindowCocoa::Minimize() {
330 [window() miniaturize:controller_];
331}
332
333void BrowserWindowCocoa::Restore() {
334 if (IsMaximized())
335 [window() zoom:controller_]; // Toggles zoom mode.
336 else if (IsMinimized())
337 [window() deminiaturize:controller_];
338}
339
[email protected]8d944b32011-10-17 06:11:53340void BrowserWindowCocoa::EnterFullscreen(
[email protected]22d74a6b2011-10-17 20:30:31341 const GURL& url, FullscreenExitBubbleType bubble_type) {
[email protected]34337d32013-01-29 20:29:01342 [controller_ enterPresentationModeForURL:url
343 bubbleType:bubble_type];
[email protected]55c87fa2011-10-15 07:28:28344}
345
346void BrowserWindowCocoa::ExitFullscreen() {
[email protected]22d74a6b2011-10-17 20:30:31347 [controller_ exitFullscreen];
[email protected]8d944b32011-10-17 06:11:53348}
349
350void BrowserWindowCocoa::UpdateFullscreenExitBubbleContent(
351 const GURL& url,
352 FullscreenExitBubbleType bubble_type) {
[email protected]22d74a6b2011-10-17 20:30:31353 [controller_ updateFullscreenExitBubbleURL:url bubbleType:bubble_type];
[email protected]7d791652010-12-01 16:34:49354}
355
356bool BrowserWindowCocoa::IsFullscreen() const {
[email protected]34337d32013-01-29 20:29:01357 if ([controller_ inPresentationMode])
358 CHECK([controller_ isFullscreen]); // Presentation mode must be fullscreen.
[email protected]8d944b32011-10-17 06:11:53359 return [controller_ isFullscreen];
[email protected]7d791652010-12-01 16:34:49360}
361
362bool BrowserWindowCocoa::IsFullscreenBubbleVisible() const {
363 return false;
364}
365
366void BrowserWindowCocoa::ConfirmAddSearchProvider(
[email protected]3613347d2012-04-27 20:27:37367 TemplateURL* template_url,
[email protected]7d791652010-12-01 16:34:49368 Profile* profile) {
[email protected]464f0012011-07-07 02:12:51369 // The controller will release itself when the window closes.
370 EditSearchEngineCocoaController* editor =
371 [[EditSearchEngineCocoaController alloc] initWithProfile:profile
372 delegate:NULL
373 templateURL:template_url];
374 [NSApp beginSheet:[editor window]
375 modalForWindow:window()
376 modalDelegate:controller_
377 didEndSelector:@selector(sheetDidEnd:returnCode:context:)
378 contextInfo:NULL];
[email protected]7d791652010-12-01 16:34:49379}
380
381LocationBar* BrowserWindowCocoa::GetLocationBar() const {
382 return [controller_ locationBarBridge];
383}
384
385void BrowserWindowCocoa::SetFocusToLocationBar(bool select_all) {
386 [controller_ focusLocationBar:select_all ? YES : NO];
387}
388
389void BrowserWindowCocoa::UpdateReloadStopState(bool is_loading, bool force) {
390 [controller_ setIsLoading:is_loading force:force];
391}
392
[email protected]36ad4aa82012-11-21 19:20:48393void BrowserWindowCocoa::UpdateToolbar(content::WebContents* contents,
[email protected]7d791652010-12-01 16:34:49394 bool should_restore_state) {
[email protected]36ad4aa82012-11-21 19:20:48395 [controller_ updateToolbarWithContents:contents
[email protected]7d791652010-12-01 16:34:49396 shouldRestoreState:should_restore_state ? YES : NO];
397}
398
399void BrowserWindowCocoa::FocusToolbar() {
400 // Not needed on the Mac.
401}
402
403void BrowserWindowCocoa::FocusAppMenu() {
404 // Chrome uses the standard Mac OS X menu bar, so this isn't needed.
405}
406
407void BrowserWindowCocoa::RotatePaneFocus(bool forwards) {
408 // Not needed on the Mac.
409}
410
411void BrowserWindowCocoa::FocusBookmarksToolbar() {
412 // Not needed on the Mac.
413}
414
[email protected]7d791652010-12-01 16:34:49415
416bool BrowserWindowCocoa::IsBookmarkBarVisible() const {
[email protected]a007e732011-08-05 13:32:19417 return browser_->profile()->GetPrefs()->GetBoolean(prefs::kShowBookmarkBar);
[email protected]7d791652010-12-01 16:34:49418}
419
420bool BrowserWindowCocoa::IsBookmarkBarAnimating() const {
421 return [controller_ isBookmarkBarAnimating];
422}
423
[email protected]95bf8a5b2010-12-22 16:04:07424bool BrowserWindowCocoa::IsTabStripEditable() const {
425 return ![controller_ isDragSessionActive];
426}
427
[email protected]7d791652010-12-01 16:34:49428bool BrowserWindowCocoa::IsToolbarVisible() const {
429 return browser_->SupportsWindowFeature(Browser::FEATURE_TOOLBAR) ||
430 browser_->SupportsWindowFeature(Browser::FEATURE_LOCATIONBAR);
431}
432
[email protected]b7a756d42012-01-23 18:08:17433gfx::Rect BrowserWindowCocoa::GetRootWindowResizerRect() const {
[email protected]9f8727092012-02-08 01:38:18434 if (IsDownloadShelfVisible())
435 return gfx::Rect();
[email protected]b7a756d42012-01-23 18:08:17436 NSRect tabRect = [controller_ selectedTabGrowBoxRect];
437 return gfx::Rect(NSRectToCGRect(tabRect));
438}
439
[email protected]5f58c2af2012-01-11 17:55:29440bool BrowserWindowCocoa::IsPanel() const {
441 return false;
442}
443
[email protected]7d791652010-12-01 16:34:49444// This is called from Browser, which in turn is called directly from
445// a menu option. All we do here is set a preference. The act of
446// setting the preference sends notifications to all windows who then
447// know what to do.
448void BrowserWindowCocoa::ToggleBookmarkBar() {
[email protected]03020ff2012-11-29 12:08:17449 chrome::ToggleBookmarkBarWhenVisible(browser_->profile());
[email protected]7d791652010-12-01 16:34:49450}
451
452void BrowserWindowCocoa::AddFindBar(
453 FindBarCocoaController* find_bar_cocoa_controller) {
[email protected]632983f2011-08-08 22:51:24454 [controller_ addFindBar:find_bar_cocoa_controller];
[email protected]7d791652010-12-01 16:34:49455}
456
[email protected]7d791652010-12-01 16:34:49457void BrowserWindowCocoa::ShowUpdateChromeDialog() {
[email protected]678dae82011-02-11 20:03:08458 restart_browser::RequestRestart(window());
[email protected]7d791652010-12-01 16:34:49459}
460
[email protected]a316e572013-01-18 21:23:55461void BrowserWindowCocoa::ShowTaskManager() {
[email protected]898febec2012-05-31 18:15:48462 TaskManagerMac::Show(false);
[email protected]adb6a84d2011-02-07 16:58:40463}
464
[email protected]a316e572013-01-18 21:23:55465void BrowserWindowCocoa::ShowBackgroundPages() {
[email protected]898febec2012-05-31 18:15:48466 TaskManagerMac::Show(true);
[email protected]7d791652010-12-01 16:34:49467}
468
469void BrowserWindowCocoa::ShowBookmarkBubble(const GURL& url,
470 bool already_bookmarked) {
471 [controller_ showBookmarkBubbleForURL:url
472 alreadyBookmarked:(already_bookmarked ? YES : NO)];
473}
474
[email protected]b106ca52012-03-13 06:08:46475void BrowserWindowCocoa::ShowChromeToMobileBubble() {
[email protected]24bbcdd2012-03-27 03:14:17476 [controller_ showChromeToMobileBubble];
[email protected]b106ca52012-03-13 06:08:46477}
478
[email protected]235a0562012-03-26 22:22:35479#if defined(ENABLE_ONE_CLICK_SIGNIN)
[email protected]fe54b4a2012-03-28 16:11:04480void BrowserWindowCocoa::ShowOneClickSigninBubble(
[email protected]265c9272013-01-25 19:18:45481 OneClickSigninBubbleType type,
482 const StartSyncCallback& start_sync_callback) {
[email protected]fe54b4a2012-03-28 16:11:04483 OneClickSigninBubbleController* bubble_controller =
484 [[OneClickSigninBubbleController alloc]
485 initWithBrowserWindowController:cocoa_controller()
[email protected]e4b66bf2012-05-29 20:39:51486 start_sync_callback:start_sync_callback];
[email protected]fe54b4a2012-03-28 16:11:04487 [bubble_controller showWindow:nil];
[email protected]235a0562012-03-26 22:22:35488}
489#endif
490
[email protected]7d791652010-12-01 16:34:49491bool BrowserWindowCocoa::IsDownloadShelfVisible() const {
492 return [controller_ isDownloadShelfVisible] != NO;
493}
494
495DownloadShelf* BrowserWindowCocoa::GetDownloadShelf() {
496 DownloadShelfController* shelfController = [controller_ downloadShelf];
497 return [shelfController bridge];
498}
499
[email protected]7d791652010-12-01 16:34:49500// We allow closing the window here since the real quit decision on Mac is made
501// in [AppController quit:].
502void BrowserWindowCocoa::ConfirmBrowserCloseWithPendingDownloads() {
503 // Call InProgressDownloadResponse asynchronously to avoid a crash when the
504 // browser window is closed here (http://crbug.com/44454).
[email protected]a932d9e2011-09-29 01:14:34505 MessageLoop::current()->PostTask(FROM_HERE,
506 base::Bind(&Browser::InProgressDownloadResponse,
507 confirm_close_factory_.GetWeakPtr(), true));
[email protected]7d791652010-12-01 16:34:49508}
509
[email protected]7d791652010-12-01 16:34:49510void BrowserWindowCocoa::UserChangedTheme() {
511 [controller_ userChangedTheme];
512}
513
514int BrowserWindowCocoa::GetExtraRenderViewHeight() const {
515 // Currently this is only used on linux.
516 return 0;
517}
518
[email protected]2a6bc3e2011-12-28 23:51:33519void BrowserWindowCocoa::WebContentsFocused(WebContents* contents) {
[email protected]7d791652010-12-01 16:34:49520 NOTIMPLEMENTED();
521}
522
[email protected]b8e681e82012-02-20 10:18:47523void BrowserWindowCocoa::ShowWebsiteSettings(
524 Profile* profile,
[email protected]36ad4aa82012-11-21 19:20:48525 content::WebContents* web_contents,
[email protected]b8e681e82012-02-20 10:18:47526 const GURL& url,
527 const content::SSLStatus& ssl,
528 bool show_history) {
[email protected]5436c8fd2012-07-02 11:30:46529 WebsiteSettingsUIBridge::Show(
[email protected]36ad4aa82012-11-21 19:20:48530 window(), profile, web_contents, url, ssl);
[email protected]b8e681e82012-02-20 10:18:47531}
532
[email protected]7d791652010-12-01 16:34:49533void BrowserWindowCocoa::ShowAppMenu() {
534 // No-op. Mac doesn't support showing the menus via alt keys.
535}
536
537bool BrowserWindowCocoa::PreHandleKeyboardEvent(
538 const NativeWebKeyboardEvent& event, bool* is_keyboard_shortcut) {
[email protected]3a1381d2011-08-26 18:12:13539 if (![BrowserWindowUtils shouldHandleKeyboardEvent:event])
[email protected]7d791652010-12-01 16:34:49540 return false;
541
[email protected]d2885ba2012-08-17 10:23:12542 if (event.type == WebKit::WebInputEvent::RawKeyDown &&
543 [controller_ handledByExtensionCommand:event.os_event])
544 return true;
545
[email protected]3a1381d2011-08-26 18:12:13546 int id = [BrowserWindowUtils getCommandId:event];
[email protected]7d791652010-12-01 16:34:49547 if (id == -1)
548 return false;
549
[email protected]5d98294912012-06-27 22:57:40550 if (browser_->command_controller()->IsReservedCommandOrKey(id, event)) {
[email protected]3a1381d2011-08-26 18:12:13551 return [BrowserWindowUtils handleKeyboardEvent:event.os_event
552 inWindow:window()];
553 }
[email protected]7d791652010-12-01 16:34:49554
[email protected]3a1381d2011-08-26 18:12:13555 DCHECK(is_keyboard_shortcut);
[email protected]7d791652010-12-01 16:34:49556 *is_keyboard_shortcut = true;
[email protected]7d791652010-12-01 16:34:49557 return false;
558}
559
560void BrowserWindowCocoa::HandleKeyboardEvent(
561 const NativeWebKeyboardEvent& event) {
[email protected]3a1381d2011-08-26 18:12:13562 if ([BrowserWindowUtils shouldHandleKeyboardEvent:event])
563 [BrowserWindowUtils handleKeyboardEvent:event.os_event inWindow:window()];
[email protected]7d791652010-12-01 16:34:49564}
565
[email protected]7d791652010-12-01 16:34:49566void BrowserWindowCocoa::ShowCreateChromeAppShortcutsDialog(
[email protected]1c321ee2012-05-21 03:02:34567 Profile* profile, const extensions::Extension* app) {
[email protected]25ebfd362013-01-16 05:41:55568 // Normally we would show a dialog, but since we always create the app
569 // shortcut in /Applications there are no options for the user to choose.
570 ShellIntegration::ShortcutInfo shortcut_info;
571 web_app::UpdateShortcutInfoForApp(*app, profile, &shortcut_info);
572 web_app::CreateShortcuts(shortcut_info);
[email protected]7d791652010-12-01 16:34:49573}
574
575void BrowserWindowCocoa::Cut() {
576 [NSApp sendAction:@selector(cut:) to:nil from:nil];
577}
578
579void BrowserWindowCocoa::Copy() {
580 [NSApp sendAction:@selector(copy:) to:nil from:nil];
581}
582
583void BrowserWindowCocoa::Paste() {
584 [NSApp sendAction:@selector(paste:) to:nil from:nil];
585}
586
[email protected]7d791652010-12-01 16:34:49587void BrowserWindowCocoa::OpenTabpose() {
588 [controller_ openTabpose];
589}
590
[email protected]34337d32013-01-29 20:29:01591void BrowserWindowCocoa::EnterFullscreenWithChrome() {
592 CHECK(base::mac::IsOSLionOrLater());
593 if ([controller_ inPresentationMode])
594 [controller_ exitPresentationMode];
595 else
596 [controller_ enterFullscreen];
[email protected]8d944b32011-10-17 06:11:53597}
598
[email protected]34337d32013-01-29 20:29:01599bool BrowserWindowCocoa::IsFullscreenWithChrome() {
600 return IsFullscreen() && ![controller_ inPresentationMode];
[email protected]d3766932011-08-04 22:18:23601}
602
[email protected]34337d32013-01-29 20:29:01603bool BrowserWindowCocoa::IsFullscreenWithoutChrome() {
604 return IsFullscreen() && [controller_ inPresentationMode];
[email protected]d3766932011-08-04 22:18:23605}
606
[email protected]7d791652010-12-01 16:34:49607gfx::Rect BrowserWindowCocoa::GetInstantBounds() {
608 // Flip coordinates based on the primary screen.
609 NSScreen* screen = [[NSScreen screens] objectAtIndex:0];
610 NSRect monitorFrame = [screen frame];
611 NSRect frame = [controller_ instantFrame];
612 gfx::Rect bounds(NSRectToCGRect(frame));
613 bounds.set_y(NSHeight(monitorFrame) - bounds.y() - bounds.height());
614 return bounds;
615}
616
[email protected]588300d2011-04-28 21:06:35617WindowOpenDisposition BrowserWindowCocoa::GetDispositionForPopupBounds(
618 const gfx::Rect& bounds) {
[email protected]d82a3c9f2012-02-22 04:46:00619 // In Lion fullscreen mode, convert popups into tabs.
620 if (base::mac::IsOSLionOrLater() && IsFullscreen())
621 return NEW_FOREGROUND_TAB;
[email protected]588300d2011-04-28 21:06:35622 return NEW_POPUP;
623}
624
[email protected]632983f2011-08-08 22:51:24625FindBar* BrowserWindowCocoa::CreateFindBar() {
626 // We could push the AddFindBar() call into the FindBarBridge
627 // constructor or the FindBarCocoaController init, but that makes
628 // unit testing difficult, since we would also require a
629 // BrowserWindow object.
630 FindBarBridge* bridge = new FindBarBridge();
631 AddFindBar(bridge->find_bar_cocoa_controller());
632 return bridge;
633}
634
[email protected]d3afce92012-10-07 05:47:36635bool BrowserWindowCocoa::GetConstrainedWindowTopY(int* top_y) {
636 return false;
[email protected]6a151762012-10-03 22:33:19637}
638
[email protected]78ce3022012-09-24 01:48:48639extensions::ActiveTabPermissionGranter*
640 BrowserWindowCocoa::GetActiveTabPermissionGranter() {
[email protected]852934842012-12-10 16:50:13641 WebContents* web_contents =
642 browser_->tab_strip_model()->GetActiveWebContents();
643 if (!web_contents)
[email protected]78ce3022012-09-24 01:48:48644 return NULL;
645 extensions::TabHelper* tab_helper =
[email protected]852934842012-12-10 16:50:13646 extensions::TabHelper::FromWebContents(web_contents);
[email protected]78ce3022012-09-24 01:48:48647 return tab_helper ? tab_helper->active_tab_permission_granter() : NULL;
648}
649
[email protected]e2395da2013-01-23 22:05:35650void BrowserWindowCocoa::ModeChanged(
651 const chrome::search::Mode& old_mode,
652 const chrome::search::Mode& new_mode) {
653 [controller_ updateBookmarkBarStateForInstantPreview];
654}
655
[email protected]7d791652010-12-01 16:34:49656void BrowserWindowCocoa::DestroyBrowser() {
657 [controller_ destroyBrowser];
658
659 // at this point the controller is dead (autoreleased), so
660 // make sure we don't try to reference it any more.
661}
662
663NSWindow* BrowserWindowCocoa::window() const {
664 return [controller_ window];
665}
666
[email protected]0ec4898e2011-12-30 21:09:24667void BrowserWindowCocoa::ShowAvatarBubble(WebContents* web_contents,
[email protected]2f733a02011-10-06 15:17:34668 const gfx::Rect& rect) {
[email protected]f5d230b32012-12-11 02:04:11669 NSPoint point = GetPointForBubble(web_contents, rect.right(), rect.bottom());
[email protected]2f733a02011-10-06 15:17:34670
671 // |menu| will automatically release itself on close.
672 AvatarMenuBubbleController* menu =
673 [[AvatarMenuBubbleController alloc] initWithBrowser:browser_
674 anchoredAt:point];
[email protected]51152d6d2011-11-07 01:55:12675 [[menu bubble] setAlignment:info_bubble::kAlignEdgeToAnchorEdge];
[email protected]2f733a02011-10-06 15:17:34676 [menu showWindow:nil];
677}
[email protected]7d2d08152011-10-25 22:58:47678
679void BrowserWindowCocoa::ShowAvatarBubbleFromAvatarButton() {
680 [[controller_ avatarButtonController] showAvatarBubble];
681}
[email protected]f5d230b32012-12-11 02:04:11682
683void BrowserWindowCocoa::ShowPasswordGenerationBubble(
684 const gfx::Rect& rect,
685 const content::PasswordForm& form,
686 autofill::PasswordGenerator* password_generator) {
[email protected]617ee962013-01-29 20:49:12687 WebContents* web_contents =
688 browser_->tab_strip_model()->GetActiveWebContents();
[email protected]f5d230b32012-12-11 02:04:11689 // We want to point to the middle of the rect instead of the right side.
690 NSPoint point = GetPointForBubble(web_contents,
691 rect.x() + rect.width()/2,
692 rect.bottom());
693
694 PasswordGenerationBubbleController* controller =
695 [[PasswordGenerationBubbleController alloc]
696 initWithWindow:browser_->window()->GetNativeWindow()
697 anchoredAt:point
698 renderViewHost:web_contents->GetRenderViewHost()
699 passwordManager:PasswordManager::FromWebContents(web_contents)
700 usingGenerator:password_generator
701 forForm:form];
702 [controller showWindow:nil];
703}