blob: dae17190d7b995c12042459314642b0a0ae053dd [file] [log] [blame]
[email protected]35d06152011-01-10 22:19:421// Copyright (c) 2011 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]7d791652010-12-01 16:34:497#include "base/command_line.h"
8#include "base/logging.h"
9#include "base/message_loop.h"
10#include "base/sys_string_conversions.h"
11#include "chrome/app/chrome_command_ids.h"
12#include "chrome/browser/bookmarks/bookmark_utils.h"
13#include "chrome/browser/download/download_shelf.h"
14#include "chrome/browser/global_keyboard_shortcuts_mac.h"
15#include "chrome/browser/page_info_window.h"
16#include "chrome/browser/prefs/pref_service.h"
[email protected]8ecad5e2010-12-02 21:18:3317#include "chrome/browser/profiles/profile.h"
[email protected]7d791652010-12-01 16:34:4918#include "chrome/browser/sidebar/sidebar_container.h"
19#include "chrome/browser/sidebar/sidebar_manager.h"
[email protected]7d791652010-12-01 16:34:4920#include "chrome/browser/ui/browser.h"
21#include "chrome/browser/ui/browser_list.h"
22#import "chrome/browser/ui/cocoa/browser_window_controller.h"
23#import "chrome/browser/ui/cocoa/bug_report_window_controller.h"
24#import "chrome/browser/ui/cocoa/chrome_event_processing_window.h"
25#import "chrome/browser/ui/cocoa/clear_browsing_data_controller.h"
[email protected]fa8102292011-01-20 16:21:2326#import "chrome/browser/ui/cocoa/content_settings/collected_cookies_mac.h"
[email protected]7d791652010-12-01 16:34:4927#import "chrome/browser/ui/cocoa/download/download_shelf_controller.h"
[email protected]7d791652010-12-01 16:34:4928#import "chrome/browser/ui/cocoa/html_dialog_window_controller.h"
[email protected]a7d83ca2011-03-06 14:41:0729#import "chrome/browser/ui/cocoa/importer/import_dialog_cocoa.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]463194f2011-01-14 22:36:3632#import "chrome/browser/ui/cocoa/options/content_settings_dialog_controller.h"
33#import "chrome/browser/ui/cocoa/options/edit_search_engine_cocoa_controller.h"
34#import "chrome/browser/ui/cocoa/options/keyword_editor_cocoa_controller.h"
[email protected]7d791652010-12-01 16:34:4935#include "chrome/browser/ui/cocoa/repost_form_warning_mac.h"
36#include "chrome/browser/ui/cocoa/restart_browser.h"
37#include "chrome/browser/ui/cocoa/status_bubble_mac.h"
38#include "chrome/browser/ui/cocoa/task_manager_mac.h"
39#import "chrome/browser/ui/cocoa/theme_install_bubble_view.h"
[email protected]8450c4f2011-01-19 22:16:2240#import "chrome/browser/ui/cocoa/toolbar/toolbar_controller.h"
[email protected]6a3ec2312010-12-02 19:30:1941#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
[email protected]7d791652010-12-01 16:34:4942#include "chrome/common/native_web_keyboard_event.h"
43#include "chrome/common/notification_service.h"
44#include "chrome/common/pref_names.h"
[email protected]21f11682011-03-02 16:45:4245#include "content/browser/tab_contents/tab_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
51BrowserWindowCocoa::BrowserWindowCocoa(Browser* browser,
52 BrowserWindowController* controller,
53 NSWindow* window)
54 : browser_(browser),
55 controller_(controller),
56 confirm_close_factory_(browser) {
57 // This pref applies to all windows, so all must watch for it.
58 registrar_.Add(this, NotificationType::BOOKMARK_BAR_VISIBILITY_PREF_CHANGED,
59 NotificationService::AllSources());
60 registrar_.Add(this, NotificationType::SIDEBAR_CHANGED,
61 NotificationService::AllSources());
62}
63
64BrowserWindowCocoa::~BrowserWindowCocoa() {
65}
66
67void BrowserWindowCocoa::Show() {
68 // The Browser associated with this browser window must become the active
69 // browser at the time |Show()| is called. This is the natural behaviour under
70 // Windows, but |-makeKeyAndOrderFront:| won't send |-windowDidBecomeMain:|
71 // until we return to the runloop. Therefore any calls to
72 // |BrowserList::GetLastActive()| (for example, in bookmark_util), will return
73 // the previous browser instead if we don't explicitly set it here.
74 BrowserList::SetLastActive(browser_);
75
76 [window() makeKeyAndOrderFront:controller_];
77}
78
79void BrowserWindowCocoa::SetBounds(const gfx::Rect& bounds) {
[email protected]d479b8e22011-02-09 05:19:4980 SetFullscreen(false);
[email protected]7d791652010-12-01 16:34:4981 NSRect cocoa_bounds = NSMakeRect(bounds.x(), 0, bounds.width(),
82 bounds.height());
83 // Flip coordinates based on the primary screen.
84 NSScreen* screen = [[NSScreen screens] objectAtIndex:0];
85 cocoa_bounds.origin.y =
86 [screen frame].size.height - bounds.height() - bounds.y();
87
88 [window() setFrame:cocoa_bounds display:YES];
89}
90
91// Callers assume that this doesn't immediately delete the Browser object.
92// The controller implementing the window delegate methods called from
93// |-performClose:| must take precautions to ensure that.
94void BrowserWindowCocoa::Close() {
95 // If there is an overlay window, we contain a tab being dragged between
96 // windows. Don't hide the window as it makes the UI extra confused. We can
97 // still close the window, as that will happen when the drag completes.
98 if ([controller_ overlayWindow]) {
99 [controller_ deferPerformClose];
100 } else {
101 // Make sure we hide the window immediately. Even though performClose:
102 // calls orderOut: eventually, it leaves the window on-screen long enough
103 // that we start to see tabs shutting down. http://crbug.com/23959
104 // TODO(viettrungluu): This is kind of bad, since |-performClose:| calls
105 // |-windowShouldClose:| (on its delegate, which is probably the
106 // controller) which may return |NO| causing the window to not be closed,
107 // thereby leaving a hidden window. In fact, our window-closing procedure
108 // involves a (indirect) recursion on |-performClose:|, which is also bad.
109 [window() orderOut:controller_];
110 [window() performClose:controller_];
111 }
112}
113
114void BrowserWindowCocoa::Activate() {
115 [controller_ activate];
116}
117
118void BrowserWindowCocoa::Deactivate() {
119 // TODO(jcivelli): http://crbug.com/51364 Implement me.
120 NOTIMPLEMENTED();
121}
122
123void BrowserWindowCocoa::FlashFrame() {
124 [NSApp requestUserAttention:NSInformationalRequest];
125}
126
127bool BrowserWindowCocoa::IsActive() const {
128 return [window() isKeyWindow];
129}
130
131gfx::NativeWindow BrowserWindowCocoa::GetNativeHandle() {
132 return window();
133}
134
135BrowserWindowTesting* BrowserWindowCocoa::GetBrowserWindowTesting() {
136 return NULL;
137}
138
139StatusBubble* BrowserWindowCocoa::GetStatusBubble() {
140 return [controller_ statusBubble];
141}
142
143void BrowserWindowCocoa::SelectedTabToolbarSizeChanged(bool is_animating) {
144 // According to beng, this is an ugly method that comes from the days when the
145 // download shelf was a ChromeView attached to the TabContents, and as its
146 // size changed via animation it notified through TCD/etc to the browser view
147 // to relayout for each tick of the animation. We don't need anything of the
148 // sort on Mac.
149}
150
151void BrowserWindowCocoa::UpdateTitleBar() {
152 NSString* newTitle =
153 base::SysUTF16ToNSString(browser_->GetWindowTitleForCurrentTab());
154
155 // Work around Cocoa bug: if a window changes title during the tracking of the
156 // Window menu it doesn't display well and the constant re-sorting of the list
157 // makes it difficult for the user to pick the desired window. Delay window
158 // title updates until the default run-loop mode.
159
160 if (pending_window_title_.get())
161 [[NSRunLoop currentRunLoop]
162 cancelPerformSelector:@selector(setTitle:)
163 target:window()
164 argument:pending_window_title_.get()];
165
166 pending_window_title_.reset([newTitle copy]);
167 [[NSRunLoop currentRunLoop]
168 performSelector:@selector(setTitle:)
169 target:window()
170 argument:newTitle
171 order:0
172 modes:[NSArray arrayWithObject:NSDefaultRunLoopMode]];
173}
174
175void BrowserWindowCocoa::ShelfVisibilityChanged() {
176 // Mac doesn't yet support showing the bookmark bar at a different size on
177 // the new tab page. When it does, this method should attempt to relayout the
178 // bookmark bar/extension shelf as their preferred height may have changed.
179 // http://crbug.com/43346
180}
181
182void BrowserWindowCocoa::UpdateDevTools() {
183 [controller_ updateDevToolsForContents:
184 browser_->GetSelectedTabContents()];
185}
186
187void BrowserWindowCocoa::UpdateLoadingAnimations(bool should_animate) {
188 // Do nothing on Mac.
189}
190
191void BrowserWindowCocoa::SetStarredState(bool is_starred) {
192 [controller_ setStarredState:is_starred ? YES : NO];
193}
194
195gfx::Rect BrowserWindowCocoa::GetRestoredBounds() const {
196 // Flip coordinates based on the primary screen.
197 NSScreen* screen = [[NSScreen screens] objectAtIndex:0];
198 NSRect frame = [controller_ regularWindowFrame];
199 gfx::Rect bounds(frame.origin.x, 0, frame.size.width, frame.size.height);
200 bounds.set_y([screen frame].size.height - frame.origin.y - frame.size.height);
201 return bounds;
202}
203
[email protected]d479b8e22011-02-09 05:19:49204gfx::Rect BrowserWindowCocoa::GetBounds() const {
205 return GetRestoredBounds();
206}
207
[email protected]7d791652010-12-01 16:34:49208bool BrowserWindowCocoa::IsMaximized() const {
209 return [window() isZoomed];
210}
211
212void BrowserWindowCocoa::SetFullscreen(bool fullscreen) {
213 [controller_ setFullscreen:fullscreen];
214}
215
216bool BrowserWindowCocoa::IsFullscreen() const {
217 return !![controller_ isFullscreen];
218}
219
220bool BrowserWindowCocoa::IsFullscreenBubbleVisible() const {
221 return false;
222}
223
224void BrowserWindowCocoa::ConfirmAddSearchProvider(
225 const TemplateURL* template_url,
226 Profile* profile) {
227 // The controller will release itself when the window closes.
228 EditSearchEngineCocoaController* editor =
229 [[EditSearchEngineCocoaController alloc] initWithProfile:profile
230 delegate:NULL
231 templateURL:template_url];
232 [NSApp beginSheet:[editor window]
233 modalForWindow:window()
234 modalDelegate:controller_
235 didEndSelector:@selector(sheetDidEnd:returnCode:context:)
236 contextInfo:NULL];
237}
238
239LocationBar* BrowserWindowCocoa::GetLocationBar() const {
240 return [controller_ locationBarBridge];
241}
242
243void BrowserWindowCocoa::SetFocusToLocationBar(bool select_all) {
244 [controller_ focusLocationBar:select_all ? YES : NO];
245}
246
247void BrowserWindowCocoa::UpdateReloadStopState(bool is_loading, bool force) {
248 [controller_ setIsLoading:is_loading force:force];
249}
250
251void BrowserWindowCocoa::UpdateToolbar(TabContentsWrapper* contents,
252 bool should_restore_state) {
253 [controller_ updateToolbarWithContents:contents->tab_contents()
254 shouldRestoreState:should_restore_state ? YES : NO];
255}
256
257void BrowserWindowCocoa::FocusToolbar() {
258 // Not needed on the Mac.
259}
260
261void BrowserWindowCocoa::FocusAppMenu() {
262 // Chrome uses the standard Mac OS X menu bar, so this isn't needed.
263}
264
265void BrowserWindowCocoa::RotatePaneFocus(bool forwards) {
266 // Not needed on the Mac.
267}
268
269void BrowserWindowCocoa::FocusBookmarksToolbar() {
270 // Not needed on the Mac.
271}
272
273void BrowserWindowCocoa::FocusChromeOSStatus() {
274 // Not needed on the Mac.
275}
276
277bool BrowserWindowCocoa::IsBookmarkBarVisible() const {
278 return browser_->profile()->GetPrefs()->GetBoolean(prefs::kShowBookmarkBar);
279}
280
281bool BrowserWindowCocoa::IsBookmarkBarAnimating() const {
282 return [controller_ isBookmarkBarAnimating];
283}
284
[email protected]95bf8a5b2010-12-22 16:04:07285bool BrowserWindowCocoa::IsTabStripEditable() const {
286 return ![controller_ isDragSessionActive];
287}
288
[email protected]7d791652010-12-01 16:34:49289bool BrowserWindowCocoa::IsToolbarVisible() const {
290 return browser_->SupportsWindowFeature(Browser::FEATURE_TOOLBAR) ||
291 browser_->SupportsWindowFeature(Browser::FEATURE_LOCATIONBAR);
292}
293
294// This is called from Browser, which in turn is called directly from
295// a menu option. All we do here is set a preference. The act of
296// setting the preference sends notifications to all windows who then
297// know what to do.
298void BrowserWindowCocoa::ToggleBookmarkBar() {
299 bookmark_utils::ToggleWhenVisible(browser_->profile());
300}
301
302void BrowserWindowCocoa::AddFindBar(
303 FindBarCocoaController* find_bar_cocoa_controller) {
304 return [controller_ addFindBar:find_bar_cocoa_controller];
305}
306
[email protected]4c6b474b72011-02-24 21:35:21307void BrowserWindowCocoa::ShowAboutChromeDialog() {
[email protected]287b90602011-03-02 22:43:27308 // Go through AppController's implementation to bring up the branded panel.
309 [[NSApp delegate] orderFrontStandardAboutPanel:nil];
[email protected]7d791652010-12-01 16:34:49310}
311
312void BrowserWindowCocoa::ShowUpdateChromeDialog() {
[email protected]678dae82011-02-11 20:03:08313 restart_browser::RequestRestart(window());
[email protected]7d791652010-12-01 16:34:49314}
315
316void BrowserWindowCocoa::ShowTaskManager() {
[email protected]adb6a84d2011-02-07 16:58:40317 TaskManagerMac::Show(false);
318}
319
320void BrowserWindowCocoa::ShowBackgroundPages() {
321 TaskManagerMac::Show(true);
[email protected]7d791652010-12-01 16:34:49322}
323
324void BrowserWindowCocoa::ShowBookmarkBubble(const GURL& url,
325 bool already_bookmarked) {
326 [controller_ showBookmarkBubbleForURL:url
327 alreadyBookmarked:(already_bookmarked ? YES : NO)];
328}
329
330bool BrowserWindowCocoa::IsDownloadShelfVisible() const {
331 return [controller_ isDownloadShelfVisible] != NO;
332}
333
334DownloadShelf* BrowserWindowCocoa::GetDownloadShelf() {
335 DownloadShelfController* shelfController = [controller_ downloadShelf];
336 return [shelfController bridge];
337}
338
[email protected]7d791652010-12-01 16:34:49339void BrowserWindowCocoa::ShowClearBrowsingDataDialog() {
340 [ClearBrowsingDataController
341 showClearBrowsingDialogForProfile:browser_->profile()];
342}
343
344void BrowserWindowCocoa::ShowImportDialog() {
[email protected]a7d83ca2011-03-06 14:41:07345 [ImportDialogController
[email protected]7d791652010-12-01 16:34:49346 showImportSettingsDialogForProfile:browser_->profile()];
347}
348
349void BrowserWindowCocoa::ShowSearchEnginesDialog() {
350 [KeywordEditorCocoaController showKeywordEditor:browser_->profile()];
351}
352
353void BrowserWindowCocoa::ShowPasswordManager() {
354 NOTIMPLEMENTED();
355}
356
357void BrowserWindowCocoa::ShowRepostFormWarningDialog(
358 TabContents* tab_contents) {
359 RepostFormWarningMac::Create(GetNativeHandle(), tab_contents);
360}
361
362void BrowserWindowCocoa::ShowContentSettingsWindow(
363 ContentSettingsType settings_type,
364 Profile* profile) {
365 [ContentSettingsDialogController showContentSettingsForType:settings_type
366 profile:profile];
367}
368
369void BrowserWindowCocoa::ShowCollectedCookiesDialog(TabContents* tab_contents) {
370 // Deletes itself on close.
371 new CollectedCookiesMac(GetNativeHandle(), tab_contents);
372}
373
374void BrowserWindowCocoa::ShowProfileErrorDialog(int message_id) {
375 scoped_nsobject<NSAlert> alert([[NSAlert alloc] init]);
376 [alert addButtonWithTitle:l10n_util::GetNSStringWithFixup(IDS_OK)];
377 [alert setMessageText:l10n_util::GetNSStringWithFixup(IDS_PRODUCT_NAME)];
378 [alert setInformativeText:l10n_util::GetNSStringWithFixup(message_id)];
379 [alert setAlertStyle:NSWarningAlertStyle];
380 [alert runModal];
381}
382
383void BrowserWindowCocoa::ShowThemeInstallBubble() {
384 ThemeInstallBubbleView::Show(window());
385}
386
387// We allow closing the window here since the real quit decision on Mac is made
388// in [AppController quit:].
389void BrowserWindowCocoa::ConfirmBrowserCloseWithPendingDownloads() {
390 // Call InProgressDownloadResponse asynchronously to avoid a crash when the
391 // browser window is closed here (http://crbug.com/44454).
392 MessageLoop::current()->PostTask(
393 FROM_HERE,
394 confirm_close_factory_.NewRunnableMethod(
395 &Browser::InProgressDownloadResponse,
396 true));
397}
398
399void BrowserWindowCocoa::ShowHTMLDialog(HtmlDialogUIDelegate* delegate,
400 gfx::NativeWindow parent_window) {
401 [HtmlDialogWindowController showHtmlDialog:delegate
402 profile:browser_->profile()];
403}
404
405void BrowserWindowCocoa::UserChangedTheme() {
406 [controller_ userChangedTheme];
407}
408
409int BrowserWindowCocoa::GetExtraRenderViewHeight() const {
410 // Currently this is only used on linux.
411 return 0;
412}
413
414void BrowserWindowCocoa::TabContentsFocused(TabContents* tab_contents) {
415 NOTIMPLEMENTED();
416}
417
418void BrowserWindowCocoa::ShowPageInfo(Profile* profile,
419 const GURL& url,
420 const NavigationEntry::SSLStatus& ssl,
421 bool show_history) {
422 browser::ShowPageInfoBubble(window(), profile, url, ssl, show_history);
423}
424
425void BrowserWindowCocoa::ShowAppMenu() {
426 // No-op. Mac doesn't support showing the menus via alt keys.
427}
428
429bool BrowserWindowCocoa::PreHandleKeyboardEvent(
430 const NativeWebKeyboardEvent& event, bool* is_keyboard_shortcut) {
431 if (event.skip_in_browser || event.type == NativeWebKeyboardEvent::Char)
432 return false;
433
434 DCHECK(event.os_event != NULL);
435 int id = GetCommandId(event);
436 if (id == -1)
437 return false;
438
[email protected]06181422011-02-09 17:44:21439 if (browser_->IsReservedCommandOrKey(id, event))
[email protected]7d791652010-12-01 16:34:49440 return HandleKeyboardEventInternal(event.os_event);
441
442 DCHECK(is_keyboard_shortcut != NULL);
443 *is_keyboard_shortcut = true;
444
445 return false;
446}
447
448void BrowserWindowCocoa::HandleKeyboardEvent(
449 const NativeWebKeyboardEvent& event) {
450 if (event.skip_in_browser || event.type == NativeWebKeyboardEvent::Char)
451 return;
452
453 DCHECK(event.os_event != NULL);
454 HandleKeyboardEventInternal(event.os_event);
455}
456
457@interface MenuWalker : NSObject
458+ (NSMenuItem*)itemForKeyEquivalent:(NSEvent*)key
459 menu:(NSMenu*)menu;
460@end
461
462@implementation MenuWalker
463+ (NSMenuItem*)itemForKeyEquivalent:(NSEvent*)key
464 menu:(NSMenu*)menu {
465 NSMenuItem* result = nil;
466
467 for (NSMenuItem *item in [menu itemArray]) {
468 NSMenu* submenu = [item submenu];
469 if (submenu) {
470 if (submenu != [NSApp servicesMenu])
471 result = [self itemForKeyEquivalent:key
472 menu:submenu];
[email protected]0f72a2dc2010-12-06 19:40:23473 } else if ([item cr_firesForKeyEventIfEnabled:key]) {
[email protected]7d791652010-12-01 16:34:49474 result = item;
475 }
476
477 if (result)
478 break;
479 }
480
481 return result;
482}
483@end
484
485int BrowserWindowCocoa::GetCommandId(const NativeWebKeyboardEvent& event) {
486 if ([event.os_event type] != NSKeyDown)
487 return -1;
488
489 // Look in menu.
490 NSMenuItem* item = [MenuWalker itemForKeyEquivalent:event.os_event
491 menu:[NSApp mainMenu]];
492
493 if (item && [item action] == @selector(commandDispatch:) && [item tag] > 0)
494 return [item tag];
495
496 // "Close window" doesn't use the |commandDispatch:| mechanism. Menu items
497 // that do not correspond to IDC_ constants need no special treatment however,
[email protected]06181422011-02-09 17:44:21498 // as they can't be blacklisted in |Browser::IsReservedCommandOrKey()| anyhow.
[email protected]7d791652010-12-01 16:34:49499 if (item && [item action] == @selector(performClose:))
500 return IDC_CLOSE_WINDOW;
501
502 // "Exit" doesn't use the |commandDispatch:| mechanism either.
503 if (item && [item action] == @selector(terminate:))
504 return IDC_EXIT;
505
506 // Look in secondary keyboard shortcuts.
507 NSUInteger modifiers = [event.os_event modifierFlags];
508 const bool cmdKey = (modifiers & NSCommandKeyMask) != 0;
509 const bool shiftKey = (modifiers & NSShiftKeyMask) != 0;
510 const bool cntrlKey = (modifiers & NSControlKeyMask) != 0;
511 const bool optKey = (modifiers & NSAlternateKeyMask) != 0;
512 const int keyCode = [event.os_event keyCode];
513 const unichar keyChar = KeyCharacterForEvent(event.os_event);
514
515 int cmdNum = CommandForWindowKeyboardShortcut(
516 cmdKey, shiftKey, cntrlKey, optKey, keyCode, keyChar);
517 if (cmdNum != -1)
518 return cmdNum;
519
520 cmdNum = CommandForBrowserKeyboardShortcut(
521 cmdKey, shiftKey, cntrlKey, optKey, keyCode, keyChar);
522 if (cmdNum != -1)
523 return cmdNum;
524
525 return -1;
526}
527
528bool BrowserWindowCocoa::HandleKeyboardEventInternal(NSEvent* event) {
529 ChromeEventProcessingWindow* event_window =
530 static_cast<ChromeEventProcessingWindow*>(window());
531 DCHECK([event_window isKindOfClass:[ChromeEventProcessingWindow class]]);
532
533 // Do not fire shortcuts on key up.
534 if ([event type] == NSKeyDown) {
535 // Send the event to the menu before sending it to the browser/window
536 // shortcut handling, so that if a user configures cmd-left to mean
537 // "previous tab", it takes precedence over the built-in "history back"
538 // binding. Other than that, the |-redispatchKeyEvent:| call would take care
539 // of invoking the original menu item shortcut as well.
540
541 if ([[NSApp mainMenu] performKeyEquivalent:event])
542 return true;
543
544 if ([event_window handleExtraBrowserKeyboardShortcut:event])
545 return true;
546
547 if ([event_window handleExtraWindowKeyboardShortcut:event])
548 return true;
549
550 if ([event_window handleDelayedWindowKeyboardShortcut:event])
551 return true;
552 }
553
554 return [event_window redispatchKeyEvent:event];
555}
556
557void BrowserWindowCocoa::ShowCreateWebAppShortcutsDialog(
558 TabContents* tab_contents) {
559 NOTIMPLEMENTED();
560}
561
562void BrowserWindowCocoa::ShowCreateChromeAppShortcutsDialog(
563 Profile* profile, const Extension* app) {
564 NOTIMPLEMENTED();
565}
566
567void BrowserWindowCocoa::Cut() {
568 [NSApp sendAction:@selector(cut:) to:nil from:nil];
569}
570
571void BrowserWindowCocoa::Copy() {
572 [NSApp sendAction:@selector(copy:) to:nil from:nil];
573}
574
575void BrowserWindowCocoa::Paste() {
576 [NSApp sendAction:@selector(paste:) to:nil from:nil];
577}
578
579void BrowserWindowCocoa::ToggleTabStripMode() {
580 [controller_ toggleTabStripDisplayMode];
581}
582
583void BrowserWindowCocoa::OpenTabpose() {
584 [controller_ openTabpose];
585}
586
587void BrowserWindowCocoa::PrepareForInstant() {
588 // TODO: implement fade as done on windows.
589}
590
591void BrowserWindowCocoa::ShowInstant(TabContents* preview_contents) {
592 [controller_ showInstant:preview_contents];
593}
594
[email protected]1946c932010-12-15 00:07:38595void BrowserWindowCocoa::HideInstant(bool instant_is_active) {
[email protected]7d791652010-12-01 16:34:49596 [controller_ hideInstant];
[email protected]1946c932010-12-15 00:07:38597
598 // TODO: add support for |instant_is_active|.
[email protected]7d791652010-12-01 16:34:49599}
600
601gfx::Rect BrowserWindowCocoa::GetInstantBounds() {
602 // Flip coordinates based on the primary screen.
603 NSScreen* screen = [[NSScreen screens] objectAtIndex:0];
604 NSRect monitorFrame = [screen frame];
605 NSRect frame = [controller_ instantFrame];
606 gfx::Rect bounds(NSRectToCGRect(frame));
607 bounds.set_y(NSHeight(monitorFrame) - bounds.y() - bounds.height());
608 return bounds;
609}
610
[email protected]7d791652010-12-01 16:34:49611void BrowserWindowCocoa::Observe(NotificationType type,
612 const NotificationSource& source,
613 const NotificationDetails& details) {
614 switch (type.value) {
615 // Only the key window gets a direct toggle from the menu.
616 // Other windows hear about it from the notification.
617 case NotificationType::BOOKMARK_BAR_VISIBILITY_PREF_CHANGED:
618 [controller_ updateBookmarkBarVisibilityWithAnimation:YES];
619 break;
620 case NotificationType::SIDEBAR_CHANGED:
621 UpdateSidebarForContents(
622 Details<SidebarContainer>(details)->tab_contents());
623 break;
624 default:
625 NOTREACHED(); // we don't ask for anything else!
626 break;
627 }
628}
629
630void BrowserWindowCocoa::DestroyBrowser() {
631 [controller_ destroyBrowser];
632
633 // at this point the controller is dead (autoreleased), so
634 // make sure we don't try to reference it any more.
635}
636
637NSWindow* BrowserWindowCocoa::window() const {
638 return [controller_ window];
639}
640
641void BrowserWindowCocoa::UpdateSidebarForContents(TabContents* tab_contents) {
642 if (tab_contents == browser_->GetSelectedTabContents()) {
643 [controller_ updateSidebarForContents:tab_contents];
644 }
645}