| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/ui/panels/panel_window_controller_cocoa.h" | 5 #include "chrome/browser/ui/panels/panel_window_controller_cocoa.h" |
| 6 | 6 |
| 7 #import <Cocoa/Cocoa.h> | 7 #import <Cocoa/Cocoa.h> |
| 8 | 8 |
| 9 #include "base/auto_reset.h" | 9 #include "base/auto_reset.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "base/mac/bundle_locations.h" | 11 #include "base/mac/bundle_locations.h" |
| 12 #include "base/mac/mac_util.h" | 12 #include "base/mac/mac_util.h" |
| 13 #include "base/mac/scoped_nsautorelease_pool.h" | 13 #include "base/mac/scoped_nsautorelease_pool.h" |
| 14 #include "base/sys_string_conversions.h" | 14 #include "base/sys_string_conversions.h" |
| 15 #include "chrome/app/chrome_command_ids.h" // IDC_* | 15 #include "chrome/app/chrome_command_ids.h" // IDC_* |
| 16 #include "chrome/browser/chrome_browser_application_mac.h" | 16 #include "chrome/browser/chrome_browser_application_mac.h" |
| 17 #include "chrome/browser/profiles/profile.h" | 17 #include "chrome/browser/profiles/profile.h" |
| 18 #include "chrome/browser/themes/theme_service.h" | 18 #include "chrome/browser/themes/theme_service.h" |
| 19 #include "chrome/browser/themes/theme_service_factory.h" | 19 #include "chrome/browser/themes/theme_service_factory.h" |
| 20 #import "chrome/browser/ui/cocoa/browser_command_executor.h" |
| 20 #import "chrome/browser/ui/cocoa/browser_window_utils.h" | 21 #import "chrome/browser/ui/cocoa/browser_window_utils.h" |
| 21 #import "chrome/browser/ui/cocoa/event_utils.h" | 22 #import "chrome/browser/ui/cocoa/event_utils.h" |
| 22 #import "chrome/browser/ui/cocoa/find_bar/find_bar_bridge.h" | |
| 23 #import "chrome/browser/ui/cocoa/find_bar/find_bar_cocoa_controller.h" | |
| 24 #import "chrome/browser/ui/cocoa/menu_controller.h" | 23 #import "chrome/browser/ui/cocoa/menu_controller.h" |
| 25 #import "chrome/browser/ui/cocoa/tab_contents/favicon_util_mac.h" | 24 #import "chrome/browser/ui/cocoa/tab_contents/favicon_util_mac.h" |
| 26 #import "chrome/browser/ui/cocoa/tab_contents/tab_contents_controller.h" | 25 #import "chrome/browser/ui/cocoa/tab_contents/tab_contents_controller.h" |
| 27 #import "chrome/browser/ui/cocoa/tabs/throbber_view.h" | 26 #import "chrome/browser/ui/cocoa/tabs/throbber_view.h" |
| 28 #include "chrome/browser/ui/panels/native_panel_cocoa.h" | |
| 29 #include "chrome/browser/ui/panels/panel_bounds_animation.h" | 27 #include "chrome/browser/ui/panels/panel_bounds_animation.h" |
| 28 #include "chrome/browser/ui/panels/panel_cocoa.h" |
| 30 #include "chrome/browser/ui/panels/panel_constants.h" | 29 #include "chrome/browser/ui/panels/panel_constants.h" |
| 31 #include "chrome/browser/ui/panels/panel_manager.h" | 30 #include "chrome/browser/ui/panels/panel_manager.h" |
| 32 #include "chrome/browser/ui/panels/panel_strip.h" | 31 #include "chrome/browser/ui/panels/panel_strip.h" |
| 33 #import "chrome/browser/ui/panels/panel_titlebar_view_cocoa.h" | 32 #import "chrome/browser/ui/panels/panel_titlebar_view_cocoa.h" |
| 34 #import "chrome/browser/ui/panels/panel_utils_cocoa.h" | 33 #import "chrome/browser/ui/panels/panel_utils_cocoa.h" |
| 35 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 34 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
| 36 #include "chrome/browser/ui/toolbar/encoding_menu_controller.h" | 35 #include "chrome/browser/ui/toolbar/encoding_menu_controller.h" |
| 37 #include "content/public/browser/render_widget_host_view.h" | 36 #include "content/public/browser/render_widget_host_view.h" |
| 38 #include "content/public/browser/web_contents.h" | 37 #include "content/public/browser/web_contents.h" |
| 39 #include "third_party/WebKit/Source/WebKit/chromium/public/WebCursorInfo.h" | 38 #include "third_party/WebKit/Source/WebKit/chromium/public/WebCursorInfo.h" |
| (...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 407 bottomRightCursorRect_.origin.y = NSMinY(bounds); | 406 bottomRightCursorRect_.origin.y = NSMinY(bounds); |
| 408 [self addCursorRect:bottomRightCursorRect_ cursor:northWestSouthEastCursor_]; | 407 [self addCursorRect:bottomRightCursorRect_ cursor:northWestSouthEastCursor_]; |
| 409 | 408 |
| 410 // Bottom left corner. | 409 // Bottom left corner. |
| 411 bottomLeftCursorRect_ = bottomRightCursorRect_; | 410 bottomLeftCursorRect_ = bottomRightCursorRect_; |
| 412 bottomLeftCursorRect_.origin.x = NSMinX(bounds); | 411 bottomLeftCursorRect_.origin.x = NSMinX(bounds); |
| 413 [self addCursorRect:bottomLeftCursorRect_ cursor:northEastSouthWestCursor_]; | 412 [self addCursorRect:bottomLeftCursorRect_ cursor:northEastSouthWestCursor_]; |
| 414 } | 413 } |
| 415 @end | 414 @end |
| 416 | 415 |
| 416 // ChromeEventProcessingWindow expects its controller to implement the |
| 417 // BrowserCommandExecutor protocol. |
| 418 @interface PanelWindowControllerCocoa (InternalAPI) <BrowserCommandExecutor> |
| 419 |
| 420 // BrowserCommandExecutor methods. |
| 421 - (void)executeCommand:(int)command; |
| 422 |
| 423 @end |
| 424 |
| 425 @implementation PanelWindowControllerCocoa (InternalAPI) |
| 426 |
| 427 // This gets called whenever a browser-specific keyboard shortcut is performed |
| 428 // in the Panel window. We simply swallow all those events. |
| 429 - (void)executeCommand:(int)command {} |
| 430 |
| 431 @end |
| 432 |
| 417 @implementation PanelWindowControllerCocoa | 433 @implementation PanelWindowControllerCocoa |
| 418 | 434 |
| 419 - (id)initWithPanel:(NativePanelCocoa*)window { | 435 - (id)initWithPanel:(PanelCocoa*)window { |
| 420 NSString* nibpath = | 436 NSString* nibpath = |
| 421 [base::mac::FrameworkBundle() pathForResource:@"Panel" ofType:@"nib"]; | 437 [base::mac::FrameworkBundle() pathForResource:@"Panel" ofType:@"nib"]; |
| 422 if ((self = [super initWithWindowNibPath:nibpath owner:self])) { | 438 if ((self = [super initWithWindowNibPath:nibpath owner:self])) { |
| 423 windowShim_.reset(window); | 439 windowShim_.reset(window); |
| 424 animateOnBoundsChange_ = YES; | 440 animateOnBoundsChange_ = YES; |
| 425 canBecomeKeyWindow_ = YES; | 441 canBecomeKeyWindow_ = YES; |
| 426 activationRequestedByPanel_ = NO; | 442 activationRequestedByPanel_ = NO; |
| 427 contentsController_.reset( | 443 contentsController_.reset( |
| 428 [[TabContentsController alloc] initWithContents:nil]); | 444 [[TabContentsController alloc] initWithContents:nil]); |
| 429 } | 445 } |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 585 | 601 |
| 586 [self updateIcon]; | 602 [self updateIcon]; |
| 587 } | 603 } |
| 588 | 604 |
| 589 - (void)updateTitleBarMinimizeRestoreButtonVisibility { | 605 - (void)updateTitleBarMinimizeRestoreButtonVisibility { |
| 590 Panel* panel = windowShim_->panel(); | 606 Panel* panel = windowShim_->panel(); |
| 591 [titlebar_view_ setMinimizeButtonVisibility:panel->CanMinimize()]; | 607 [titlebar_view_ setMinimizeButtonVisibility:panel->CanMinimize()]; |
| 592 [titlebar_view_ setRestoreButtonVisibility:panel->CanRestore()]; | 608 [titlebar_view_ setRestoreButtonVisibility:panel->CanRestore()]; |
| 593 } | 609 } |
| 594 | 610 |
| 595 - (void)addFindBar:(FindBarCocoaController*)findBarCocoaController { | |
| 596 NSView* contentView = [[self window] contentView]; | |
| 597 [contentView addSubview:[findBarCocoaController view]]; | |
| 598 | |
| 599 CGFloat maxY = NSMaxY([contentView frame]); | |
| 600 CGFloat maxWidth = NSWidth([contentView frame]); | |
| 601 [findBarCocoaController positionFindBarViewAtMaxY:maxY maxWidth:maxWidth]; | |
| 602 } | |
| 603 | |
| 604 - (void)webContentsInserted:(WebContents*)contents { | 611 - (void)webContentsInserted:(WebContents*)contents { |
| 605 [contentsController_ changeWebContents:contents]; | 612 [contentsController_ changeWebContents:contents]; |
| 606 DCHECK(![[contentsController_ view] isHidden]); | 613 DCHECK(![[contentsController_ view] isHidden]); |
| 607 } | 614 } |
| 608 | 615 |
| 609 - (void)webContentsDetached:(WebContents*)contents { | 616 - (void)webContentsDetached:(WebContents*)contents { |
| 610 DCHECK(contents == [contentsController_ webContents]); | 617 DCHECK(contents == [contentsController_ webContents]); |
| 611 [contentsController_ changeWebContents:nil]; | 618 [contentsController_ changeWebContents:nil]; |
| 612 [[contentsController_ view] setHidden:YES]; | 619 [[contentsController_ view] setHidden:YES]; |
| 613 } | 620 } |
| 614 | 621 |
| 615 - (PanelTitlebarViewCocoa*)titlebarView { | 622 - (PanelTitlebarViewCocoa*)titlebarView { |
| 616 return titlebar_view_; | 623 return titlebar_view_; |
| 617 } | 624 } |
| 618 | 625 |
| 619 // Called to validate menu and toolbar items when this window is key. All the | 626 // Called to validate menu and toolbar items when this window is key. All the |
| 620 // items we care about have been set with the |-commandDispatch:| or | 627 // items we care about have been set with the |-commandDispatch:| or |
| 621 // |-commandDispatchUsingKeyModifiers:| actions and a target of FirstResponder | 628 // |-commandDispatchUsingKeyModifiers:| actions and a target of FirstResponder |
| 622 // in IB. If it's not one of those, let it continue up the responder chain to be | 629 // in IB. If it's not one of those, let it continue up the responder chain to be |
| 623 // handled elsewhere. | 630 // handled elsewhere. |
| 624 - (BOOL)validateUserInterfaceItem:(id<NSValidatedUserInterfaceItem>)item { | 631 - (BOOL)validateUserInterfaceItem:(id<NSValidatedUserInterfaceItem>)item { |
| 625 SEL action = [item action]; | 632 SEL action = [item action]; |
| 626 BOOL enable = NO; | 633 BOOL enable = NO; |
| 627 if (action == @selector(commandDispatch:) || | 634 if (action == @selector(commandDispatch:) || |
| 628 action == @selector(commandDispatchUsingKeyModifiers:)) { | 635 action == @selector(commandDispatchUsingKeyModifiers:)) { |
| 629 NSInteger tag = [item tag]; | 636 NSInteger tag = [item tag]; |
| 630 CommandUpdater* command_updater = | 637 CommandUpdater* command_updater = windowShim_->panel()->command_updater(); |
| 631 windowShim_->panel()->command_updater(); | |
| 632 if (command_updater->SupportsCommand(tag)) { | 638 if (command_updater->SupportsCommand(tag)) { |
| 633 enable = command_updater->IsCommandEnabled(tag); | 639 enable = command_updater->IsCommandEnabled(tag); |
| 634 // Disable commands that do not apply to Panels. | 640 // Special handling for the contents of the Text Encoding submenu. On |
| 635 switch (tag) { | 641 // Mac OS, instead of enabling/disabling the top-level menu item, we |
| 636 case IDC_CLOSE_TAB: | 642 // enable/disable the submenu's contents (per Apple's HIG). |
| 637 case IDC_FULLSCREEN: | 643 EncodingMenuController encoding_controller; |
| 638 case IDC_PRESENTATION_MODE: | 644 if (encoding_controller.DoesCommandBelongToEncodingMenu(tag)) { |
| 639 case IDC_SHOW_SYNC_SETUP: | 645 enable &= command_updater->IsCommandEnabled(IDC_ENCODING_MENU) ? |
| 640 enable = NO; | 646 YES : NO; |
| 641 break; | |
| 642 default: | |
| 643 // Special handling for the contents of the Text Encoding submenu. On | |
| 644 // Mac OS, instead of enabling/disabling the top-level menu item, we | |
| 645 // enable/disable the submenu's contents (per Apple's HIG). | |
| 646 EncodingMenuController encoding_controller; | |
| 647 if (encoding_controller.DoesCommandBelongToEncodingMenu(tag)) { | |
| 648 enable &= command_updater->IsCommandEnabled(IDC_ENCODING_MENU) ? | |
| 649 YES : NO; | |
| 650 } | |
| 651 } | 647 } |
| 652 } | 648 } |
| 653 } | 649 } |
| 654 return enable; | 650 return enable; |
| 655 } | 651 } |
| 656 | 652 |
| 657 // Called when the user picks a menu or toolbar item when this window is key. | 653 // Called when the user picks a menu or toolbar item when this window is key. |
| 658 // Calls through to the panel object to execute the command. This assumes that | 654 // Calls through to the panel object to execute the command. This assumes that |
| 659 // the command is supported and doesn't check, otherwise it would have been | 655 // the command is supported and doesn't check, otherwise it would have been |
| 660 // disabled in the UI in validateUserInterfaceItem:. | 656 // disabled in the UI in validateUserInterfaceItem:. |
| 661 - (void)commandDispatch:(id)sender { | 657 - (void)commandDispatch:(id)sender { |
| 662 DCHECK(sender); | 658 DCHECK(sender); |
| 663 windowShim_->panel()->ExecuteCommandWithDisposition([sender tag], | 659 windowShim_->panel()->ExecuteCommandWithDisposition([sender tag], |
| 664 CURRENT_TAB); | 660 CURRENT_TAB); |
| 665 } | 661 } |
| 666 | 662 |
| 667 // Same as |-commandDispatch:|, but executes commands using a disposition | 663 // Same as |-commandDispatch:|, but executes commands using a disposition |
| 668 // determined by the key flags. | 664 // determined by the key flags. |
| 669 - (void)commandDispatchUsingKeyModifiers:(id)sender { | 665 - (void)commandDispatchUsingKeyModifiers:(id)sender { |
| 670 DCHECK(sender); | 666 DCHECK(sender); |
| 671 NSEvent* event = [NSApp currentEvent]; | 667 NSEvent* event = [NSApp currentEvent]; |
| 672 WindowOpenDisposition disposition = | 668 WindowOpenDisposition disposition = |
| 673 event_utils::WindowOpenDispositionFromNSEventWithFlags( | 669 event_utils::WindowOpenDispositionFromNSEventWithFlags( |
| 674 event, [event modifierFlags]); | 670 event, [event modifierFlags]); |
| 675 windowShim_->panel()->ExecuteCommandWithDisposition( | 671 windowShim_->panel()->ExecuteCommandWithDisposition( |
| 676 [sender tag], disposition); | 672 [sender tag], disposition); |
| 677 } | 673 } |
| 678 | 674 |
| 679 - (void)executeCommand:(int)command { | |
| 680 windowShim_->panel()->ExecuteCommandIfEnabled(command); | |
| 681 } | |
| 682 | |
| 683 // Handler for the custom Close button. | 675 // Handler for the custom Close button. |
| 684 - (void)closePanel { | 676 - (void)closePanel { |
| 685 windowShim_->panel()->Close(); | 677 windowShim_->panel()->Close(); |
| 686 } | 678 } |
| 687 | 679 |
| 688 // Handler for the custom Minimize button. | 680 // Handler for the custom Minimize button. |
| 689 - (void)minimizeButtonClicked:(int)modifierFlags { | 681 - (void)minimizeButtonClicked:(int)modifierFlags { |
| 690 Panel* panel = windowShim_->panel(); | 682 Panel* panel = windowShim_->panel(); |
| 691 panel->OnMinimizeButtonClicked((modifierFlags & NSShiftKeyMask) ? | 683 panel->OnMinimizeButtonClicked((modifierFlags & NSShiftKeyMask) ? |
| 692 panel::APPLY_TO_ALL : panel::NO_MODIFIER); | 684 panel::APPLY_TO_ALL : panel::NO_MODIFIER); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 729 } | 721 } |
| 730 | 722 |
| 731 // When windowShouldClose returns YES (or if controller receives direct 'close' | 723 // When windowShouldClose returns YES (or if controller receives direct 'close' |
| 732 // signal), window will be unconditionally closed. Clean up. | 724 // signal), window will be unconditionally closed. Clean up. |
| 733 - (void)windowWillClose:(NSNotification*)notification { | 725 - (void)windowWillClose:(NSNotification*)notification { |
| 734 DCHECK(!windowShim_->panel()->GetWebContents()); | 726 DCHECK(!windowShim_->panel()->GetWebContents()); |
| 735 // Avoid callbacks from a nonblocking animation in progress, if any. | 727 // Avoid callbacks from a nonblocking animation in progress, if any. |
| 736 [self terminateBoundsAnimation]; | 728 [self terminateBoundsAnimation]; |
| 737 windowShim_->DidCloseNativeWindow(); | 729 windowShim_->DidCloseNativeWindow(); |
| 738 // Call |-autorelease| after a zero-length delay to avoid deadlock from | 730 // Call |-autorelease| after a zero-length delay to avoid deadlock from |
| 739 // code in the current run loop that waits on BROWSER_CLOSED notification. | 731 // code in the current run loop that waits on PANEL_CLOSED notification. |
| 740 // The notification is sent when this object is freed, but this object | 732 // The notification is sent when this object is freed, but this object |
| 741 // cannot be freed until the current run loop completes. | 733 // cannot be freed until the current run loop completes. |
| 742 [self performSelector:@selector(autorelease) | 734 [self performSelector:@selector(autorelease) |
| 743 withObject:nil | 735 withObject:nil |
| 744 afterDelay:0]; | 736 afterDelay:0]; |
| 745 } | 737 } |
| 746 | 738 |
| 747 - (void)startDrag:(NSPoint)mouseLocation { | 739 - (void)startDrag:(NSPoint)mouseLocation { |
| 748 // Convert from Cocoa's screen coordinates to platform-indepedent screen | 740 // Convert from Cocoa's screen coordinates to platform-indepedent screen |
| 749 // coordinates because PanelManager method takes platform-indepedent screen | 741 // coordinates because PanelManager method takes platform-indepedent screen |
| (...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1027 - (NSRect)contentRectForFrameRect:(NSRect)frameRect { | 1019 - (NSRect)contentRectForFrameRect:(NSRect)frameRect { |
| 1028 NSRect contentRect = [[[self window] contentView] convertRect:frameRect | 1020 NSRect contentRect = [[[self window] contentView] convertRect:frameRect |
| 1029 fromView:nil]; | 1021 fromView:nil]; |
| 1030 contentRect.size.height -= panel::kTitlebarHeight; | 1022 contentRect.size.height -= panel::kTitlebarHeight; |
| 1031 if (contentRect.size.height < 0) | 1023 if (contentRect.size.height < 0) |
| 1032 contentRect.size.height = 0; | 1024 contentRect.size.height = 0; |
| 1033 return contentRect; | 1025 return contentRect; |
| 1034 } | 1026 } |
| 1035 | 1027 |
| 1036 @end | 1028 @end |
| OLD | NEW |