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