blob: 3c950c52171eb3b2020630d808984a1de2bef64f [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"
10#include "base/message_loop.h"
11#include "base/sys_string_conversions.h"
12#include "chrome/app/chrome_command_ids.h"
13#include "chrome/browser/bookmarks/bookmark_utils.h"
14#include "chrome/browser/download/download_shelf.h"
[email protected]7d791652010-12-01 16:34:4915#include "chrome/browser/prefs/pref_service.h"
[email protected]8ecad5e2010-12-02 21:18:3316#include "chrome/browser/profiles/profile.h"
[email protected]7d791652010-12-01 16:34:4917#include "chrome/browser/ui/browser.h"
18#include "chrome/browser/ui/browser_list.h"
[email protected]7d2d08152011-10-25 22:58:4719#import "chrome/browser/ui/cocoa/browser/avatar_button_controller.h"
[email protected]2f733a02011-10-06 15:17:3420#import "chrome/browser/ui/cocoa/browser/avatar_menu_bubble_controller.h"
[email protected]464f0012011-07-07 02:12:5121#import "chrome/browser/ui/cocoa/browser/edit_search_engine_cocoa_controller.h"
[email protected]7d791652010-12-01 16:34:4922#import "chrome/browser/ui/cocoa/browser_window_controller.h"
[email protected]3a1381d2011-08-26 18:12:1323#import "chrome/browser/ui/cocoa/browser_window_utils.h"
[email protected]7d791652010-12-01 16:34:4924#import "chrome/browser/ui/cocoa/chrome_event_processing_window.h"
[email protected]fa8102292011-01-20 16:21:2325#import "chrome/browser/ui/cocoa/content_settings/collected_cookies_mac.h"
[email protected]7d791652010-12-01 16:34:4926#import "chrome/browser/ui/cocoa/download/download_shelf_controller.h"
[email protected]632983f2011-08-08 22:51:2427#include "chrome/browser/ui/cocoa/find_bar/find_bar_bridge.h"
[email protected]7d791652010-12-01 16:34:4928#import "chrome/browser/ui/cocoa/html_dialog_window_controller.h"
[email protected]51152d6d2011-11-07 01:55:1229#import "chrome/browser/ui/cocoa/info_bubble_view.h"
[email protected]7d791652010-12-01 16:34:4930#import "chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h"
[email protected]a7d83ca2011-03-06 14:41:0731#import "chrome/browser/ui/cocoa/nsmenuitem_additions.h"
[email protected]7d791652010-12-01 16:34:4932#include "chrome/browser/ui/cocoa/restart_browser.h"
33#include "chrome/browser/ui/cocoa/status_bubble_mac.h"
34#include "chrome/browser/ui/cocoa/task_manager_mac.h"
[email protected]8450c4f2011-01-19 22:16:2235#import "chrome/browser/ui/cocoa/toolbar/toolbar_controller.h"
[email protected]7e2514c2011-11-28 20:04:4536#include "chrome/browser/ui/page_info_bubble.h"
[email protected]6a3ec2312010-12-02 19:30:1937#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
[email protected]0bf4dc622011-12-19 06:59:4438#include "chrome/browser/ui/webui/chrome_web_ui.h"
[email protected]7b937362011-10-05 08:28:0739#include "chrome/browser/ui/webui/task_manager_dialog.h"
[email protected]432115822011-07-10 15:52:2740#include "chrome/common/chrome_notification_types.h"
[email protected]7d791652010-12-01 16:34:4941#include "chrome/common/pref_names.h"
[email protected]ad50def52011-10-19 23:17:0742#include "content/public/browser/notification_source.h"
[email protected]8bc38d22011-10-14 20:39:2043#include "content/public/browser/native_web_keyboard_event.h"
[email protected]6c2381d2011-10-19 02:52:5344#include "content/public/browser/notification_details.h"
[email protected]e8558cf22012-01-10 03:10:5145#include "content/public/browser/web_contents.h"
[email protected]7d791652010-12-01 16:34:4946#include "grit/chromium_strings.h"
47#include "grit/generated_resources.h"
[email protected]c051a1b2011-01-21 23:30:1748#include "ui/base/l10n/l10n_util_mac.h"
[email protected]08397d52011-02-05 01:53:3849#include "ui/gfx/rect.h"
[email protected]7d791652010-12-01 16:34:4950
[email protected]d583e3f22011-12-27 21:38:1751using content::SSLStatus;
[email protected]2a6bc3e2011-12-28 23:51:3352using content::WebContents;
[email protected]d583e3f22011-12-27 21:38:1753
[email protected]400eaf82011-08-22 15:47:3954// Replicate specific 10.7 SDK declarations for building with prior SDKs.
55#if !defined(MAC_OS_X_VERSION_10_7) || \
56 MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7
57
58enum {
59 NSWindowAnimationBehaviorDefault = 0,
60 NSWindowAnimationBehaviorNone = 2,
61 NSWindowAnimationBehaviorDocumentWindow = 3,
62 NSWindowAnimationBehaviorUtilityWindow = 4,
63 NSWindowAnimationBehaviorAlertPanel = 5
64};
65typedef NSInteger NSWindowAnimationBehavior;
66
67@interface NSWindow (LionSDKDeclarations)
68- (NSWindowAnimationBehavior)animationBehavior;
69- (void)setAnimationBehavior:(NSWindowAnimationBehavior)newAnimationBehavior;
70@end
71
72#endif // MAC_OS_X_VERSION_10_7
73
[email protected]7d791652010-12-01 16:34:4974BrowserWindowCocoa::BrowserWindowCocoa(Browser* browser,
[email protected]400eaf82011-08-22 15:47:3975 BrowserWindowController* controller)
[email protected]7d791652010-12-01 16:34:4976 : browser_(browser),
77 controller_(controller),
78 confirm_close_factory_(browser) {
[email protected]cfecf9432011-09-27 17:10:0879
[email protected]3710d0002011-10-11 00:35:0080 pref_change_registrar_.Init(browser_->profile()->GetPrefs());
81 pref_change_registrar_.Add(prefs::kShowBookmarkBar, this);
82
[email protected]cfecf9432011-09-27 17:10:0883 initial_show_state_ = browser_->GetSavedWindowShowState();
[email protected]7d791652010-12-01 16:34:4984}
85
86BrowserWindowCocoa::~BrowserWindowCocoa() {
87}
88
89void BrowserWindowCocoa::Show() {
90 // The Browser associated with this browser window must become the active
91 // browser at the time |Show()| is called. This is the natural behaviour under
92 // Windows, but |-makeKeyAndOrderFront:| won't send |-windowDidBecomeMain:|
93 // until we return to the runloop. Therefore any calls to
94 // |BrowserList::GetLastActive()| (for example, in bookmark_util), will return
95 // the previous browser instead if we don't explicitly set it here.
96 BrowserList::SetLastActive(browser_);
97
[email protected]8bc061f2011-08-31 22:46:2398 bool is_session_restore = browser_->is_session_restore();
[email protected]b5cc93c2011-09-02 02:33:4299 NSWindowAnimationBehavior saved_animation_behavior =
100 NSWindowAnimationBehaviorDefault;
[email protected]8bc061f2011-08-31 22:46:23101 bool did_save_animation_behavior = false;
102 // Turn off swishing when restoring windows.
103 if (is_session_restore &&
104 [window() respondsToSelector:@selector(animationBehavior)] &&
105 [window() respondsToSelector:@selector(setAnimationBehavior:)]) {
106 did_save_animation_behavior = true;
107 saved_animation_behavior = [window() animationBehavior];
108 [window() setAnimationBehavior:NSWindowAnimationBehaviorNone];
109 }
[email protected]400eaf82011-08-22 15:47:39110
[email protected]8bc061f2011-08-31 22:46:23111 [window() makeKeyAndOrderFront:controller_];
[email protected]400eaf82011-08-22 15:47:39112
[email protected]8bc061f2011-08-31 22:46:23113 // When creating windows from nibs it is necessary to |makeKeyAndOrderFront:|
114 // prior to |orderOut:| then |miniaturize:| when restoring windows in the
115 // minimized state.
[email protected]cfecf9432011-09-27 17:10:08116 if (initial_show_state_ == ui::SHOW_STATE_MINIMIZED) {
[email protected]400eaf82011-08-22 15:47:39117 [window() orderOut:controller_];
118 [window() miniaturize:controller_];
[email protected]400eaf82011-08-22 15:47:39119 }
[email protected]cfecf9432011-09-27 17:10:08120 initial_show_state_ = ui::SHOW_STATE_DEFAULT;
[email protected]8bc061f2011-08-31 22:46:23121
122 // Restore window animation behavior.
123 if (did_save_animation_behavior)
124 [window() setAnimationBehavior:saved_animation_behavior];
[email protected]2f516c792011-09-19 22:22:09125
126 browser_->OnWindowDidShow();
[email protected]7d791652010-12-01 16:34:49127}
128
[email protected]d4db6c702011-03-28 21:49:14129void BrowserWindowCocoa::ShowInactive() {
[email protected]400eaf82011-08-22 15:47:39130 [window() orderFront:controller_];
[email protected]d4db6c702011-03-28 21:49:14131}
132
[email protected]7d791652010-12-01 16:34:49133void BrowserWindowCocoa::SetBounds(const gfx::Rect& bounds) {
[email protected]ccb5895f2011-06-09 21:16:14134 gfx::Rect real_bounds = [controller_ enforceMinWindowSize:bounds];
135
[email protected]55c87fa2011-10-15 07:28:28136 ExitFullscreen();
[email protected]ccb5895f2011-06-09 21:16:14137 NSRect cocoa_bounds = NSMakeRect(real_bounds.x(), 0,
138 real_bounds.width(),
139 real_bounds.height());
[email protected]7d791652010-12-01 16:34:49140 // Flip coordinates based on the primary screen.
141 NSScreen* screen = [[NSScreen screens] objectAtIndex:0];
142 cocoa_bounds.origin.y =
[email protected]ccb5895f2011-06-09 21:16:14143 [screen frame].size.height - real_bounds.height() - real_bounds.y();
[email protected]7d791652010-12-01 16:34:49144
145 [window() setFrame:cocoa_bounds display:YES];
146}
147
148// Callers assume that this doesn't immediately delete the Browser object.
149// The controller implementing the window delegate methods called from
150// |-performClose:| must take precautions to ensure that.
151void BrowserWindowCocoa::Close() {
152 // If there is an overlay window, we contain a tab being dragged between
153 // windows. Don't hide the window as it makes the UI extra confused. We can
154 // still close the window, as that will happen when the drag completes.
155 if ([controller_ overlayWindow]) {
156 [controller_ deferPerformClose];
157 } else {
158 // Make sure we hide the window immediately. Even though performClose:
159 // calls orderOut: eventually, it leaves the window on-screen long enough
160 // that we start to see tabs shutting down. http://crbug.com/23959
161 // TODO(viettrungluu): This is kind of bad, since |-performClose:| calls
162 // |-windowShouldClose:| (on its delegate, which is probably the
163 // controller) which may return |NO| causing the window to not be closed,
164 // thereby leaving a hidden window. In fact, our window-closing procedure
165 // involves a (indirect) recursion on |-performClose:|, which is also bad.
166 [window() orderOut:controller_];
167 [window() performClose:controller_];
168 }
169}
170
171void BrowserWindowCocoa::Activate() {
172 [controller_ activate];
173}
174
175void BrowserWindowCocoa::Deactivate() {
176 // TODO(jcivelli): http://crbug.com/51364 Implement me.
177 NOTIMPLEMENTED();
178}
179
180void BrowserWindowCocoa::FlashFrame() {
181 [NSApp requestUserAttention:NSInformationalRequest];
182}
183
184bool BrowserWindowCocoa::IsActive() const {
185 return [window() isKeyWindow];
186}
187
188gfx::NativeWindow BrowserWindowCocoa::GetNativeHandle() {
189 return window();
190}
191
192BrowserWindowTesting* BrowserWindowCocoa::GetBrowserWindowTesting() {
193 return NULL;
194}
195
196StatusBubble* BrowserWindowCocoa::GetStatusBubble() {
197 return [controller_ statusBubble];
198}
199
[email protected]c9bd2e82011-04-15 23:28:19200void BrowserWindowCocoa::ToolbarSizeChanged(bool is_animating) {
[email protected]7d791652010-12-01 16:34:49201 // According to beng, this is an ugly method that comes from the days when the
[email protected]e8558cf22012-01-10 03:10:51202 // download shelf was a ChromeView attached to the WebContents, and as its
[email protected]7d791652010-12-01 16:34:49203 // size changed via animation it notified through TCD/etc to the browser view
204 // to relayout for each tick of the animation. We don't need anything of the
205 // sort on Mac.
206}
207
208void BrowserWindowCocoa::UpdateTitleBar() {
209 NSString* newTitle =
210 base::SysUTF16ToNSString(browser_->GetWindowTitleForCurrentTab());
211
[email protected]d78e615e2011-09-06 21:46:03212 pending_window_title_.reset(
213 [BrowserWindowUtils scheduleReplaceOldTitle:pending_window_title_.get()
214 withNewTitle:newTitle
215 forWindow:window()]);
[email protected]7d791652010-12-01 16:34:49216}
217
[email protected]09b29342011-06-24 19:18:48218void BrowserWindowCocoa::BookmarkBarStateChanged(
219 BookmarkBar::AnimateChangeType change_type) {
220 // TODO: route changes to state through this.
[email protected]7d791652010-12-01 16:34:49221}
222
223void BrowserWindowCocoa::UpdateDevTools() {
224 [controller_ updateDevToolsForContents:
[email protected]4ca15302012-01-03 05:53:20225 browser_->GetSelectedWebContents()];
[email protected]7d791652010-12-01 16:34:49226}
227
[email protected]853e16eb2011-12-29 16:58:19228void BrowserWindowCocoa::SetDevToolsDockSide(DevToolsDockSide side) {
229 [controller_ setDevToolsDockToRight:side == DEVTOOLS_DOCK_SIDE_RIGHT];
230}
231
[email protected]7d791652010-12-01 16:34:49232void BrowserWindowCocoa::UpdateLoadingAnimations(bool should_animate) {
233 // Do nothing on Mac.
234}
235
236void BrowserWindowCocoa::SetStarredState(bool is_starred) {
237 [controller_ setStarredState:is_starred ? YES : NO];
238}
239
240gfx::Rect BrowserWindowCocoa::GetRestoredBounds() const {
241 // Flip coordinates based on the primary screen.
242 NSScreen* screen = [[NSScreen screens] objectAtIndex:0];
243 NSRect frame = [controller_ regularWindowFrame];
244 gfx::Rect bounds(frame.origin.x, 0, frame.size.width, frame.size.height);
245 bounds.set_y([screen frame].size.height - frame.origin.y - frame.size.height);
246 return bounds;
247}
248
[email protected]d479b8e22011-02-09 05:19:49249gfx::Rect BrowserWindowCocoa::GetBounds() const {
250 return GetRestoredBounds();
251}
252
[email protected]7d791652010-12-01 16:34:49253bool BrowserWindowCocoa::IsMaximized() const {
254 return [window() isZoomed];
255}
256
[email protected]400eaf82011-08-22 15:47:39257bool BrowserWindowCocoa::IsMinimized() const {
258 return [window() isMiniaturized];
259}
260
[email protected]541e3ee2011-11-22 01:31:10261void BrowserWindowCocoa::Maximize() {
262 // Zoom toggles so only call if not already maximized.
263 if (!IsMaximized())
264 [window() zoom:controller_];
265}
266
267void BrowserWindowCocoa::Minimize() {
268 [window() miniaturize:controller_];
269}
270
271void BrowserWindowCocoa::Restore() {
272 if (IsMaximized())
273 [window() zoom:controller_]; // Toggles zoom mode.
274 else if (IsMinimized())
275 [window() deminiaturize:controller_];
276}
277
[email protected]8d944b32011-10-17 06:11:53278void BrowserWindowCocoa::EnterFullscreen(
[email protected]22d74a6b2011-10-17 20:30:31279 const GURL& url, FullscreenExitBubbleType bubble_type) {
280 [controller_ enterFullscreenForURL:url
281 bubbleType:bubble_type];
[email protected]55c87fa2011-10-15 07:28:28282}
283
284void BrowserWindowCocoa::ExitFullscreen() {
[email protected]22d74a6b2011-10-17 20:30:31285 [controller_ exitFullscreen];
[email protected]8d944b32011-10-17 06:11:53286}
287
288void BrowserWindowCocoa::UpdateFullscreenExitBubbleContent(
289 const GURL& url,
290 FullscreenExitBubbleType bubble_type) {
[email protected]22d74a6b2011-10-17 20:30:31291 [controller_ updateFullscreenExitBubbleURL:url bubbleType:bubble_type];
[email protected]7d791652010-12-01 16:34:49292}
293
294bool BrowserWindowCocoa::IsFullscreen() const {
[email protected]8d944b32011-10-17 06:11:53295 return [controller_ isFullscreen];
[email protected]7d791652010-12-01 16:34:49296}
297
298bool BrowserWindowCocoa::IsFullscreenBubbleVisible() const {
299 return false;
300}
301
302void BrowserWindowCocoa::ConfirmAddSearchProvider(
303 const TemplateURL* template_url,
304 Profile* profile) {
[email protected]464f0012011-07-07 02:12:51305 // The controller will release itself when the window closes.
306 EditSearchEngineCocoaController* editor =
307 [[EditSearchEngineCocoaController alloc] initWithProfile:profile
308 delegate:NULL
309 templateURL:template_url];
310 [NSApp beginSheet:[editor window]
311 modalForWindow:window()
312 modalDelegate:controller_
313 didEndSelector:@selector(sheetDidEnd:returnCode:context:)
314 contextInfo:NULL];
[email protected]7d791652010-12-01 16:34:49315}
316
317LocationBar* BrowserWindowCocoa::GetLocationBar() const {
318 return [controller_ locationBarBridge];
319}
320
321void BrowserWindowCocoa::SetFocusToLocationBar(bool select_all) {
322 [controller_ focusLocationBar:select_all ? YES : NO];
323}
324
325void BrowserWindowCocoa::UpdateReloadStopState(bool is_loading, bool force) {
326 [controller_ setIsLoading:is_loading force:force];
327}
328
329void BrowserWindowCocoa::UpdateToolbar(TabContentsWrapper* contents,
330 bool should_restore_state) {
[email protected]83a2610a2012-01-05 01:00:27331 [controller_ updateToolbarWithContents:contents->web_contents()
[email protected]7d791652010-12-01 16:34:49332 shouldRestoreState:should_restore_state ? YES : NO];
333}
334
335void BrowserWindowCocoa::FocusToolbar() {
336 // Not needed on the Mac.
337}
338
339void BrowserWindowCocoa::FocusAppMenu() {
340 // Chrome uses the standard Mac OS X menu bar, so this isn't needed.
341}
342
343void BrowserWindowCocoa::RotatePaneFocus(bool forwards) {
344 // Not needed on the Mac.
345}
346
347void BrowserWindowCocoa::FocusBookmarksToolbar() {
348 // Not needed on the Mac.
349}
350
351void BrowserWindowCocoa::FocusChromeOSStatus() {
352 // Not needed on the Mac.
353}
354
355bool BrowserWindowCocoa::IsBookmarkBarVisible() const {
[email protected]a007e732011-08-05 13:32:19356 return browser_->profile()->GetPrefs()->GetBoolean(prefs::kShowBookmarkBar);
[email protected]7d791652010-12-01 16:34:49357}
358
359bool BrowserWindowCocoa::IsBookmarkBarAnimating() const {
360 return [controller_ isBookmarkBarAnimating];
361}
362
[email protected]95bf8a5b2010-12-22 16:04:07363bool BrowserWindowCocoa::IsTabStripEditable() const {
364 return ![controller_ isDragSessionActive];
365}
366
[email protected]7d791652010-12-01 16:34:49367bool BrowserWindowCocoa::IsToolbarVisible() const {
368 return browser_->SupportsWindowFeature(Browser::FEATURE_TOOLBAR) ||
369 browser_->SupportsWindowFeature(Browser::FEATURE_LOCATIONBAR);
370}
371
372// This is called from Browser, which in turn is called directly from
373// a menu option. All we do here is set a preference. The act of
374// setting the preference sends notifications to all windows who then
375// know what to do.
376void BrowserWindowCocoa::ToggleBookmarkBar() {
377 bookmark_utils::ToggleWhenVisible(browser_->profile());
378}
379
380void BrowserWindowCocoa::AddFindBar(
381 FindBarCocoaController* find_bar_cocoa_controller) {
[email protected]632983f2011-08-08 22:51:24382 [controller_ addFindBar:find_bar_cocoa_controller];
[email protected]7d791652010-12-01 16:34:49383}
384
[email protected]4c6b474b72011-02-24 21:35:21385void BrowserWindowCocoa::ShowAboutChromeDialog() {
[email protected]287b90602011-03-02 22:43:27386 // Go through AppController's implementation to bring up the branded panel.
387 [[NSApp delegate] orderFrontStandardAboutPanel:nil];
[email protected]7d791652010-12-01 16:34:49388}
389
390void BrowserWindowCocoa::ShowUpdateChromeDialog() {
[email protected]678dae82011-02-11 20:03:08391 restart_browser::RequestRestart(window());
[email protected]7d791652010-12-01 16:34:49392}
393
394void BrowserWindowCocoa::ShowTaskManager() {
[email protected]7b937362011-10-05 08:28:07395#if defined(WEBUI_TASK_MANAGER)
396 TaskManagerDialog::Show();
397#else
398 // Uses WebUI TaskManager when swiches is set. It is beta feature.
[email protected]21e6caf82012-01-06 23:44:20399 if (chrome_web_ui::IsMoreWebUI()) {
[email protected]7b937362011-10-05 08:28:07400 TaskManagerDialog::Show();
401 } else {
402 TaskManagerMac::Show(false);
403 }
404#endif // defined(WEBUI_TASK_MANAGER)
[email protected]adb6a84d2011-02-07 16:58:40405}
406
407void BrowserWindowCocoa::ShowBackgroundPages() {
[email protected]7b937362011-10-05 08:28:07408#if defined(WEBUI_TASK_MANAGER)
409 TaskManagerDialog::ShowBackgroundPages();
410#else
411 // Uses WebUI TaskManager when swiches is set. It is beta feature.
[email protected]21e6caf82012-01-06 23:44:20412 if (chrome_web_ui::IsMoreWebUI()) {
[email protected]7b937362011-10-05 08:28:07413 TaskManagerDialog::ShowBackgroundPages();
414 } else {
415 TaskManagerMac::Show(true);
416 }
417#endif // defined(WEBUI_TASK_MANAGER)
[email protected]7d791652010-12-01 16:34:49418}
419
420void BrowserWindowCocoa::ShowBookmarkBubble(const GURL& url,
421 bool already_bookmarked) {
422 [controller_ showBookmarkBubbleForURL:url
423 alreadyBookmarked:(already_bookmarked ? YES : NO)];
424}
425
426bool BrowserWindowCocoa::IsDownloadShelfVisible() const {
427 return [controller_ isDownloadShelfVisible] != NO;
428}
429
430DownloadShelf* BrowserWindowCocoa::GetDownloadShelf() {
431 DownloadShelfController* shelfController = [controller_ downloadShelf];
432 return [shelfController bridge];
433}
434
[email protected]a3627e62011-09-07 00:04:57435void BrowserWindowCocoa::ShowCollectedCookiesDialog(
436 TabContentsWrapper* wrapper) {
[email protected]7d791652010-12-01 16:34:49437 // Deletes itself on close.
[email protected]a3627e62011-09-07 00:04:57438 new CollectedCookiesMac(GetNativeHandle(), wrapper);
[email protected]7d791652010-12-01 16:34:49439}
440
[email protected]7d791652010-12-01 16:34:49441// We allow closing the window here since the real quit decision on Mac is made
442// in [AppController quit:].
443void BrowserWindowCocoa::ConfirmBrowserCloseWithPendingDownloads() {
444 // Call InProgressDownloadResponse asynchronously to avoid a crash when the
445 // browser window is closed here (http://crbug.com/44454).
[email protected]a932d9e2011-09-29 01:14:34446 MessageLoop::current()->PostTask(FROM_HERE,
447 base::Bind(&Browser::InProgressDownloadResponse,
448 confirm_close_factory_.GetWeakPtr(), true));
[email protected]7d791652010-12-01 16:34:49449}
450
[email protected]7d791652010-12-01 16:34:49451void BrowserWindowCocoa::UserChangedTheme() {
452 [controller_ userChangedTheme];
453}
454
455int BrowserWindowCocoa::GetExtraRenderViewHeight() const {
456 // Currently this is only used on linux.
457 return 0;
458}
459
[email protected]2a6bc3e2011-12-28 23:51:33460void BrowserWindowCocoa::WebContentsFocused(WebContents* contents) {
[email protected]7d791652010-12-01 16:34:49461 NOTIMPLEMENTED();
462}
463
464void BrowserWindowCocoa::ShowPageInfo(Profile* profile,
465 const GURL& url,
[email protected]d583e3f22011-12-27 21:38:17466 const SSLStatus& ssl,
[email protected]7d791652010-12-01 16:34:49467 bool show_history) {
468 browser::ShowPageInfoBubble(window(), profile, url, ssl, show_history);
469}
470
471void BrowserWindowCocoa::ShowAppMenu() {
472 // No-op. Mac doesn't support showing the menus via alt keys.
473}
474
475bool BrowserWindowCocoa::PreHandleKeyboardEvent(
476 const NativeWebKeyboardEvent& event, bool* is_keyboard_shortcut) {
[email protected]3a1381d2011-08-26 18:12:13477 if (![BrowserWindowUtils shouldHandleKeyboardEvent:event])
[email protected]7d791652010-12-01 16:34:49478 return false;
479
[email protected]3a1381d2011-08-26 18:12:13480 int id = [BrowserWindowUtils getCommandId:event];
[email protected]7d791652010-12-01 16:34:49481 if (id == -1)
482 return false;
483
[email protected]3a1381d2011-08-26 18:12:13484 if (browser_->IsReservedCommandOrKey(id, event)) {
485 return [BrowserWindowUtils handleKeyboardEvent:event.os_event
486 inWindow:window()];
487 }
[email protected]7d791652010-12-01 16:34:49488
[email protected]3a1381d2011-08-26 18:12:13489 DCHECK(is_keyboard_shortcut);
[email protected]7d791652010-12-01 16:34:49490 *is_keyboard_shortcut = true;
[email protected]7d791652010-12-01 16:34:49491 return false;
492}
493
494void BrowserWindowCocoa::HandleKeyboardEvent(
495 const NativeWebKeyboardEvent& event) {
[email protected]3a1381d2011-08-26 18:12:13496 if ([BrowserWindowUtils shouldHandleKeyboardEvent:event])
497 [BrowserWindowUtils handleKeyboardEvent:event.os_event inWindow:window()];
[email protected]7d791652010-12-01 16:34:49498}
499
500void BrowserWindowCocoa::ShowCreateWebAppShortcutsDialog(
[email protected]f847e6082011-03-24 00:08:26501 TabContentsWrapper* tab_contents) {
[email protected]7d791652010-12-01 16:34:49502 NOTIMPLEMENTED();
503}
504
505void BrowserWindowCocoa::ShowCreateChromeAppShortcutsDialog(
506 Profile* profile, const Extension* app) {
507 NOTIMPLEMENTED();
508}
509
510void BrowserWindowCocoa::Cut() {
511 [NSApp sendAction:@selector(cut:) to:nil from:nil];
512}
513
514void BrowserWindowCocoa::Copy() {
515 [NSApp sendAction:@selector(copy:) to:nil from:nil];
516}
517
518void BrowserWindowCocoa::Paste() {
519 [NSApp sendAction:@selector(paste:) to:nil from:nil];
520}
521
[email protected]7d791652010-12-01 16:34:49522void BrowserWindowCocoa::OpenTabpose() {
523 [controller_ openTabpose];
524}
525
[email protected]8d944b32011-10-17 06:11:53526void BrowserWindowCocoa::EnterPresentationMode(
527 const GURL& url,
528 FullscreenExitBubbleType bubble_type) {
[email protected]22d74a6b2011-10-17 20:30:31529 [controller_ enterPresentationModeForURL:url
530 bubbleType:bubble_type];
[email protected]8d944b32011-10-17 06:11:53531}
532
533void BrowserWindowCocoa::ExitPresentationMode() {
[email protected]22d74a6b2011-10-17 20:30:31534 [controller_ exitPresentationMode];
[email protected]d3766932011-08-04 22:18:23535}
536
537bool BrowserWindowCocoa::InPresentationMode() {
538 return [controller_ inPresentationMode];
539}
540
[email protected]e3690ed2011-03-25 20:25:14541void BrowserWindowCocoa::ShowInstant(TabContentsWrapper* preview) {
[email protected]83a2610a2012-01-05 01:00:27542 [controller_ showInstant:preview->web_contents()];
[email protected]7d791652010-12-01 16:34:49543}
544
[email protected]3e481282011-10-15 15:39:50545void BrowserWindowCocoa::HideInstant() {
[email protected]7d791652010-12-01 16:34:49546 [controller_ hideInstant];
[email protected]7d791652010-12-01 16:34:49547}
548
549gfx::Rect BrowserWindowCocoa::GetInstantBounds() {
550 // Flip coordinates based on the primary screen.
551 NSScreen* screen = [[NSScreen screens] objectAtIndex:0];
552 NSRect monitorFrame = [screen frame];
553 NSRect frame = [controller_ instantFrame];
554 gfx::Rect bounds(NSRectToCGRect(frame));
555 bounds.set_y(NSHeight(monitorFrame) - bounds.y() - bounds.height());
556 return bounds;
557}
558
[email protected]588300d2011-04-28 21:06:35559WindowOpenDisposition BrowserWindowCocoa::GetDispositionForPopupBounds(
560 const gfx::Rect& bounds) {
561 return NEW_POPUP;
562}
563
[email protected]632983f2011-08-08 22:51:24564FindBar* BrowserWindowCocoa::CreateFindBar() {
565 // We could push the AddFindBar() call into the FindBarBridge
566 // constructor or the FindBarCocoaController init, but that makes
567 // unit testing difficult, since we would also require a
568 // BrowserWindow object.
569 FindBarBridge* bridge = new FindBarBridge();
570 AddFindBar(bridge->find_bar_cocoa_controller());
571 return bridge;
572}
573
[email protected]432115822011-07-10 15:52:27574void BrowserWindowCocoa::Observe(int type,
[email protected]6c2381d2011-10-19 02:52:53575 const content::NotificationSource& source,
576 const content::NotificationDetails& details) {
[email protected]432115822011-07-10 15:52:27577 switch (type) {
[email protected]3710d0002011-10-11 00:35:00578 case chrome::NOTIFICATION_PREF_CHANGED: {
[email protected]7ac4b872011-10-19 03:30:42579 const std::string& pref_name =
580 *content::Details<std::string>(details).ptr();
[email protected]3710d0002011-10-11 00:35:00581 DCHECK(pref_name == prefs::kShowBookmarkBar);
582 [controller_ updateBookmarkBarVisibilityWithAnimation:YES];
[email protected]7d791652010-12-01 16:34:49583 break;
[email protected]3710d0002011-10-11 00:35:00584 }
[email protected]7d791652010-12-01 16:34:49585 default:
586 NOTREACHED(); // we don't ask for anything else!
587 break;
588 }
589}
590
591void BrowserWindowCocoa::DestroyBrowser() {
592 [controller_ destroyBrowser];
593
594 // at this point the controller is dead (autoreleased), so
595 // make sure we don't try to reference it any more.
596}
597
598NSWindow* BrowserWindowCocoa::window() const {
599 return [controller_ window];
600}
601
[email protected]0ec4898e2011-12-30 21:09:24602void BrowserWindowCocoa::ShowAvatarBubble(WebContents* web_contents,
[email protected]2f733a02011-10-06 15:17:34603 const gfx::Rect& rect) {
[email protected]0ec4898e2011-12-30 21:09:24604 NSView* view = web_contents->GetNativeView();
[email protected]79ac3cb2011-10-12 17:11:21605 NSRect bounds = [view bounds];
606 NSPoint point;
607 point.x = NSMinX(bounds) + rect.right();
608 // The view's origin is at the bottom but |rect|'s origin is at the top.
609 point.y = NSMaxY(bounds) - rect.bottom();
[email protected]2f733a02011-10-06 15:17:34610 point = [view convertPoint:point toView:nil];
611 point = [[view window] convertBaseToScreen:point];
612
613 // |menu| will automatically release itself on close.
614 AvatarMenuBubbleController* menu =
615 [[AvatarMenuBubbleController alloc] initWithBrowser:browser_
616 anchoredAt:point];
[email protected]51152d6d2011-11-07 01:55:12617 [[menu bubble] setAlignment:info_bubble::kAlignEdgeToAnchorEdge];
[email protected]2f733a02011-10-06 15:17:34618 [menu showWindow:nil];
619}
[email protected]7d2d08152011-10-25 22:58:47620
621void BrowserWindowCocoa::ShowAvatarBubbleFromAvatarButton() {
622 [[controller_ avatarButtonController] showAvatarBubble];
623}