| 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" | |
| 10 #include "base/logging.h" | 9 #include "base/logging.h" |
| 11 #include "base/mac/bundle_locations.h" | 10 #include "base/mac/bundle_locations.h" |
| 12 #include "base/mac/mac_util.h" | 11 #include "base/mac/mac_util.h" |
| 13 #include "base/mac/scoped_nsautorelease_pool.h" | 12 #include "base/mac/scoped_nsautorelease_pool.h" |
| 14 #include "base/sys_string_conversions.h" | 13 #include "base/sys_string_conversions.h" |
| 15 #include "base/time.h" | |
| 16 #include "chrome/app/chrome_command_ids.h" // IDC_* | 14 #include "chrome/app/chrome_command_ids.h" // IDC_* |
| 17 #include "chrome/browser/chrome_browser_application_mac.h" | 15 #include "chrome/browser/chrome_browser_application_mac.h" |
| 18 #include "chrome/browser/profiles/profile.h" | 16 #include "chrome/browser/profiles/profile.h" |
| 19 #include "chrome/browser/tabs/tab_strip_model.h" | 17 #include "chrome/browser/tabs/tab_strip_model.h" |
| 20 #include "chrome/browser/themes/theme_service.h" | 18 #include "chrome/browser/themes/theme_service.h" |
| 21 #include "chrome/browser/themes/theme_service_factory.h" | 19 #include "chrome/browser/themes/theme_service_factory.h" |
| 22 #include "chrome/browser/ui/browser.h" | 20 #include "chrome/browser/ui/browser.h" |
| 23 #include "chrome/browser/ui/browser_list.h" | 21 #include "chrome/browser/ui/browser_list.h" |
| 24 #import "chrome/browser/ui/cocoa/browser_window_utils.h" | 22 #import "chrome/browser/ui/cocoa/browser_window_utils.h" |
| 25 #import "chrome/browser/ui/cocoa/event_utils.h" | 23 #import "chrome/browser/ui/cocoa/event_utils.h" |
| 26 #import "chrome/browser/ui/cocoa/find_bar/find_bar_bridge.h" | 24 #import "chrome/browser/ui/cocoa/find_bar/find_bar_bridge.h" |
| 27 #import "chrome/browser/ui/cocoa/find_bar/find_bar_cocoa_controller.h" | 25 #import "chrome/browser/ui/cocoa/find_bar/find_bar_cocoa_controller.h" |
| 28 #import "chrome/browser/ui/cocoa/menu_controller.h" | 26 #import "chrome/browser/ui/cocoa/menu_controller.h" |
| 29 #import "chrome/browser/ui/cocoa/tab_contents/favicon_util.h" | 27 #import "chrome/browser/ui/cocoa/tab_contents/favicon_util.h" |
| 30 #import "chrome/browser/ui/cocoa/tab_contents/tab_contents_controller.h" | 28 #import "chrome/browser/ui/cocoa/tab_contents/tab_contents_controller.h" |
| 31 #import "chrome/browser/ui/cocoa/tabs/throbber_view.h" | 29 #import "chrome/browser/ui/cocoa/tabs/throbber_view.h" |
| 32 #include "chrome/browser/ui/panels/panel_bounds_animation.h" | 30 #include "chrome/browser/ui/panels/panel_bounds_animation.h" |
| 33 #include "chrome/browser/ui/panels/panel_browser_window_cocoa.h" | 31 #include "chrome/browser/ui/panels/panel_browser_window_cocoa.h" |
| 34 #include "chrome/browser/ui/panels/panel_manager.h" | 32 #include "chrome/browser/ui/panels/panel_manager.h" |
| 35 #include "chrome/browser/ui/panels/panel_strip.h" | 33 #include "chrome/browser/ui/panels/panel_strip.h" |
| 36 #import "chrome/browser/ui/panels/panel_titlebar_view_cocoa.h" | 34 #import "chrome/browser/ui/panels/panel_titlebar_view_cocoa.h" |
| 37 #import "chrome/browser/ui/panels/panel_utils_cocoa.h" | 35 #import "chrome/browser/ui/panels/panel_utils_cocoa.h" |
| 38 #include "chrome/browser/ui/toolbar/encoding_menu_controller.h" | 36 #include "chrome/browser/ui/toolbar/encoding_menu_controller.h" |
| 39 #include "chrome/common/chrome_notification_types.h" | |
| 40 #include "content/public/browser/notification_service.h" | |
| 41 #include "content/public/browser/render_widget_host_view.h" | 37 #include "content/public/browser/render_widget_host_view.h" |
| 42 #include "content/public/browser/web_contents.h" | 38 #include "content/public/browser/web_contents.h" |
| 43 #include "grit/ui_resources.h" | 39 #include "grit/ui_resources.h" |
| 44 #include "ui/base/resource/resource_bundle.h" | 40 #include "ui/base/resource/resource_bundle.h" |
| 45 #include "ui/gfx/image/image.h" | 41 #include "ui/gfx/image/image.h" |
| 46 #include "ui/gfx/mac/nsimage_cache.h" | 42 #include "ui/gfx/mac/nsimage_cache.h" |
| 47 | 43 |
| 48 using content::WebContents; | 44 using content::WebContents; |
| 49 | 45 |
| 50 const int kMinimumWindowSize = 1; | 46 const int kMinimumWindowSize = 1; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 77 // The panels cannot be reduced to 3-px windows on the edge of the screen | 73 // The panels cannot be reduced to 3-px windows on the edge of the screen |
| 78 // active area (above Dock). Default constraining logic makes at least a height | 74 // active area (above Dock). Default constraining logic makes at least a height |
| 79 // of the titlebar visible, so the user could still grab it. We do 'restore' | 75 // of the titlebar visible, so the user could still grab it. We do 'restore' |
| 80 // differently, and minimize panels to 3 px. Hence the need to override the | 76 // differently, and minimize panels to 3 px. Hence the need to override the |
| 81 // constraining logic. | 77 // constraining logic. |
| 82 - (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen { | 78 - (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen { |
| 83 return frameRect; | 79 return frameRect; |
| 84 } | 80 } |
| 85 | 81 |
| 86 // Prevent panel window from becoming key - for example when it is minimized. | 82 // Prevent panel window from becoming key - for example when it is minimized. |
| 83 // Panel windows use a higher priority NSWindowLevel to ensure they are always |
| 84 // visible, causing the OS to prefer panel windows when selecting a window |
| 85 // to make the key window. To counter this preference, we override |
| 86 // -[NSWindow:canBecomeKeyWindow] to restrict when the panel can become the |
| 87 // key window to a limited set of scenarios, such as when cycling through |
| 88 // windows, when panels are the only remaining windows, when an event |
| 89 // triggers window activation, etc. The panel may also be prevented from |
| 90 // becoming the key window, regardless of the above scenarios, such as when |
| 91 // a panel is minimized. |
| 87 - (BOOL)canBecomeKeyWindow { | 92 - (BOOL)canBecomeKeyWindow { |
| 88 // Give precedence to controller preventing activation of the window. | 93 // Give precedence to controller preventing activation of the window. |
| 89 PanelWindowControllerCocoa* controller = | 94 PanelWindowControllerCocoa* controller = |
| 90 base::mac::ObjCCast<PanelWindowControllerCocoa>([self windowController]); | 95 base::mac::ObjCCast<PanelWindowControllerCocoa>([self windowController]); |
| 91 if (![controller canBecomeKeyWindow]) | 96 if (![controller canBecomeKeyWindow]) |
| 92 return false; | 97 return NO; |
| 93 | 98 |
| 94 BrowserCrApplication* app = base::mac::ObjCCast<BrowserCrApplication>( | 99 BrowserCrApplication* app = base::mac::ObjCCast<BrowserCrApplication>( |
| 95 [BrowserCrApplication sharedApplication]); | 100 [BrowserCrApplication sharedApplication]); |
| 96 | 101 |
| 97 // A Panel window can become the key window only in limited scenarios. | 102 // A Panel window can become the key window only in limited scenarios. |
| 98 // This prevents the system from always preferring a Panel window due | 103 // This prevents the system from always preferring a Panel window due |
| 99 // to its higher priority NSWindowLevel when selecting a window to make key. | 104 // to its higher priority NSWindowLevel when selecting a window to make key. |
| 100 return canBecomeKey_ || | 105 return ([app isHandlingSendEvent] && [[app currentEvent] window] == self) || |
| 101 [controller activationRequestedByBrowser] || | 106 [controller activationRequestedByBrowser] || |
| 102 [app isCyclingWindows] || | 107 [app isCyclingWindows] || |
| 103 [app previousKeyWindow] == self || | 108 [app previousKeyWindow] == self || |
| 104 [[app windows] count] == static_cast<NSUInteger>([controller numPanels]); | 109 [[app windows] count] == static_cast<NSUInteger>([controller numPanels]); |
| 105 } | 110 } |
| 106 | |
| 107 - (void)sendEvent:(NSEvent*)anEvent { | |
| 108 // Allow the panel to become key in response to a mouse click. | |
| 109 AutoReset<BOOL> pin(&canBecomeKey_, YES); | |
| 110 [super sendEvent:anEvent]; | |
| 111 } | |
| 112 @end | 111 @end |
| 113 | 112 |
| 114 // Transparent view covering the whole panel in order to intercept mouse | 113 // Transparent view covering the whole panel in order to intercept mouse |
| 115 // messages for custom user resizing. We need custom resizing because panels | 114 // messages for custom user resizing. We need custom resizing because panels |
| 116 // use their own constrained layout. | 115 // use their own constrained layout. |
| 117 // TODO(dimich): Pull the start/stop drag logic into a separate base class and | 116 // TODO(dimich): Pull the start/stop drag logic into a separate base class and |
| 118 // reuse between here and PanelTitlebarController. | 117 // reuse between here and PanelTitlebarController. |
| 119 @interface PanelResizeByMouseOverlay : NSView { | 118 @interface PanelResizeByMouseOverlay : NSView { |
| 120 @private | 119 @private |
| 121 Panel* panel_; | 120 Panel* panel_; |
| (...skipping 729 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 851 [boundsAnimation_ release]; | 850 [boundsAnimation_ release]; |
| 852 boundsAnimation_ = nil; | 851 boundsAnimation_ = nil; |
| 853 } | 852 } |
| 854 | 853 |
| 855 - (BOOL)isAnimatingBounds { | 854 - (BOOL)isAnimatingBounds { |
| 856 return boundsAnimation_ && [boundsAnimation_ isAnimating]; | 855 return boundsAnimation_ && [boundsAnimation_ isAnimating]; |
| 857 } | 856 } |
| 858 | 857 |
| 859 - (void)onTitlebarMouseClicked:(int)modifierFlags { | 858 - (void)onTitlebarMouseClicked:(int)modifierFlags { |
| 860 Panel* panel = windowShim_->panel(); | 859 Panel* panel = windowShim_->panel(); |
| 861 if (modifierFlags & NSShiftKeyMask) { | 860 panel->OnTitlebarClicked((modifierFlags & NSShiftKeyMask) ? |
| 862 panel->OnTitlebarClicked(panel::APPLY_TO_ALL); | 861 panel::APPLY_TO_ALL : panel::NO_MODIFIER); |
| 863 return; | |
| 864 } | |
| 865 | |
| 866 // TODO(jennb): Move remaining titlebar click handling out of here. | |
| 867 // (http://crbug.com/118431) | |
| 868 PanelStrip* panelStrip = panel->panel_strip(); | |
| 869 if (!panelStrip) | |
| 870 return; | |
| 871 if (panelStrip->type() == PanelStrip::DOCKED && | |
| 872 panel->expansion_state() == Panel::EXPANDED) { | |
| 873 if ([[self titlebarView] isDrawingAttention]) { | |
| 874 // Do not minimize if the Panel is drawing attention since user | |
| 875 // most likely simply wants to reset the 'draw attention' status. | |
| 876 panel->Activate(); | |
| 877 return; | |
| 878 } | |
| 879 panel->SetExpansionState(Panel::MINIMIZED); | |
| 880 // The Panel class ensures deactivation when it is minimized. | |
| 881 } else { | |
| 882 panel->Activate(); | |
| 883 } | |
| 884 } | 862 } |
| 885 | 863 |
| 886 - (int)titlebarHeightInScreenCoordinates { | 864 - (int)titlebarHeightInScreenCoordinates { |
| 887 NSView* titlebar = [self titlebarView]; | 865 NSView* titlebar = [self titlebarView]; |
| 888 return NSHeight([titlebar convertRect:[titlebar bounds] toView:nil]); | 866 return NSHeight([titlebar convertRect:[titlebar bounds] toView:nil]); |
| 889 } | 867 } |
| 890 | 868 |
| 891 - (int)titlebarIconOnlyWidthInScreenCoordinates { | 869 - (int)titlebarIconOnlyWidthInScreenCoordinates { |
| 892 return [[self titlebarView] iconOnlyWidthInScreenCoordinates]; | 870 return [[self titlebarView] iconOnlyWidthInScreenCoordinates]; |
| 893 } | 871 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 906 BrowserList::SetLastActive(windowShim_->browser()); | 884 BrowserList::SetLastActive(windowShim_->browser()); |
| 907 | 885 |
| 908 // We need to activate the controls (in the "WebView"). To do this, get the | 886 // We need to activate the controls (in the "WebView"). To do this, get the |
| 909 // selected WebContents's RenderWidgetHostView and tell it to activate. | 887 // selected WebContents's RenderWidgetHostView and tell it to activate. |
| 910 if (WebContents* contents = [contentsController_ webContents]) { | 888 if (WebContents* contents = [contentsController_ webContents]) { |
| 911 if (content::RenderWidgetHostView* rwhv = | 889 if (content::RenderWidgetHostView* rwhv = |
| 912 contents->GetRenderWidgetHostView()) | 890 contents->GetRenderWidgetHostView()) |
| 913 rwhv->SetActive(true); | 891 rwhv->SetActive(true); |
| 914 } | 892 } |
| 915 | 893 |
| 916 // If the window becomes key, lets make sure it is expanded and stop | 894 windowShim_->panel()->OnActiveStateChanged(true); |
| 917 // drawing attention - since it is ready to accept input, it already has | |
| 918 // user's attention. | |
| 919 if ([[self titlebarView] isDrawingAttention]) { | |
| 920 [[self titlebarView] stopDrawingAttention]; | |
| 921 } | |
| 922 | |
| 923 content::NotificationService::current()->Notify( | |
| 924 chrome::NOTIFICATION_PANEL_CHANGED_ACTIVE_STATUS, | |
| 925 content::Source<Panel>(windowShim_->panel()), | |
| 926 content::NotificationService::NoDetails()); | |
| 927 windowShim_->panel()->OnActiveStateChanged(); | |
| 928 } | 895 } |
| 929 | 896 |
| 930 - (void)windowDidResignKey:(NSNotification*)notification { | 897 - (void)windowDidResignKey:(NSNotification*)notification { |
| 931 // If our app is still active and we're still the key window, ignore this | 898 // If our app is still active and we're still the key window, ignore this |
| 932 // message, since it just means that a menu extra (on the "system status bar") | 899 // message, since it just means that a menu extra (on the "system status bar") |
| 933 // was activated; we'll get another |-windowDidResignKey| if we ever really | 900 // was activated; we'll get another |-windowDidResignKey| if we ever really |
| 934 // lose key window status. | 901 // lose key window status. |
| 935 if ([NSApp isActive] && ([NSApp keyWindow] == [self window])) | 902 if ([NSApp isActive] && ([NSApp keyWindow] == [self window])) |
| 936 return; | 903 return; |
| 937 | 904 |
| 938 // We need to deactivate the controls (in the "WebView"). To do this, get the | 905 // We need to deactivate the controls (in the "WebView"). To do this, get the |
| 939 // selected WebContents's RenderWidgetHostView and tell it to deactivate. | 906 // selected WebContents's RenderWidgetHostView and tell it to deactivate. |
| 940 if (WebContents* contents = [contentsController_ webContents]) { | 907 if (WebContents* contents = [contentsController_ webContents]) { |
| 941 if (content::RenderWidgetHostView* rwhv = | 908 if (content::RenderWidgetHostView* rwhv = |
| 942 contents->GetRenderWidgetHostView()) | 909 contents->GetRenderWidgetHostView()) |
| 943 rwhv->SetActive(false); | 910 rwhv->SetActive(false); |
| 944 } | 911 } |
| 945 | 912 |
| 946 content::NotificationService::current()->Notify( | 913 windowShim_->panel()->OnActiveStateChanged(false); |
| 947 chrome::NOTIFICATION_PANEL_CHANGED_ACTIVE_STATUS, | |
| 948 content::Source<Panel>(windowShim_->panel()), | |
| 949 content::NotificationService::NoDetails()); | |
| 950 windowShim_->panel()->OnActiveStateChanged(); | |
| 951 } | 914 } |
| 952 | 915 |
| 953 - (void)deactivate { | 916 - (void)deactivate { |
| 954 if (![[self window] isMainWindow]) | 917 if (![[self window] isMainWindow]) |
| 955 return; | 918 return; |
| 956 BrowserWindow* browser_window = | 919 BrowserWindow* browser_window = |
| 957 windowShim_->panel()->manager()->GetNextBrowserWindowToActivate( | 920 windowShim_->panel()->manager()->GetNextBrowserWindowToActivate( |
| 958 windowShim_->panel()); | 921 windowShim_->panel()); |
| 959 | 922 |
| 960 if (browser_window) | 923 if (browser_window) |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1027 } | 990 } |
| 1028 [[self window] setLevel:NSDockWindowLevel]; | 991 [[self window] setLevel:NSDockWindowLevel]; |
| 1029 } | 992 } |
| 1030 | 993 |
| 1031 - (void)enableResizeByMouse:(BOOL)enable { | 994 - (void)enableResizeByMouse:(BOOL)enable { |
| 1032 if (![self isWindowLoaded]) | 995 if (![self isWindowLoaded]) |
| 1033 return; | 996 return; |
| 1034 [[self window] invalidateCursorRectsForView:overlayView_]; | 997 [[self window] invalidateCursorRectsForView:overlayView_]; |
| 1035 } | 998 } |
| 1036 | 999 |
| 1037 - (BOOL)isActivationByClickingTitlebarEnabled { | |
| 1038 return !windowShim_->panel()->always_on_top(); | |
| 1039 } | |
| 1040 | |
| 1041 @end | 1000 @end |
| OLD | NEW |