OLD | NEW |
1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 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 #import "chrome/browser/ui/cocoa/browser_window_controller.h" | 5 #import "chrome/browser/ui/cocoa/browser_window_controller.h" |
6 | 6 |
7 #include <cmath> | 7 #include <cmath> |
8 #include <numeric> | 8 #include <numeric> |
9 | 9 |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
11 #include "base/mac/bundle_locations.h" | 11 #include "base/mac/bundle_locations.h" |
12 #import "base/mac/foundation_util.h" | 12 #import "base/mac/foundation_util.h" |
13 #include "base/mac/mac_util.h" | 13 #include "base/mac/mac_util.h" |
14 #import "base/mac/sdk_forward_declarations.h" | 14 #import "base/mac/sdk_forward_declarations.h" |
15 #include "base/strings/sys_string_conversions.h" | 15 #include "base/strings/sys_string_conversions.h" |
16 #include "base/strings/utf_string_conversions.h" | 16 #include "base/strings/utf_string_conversions.h" |
17 #include "chrome/app/chrome_command_ids.h" // IDC_* | 17 #include "chrome/app/chrome_command_ids.h" // IDC_* |
18 #import "chrome/browser/app_controller_mac.h" | |
19 #include "chrome/browser/bookmarks/bookmark_model_factory.h" | 18 #include "chrome/browser/bookmarks/bookmark_model_factory.h" |
20 #include "chrome/browser/bookmarks/managed_bookmark_service_factory.h" | 19 #include "chrome/browser/bookmarks/managed_bookmark_service_factory.h" |
21 #include "chrome/browser/browser_process.h" | 20 #include "chrome/browser/browser_process.h" |
22 #include "chrome/browser/devtools/devtools_window.h" | 21 #include "chrome/browser/devtools/devtools_window.h" |
23 #include "chrome/browser/extensions/extension_commands_global_registry.h" | 22 #include "chrome/browser/extensions/extension_commands_global_registry.h" |
24 #include "chrome/browser/fullscreen.h" | 23 #include "chrome/browser/fullscreen.h" |
25 #include "chrome/browser/profiles/avatar_menu.h" | 24 #include "chrome/browser/profiles/avatar_menu.h" |
26 #include "chrome/browser/profiles/profile.h" | 25 #include "chrome/browser/profiles/profile.h" |
27 #include "chrome/browser/profiles/profile_info_cache.h" | 26 #include "chrome/browser/profiles/profile_info_cache.h" |
28 #include "chrome/browser/profiles/profile_manager.h" | 27 #include "chrome/browser/profiles/profile_manager.h" |
29 #include "chrome/browser/profiles/profiles_state.h" | 28 #include "chrome/browser/profiles/profiles_state.h" |
30 #include "chrome/browser/themes/theme_service.h" | 29 #include "chrome/browser/themes/theme_service.h" |
31 #include "chrome/browser/themes/theme_service_factory.h" | 30 #include "chrome/browser/themes/theme_service_factory.h" |
32 #include "chrome/browser/translate/chrome_translate_client.h" | 31 #include "chrome/browser/translate/chrome_translate_client.h" |
33 #include "chrome/browser/ui/bookmarks/bookmark_editor.h" | 32 #include "chrome/browser/ui/bookmarks/bookmark_editor.h" |
34 #include "chrome/browser/ui/bookmarks/bookmark_utils.h" | |
35 #include "chrome/browser/ui/browser.h" | 33 #include "chrome/browser/ui/browser.h" |
36 #include "chrome/browser/ui/browser_command_controller.h" | 34 #include "chrome/browser/ui/browser_command_controller.h" |
37 #include "chrome/browser/ui/browser_commands.h" | 35 #include "chrome/browser/ui/browser_commands.h" |
38 #include "chrome/browser/ui/browser_instant_controller.h" | 36 #include "chrome/browser/ui/browser_instant_controller.h" |
39 #include "chrome/browser/ui/browser_list.h" | 37 #include "chrome/browser/ui/browser_list.h" |
40 #include "chrome/browser/ui/browser_window_state.h" | 38 #include "chrome/browser/ui/browser_window_state.h" |
41 #import "chrome/browser/ui/cocoa/background_gradient_view.h" | 39 #import "chrome/browser/ui/cocoa/background_gradient_view.h" |
42 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.h" | 40 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.h" |
43 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_editor_controller.h" | 41 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_editor_controller.h" |
44 #import "chrome/browser/ui/cocoa/browser_window_cocoa.h" | 42 #import "chrome/browser/ui/cocoa/browser_window_cocoa.h" |
(...skipping 21 matching lines...) Expand all Loading... |
66 #import "chrome/browser/ui/cocoa/tabs/tab_strip_controller.h" | 64 #import "chrome/browser/ui/cocoa/tabs/tab_strip_controller.h" |
67 #import "chrome/browser/ui/cocoa/tabs/tab_strip_view.h" | 65 #import "chrome/browser/ui/cocoa/tabs/tab_strip_view.h" |
68 #import "chrome/browser/ui/cocoa/tabs/tab_view.h" | 66 #import "chrome/browser/ui/cocoa/tabs/tab_view.h" |
69 #import "chrome/browser/ui/cocoa/toolbar/toolbar_controller.h" | 67 #import "chrome/browser/ui/cocoa/toolbar/toolbar_controller.h" |
70 #import "chrome/browser/ui/cocoa/translate/translate_bubble_controller.h" | 68 #import "chrome/browser/ui/cocoa/translate/translate_bubble_controller.h" |
71 #include "chrome/browser/ui/cocoa/website_settings/permission_bubble_cocoa.h" | 69 #include "chrome/browser/ui/cocoa/website_settings/permission_bubble_cocoa.h" |
72 #include "chrome/browser/ui/exclusive_access/fullscreen_controller.h" | 70 #include "chrome/browser/ui/exclusive_access/fullscreen_controller.h" |
73 #include "chrome/browser/ui/location_bar/location_bar.h" | 71 #include "chrome/browser/ui/location_bar/location_bar.h" |
74 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 72 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
75 #include "chrome/browser/ui/tabs/tab_strip_model_delegate.h" | 73 #include "chrome/browser/ui/tabs/tab_strip_model_delegate.h" |
76 #include "chrome/browser/ui/toolbar/encoding_menu_controller.h" | |
77 #include "chrome/browser/ui/translate/translate_bubble_model_impl.h" | 74 #include "chrome/browser/ui/translate/translate_bubble_model_impl.h" |
78 #include "chrome/browser/ui/website_settings/permission_bubble_manager.h" | 75 #include "chrome/browser/ui/website_settings/permission_bubble_manager.h" |
79 #include "chrome/browser/ui/window_sizer/window_sizer.h" | 76 #include "chrome/browser/ui/window_sizer/window_sizer.h" |
80 #include "chrome/common/chrome_switches.h" | 77 #include "chrome/common/chrome_switches.h" |
81 #include "chrome/common/extensions/command.h" | 78 #include "chrome/common/extensions/command.h" |
82 #include "chrome/common/url_constants.h" | 79 #include "chrome/common/url_constants.h" |
83 #include "chrome/grit/generated_resources.h" | 80 #include "chrome/grit/generated_resources.h" |
84 #include "chrome/grit/locale_settings.h" | 81 #include "chrome/grit/locale_settings.h" |
85 #include "components/bookmarks/browser/bookmark_model.h" | 82 #include "components/bookmarks/browser/bookmark_model.h" |
86 #include "components/bookmarks/managed/managed_bookmark_service.h" | 83 #include "components/bookmarks/managed/managed_bookmark_service.h" |
(...skipping 964 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1051 if (resizeRectDirty) { | 1048 if (resizeRectDirty) { |
1052 // Send new resize rect to foreground tab. | 1049 // Send new resize rect to foreground tab. |
1053 if (WebContents* contents = [self webContents]) { | 1050 if (WebContents* contents = [self webContents]) { |
1054 if (content::RenderViewHost* rvh = contents->GetRenderViewHost()) { | 1051 if (content::RenderViewHost* rvh = contents->GetRenderViewHost()) { |
1055 rvh->ResizeRectChanged(windowShim_->GetRootWindowResizerRect()); | 1052 rvh->ResizeRectChanged(windowShim_->GetRootWindowResizerRect()); |
1056 } | 1053 } |
1057 } | 1054 } |
1058 } | 1055 } |
1059 } | 1056 } |
1060 | 1057 |
1061 // Update a toggle state for an NSMenuItem if modified. | |
1062 // Take care to ensure |item| looks like a NSMenuItem. | |
1063 // Called by validateUserInterfaceItem:. | |
1064 - (void)updateToggleStateWithTag:(NSInteger)tag forItem:(id)item { | |
1065 if (![item respondsToSelector:@selector(state)] || | |
1066 ![item respondsToSelector:@selector(setState:)]) | |
1067 return; | |
1068 | |
1069 // On Windows this logic happens in bookmark_bar_view.cc. On the | |
1070 // Mac we're a lot more MVC happy so we've moved it into a | |
1071 // controller. To be clear, this simply updates the menu item; it | |
1072 // does not display the bookmark bar itself. | |
1073 if (tag == IDC_SHOW_BOOKMARK_BAR) { | |
1074 bool toggled = windowShim_->IsBookmarkBarVisible(); | |
1075 NSInteger oldState = [(NSMenuItem*)item state]; | |
1076 NSInteger newState = toggled ? NSOnState : NSOffState; | |
1077 if (oldState != newState) | |
1078 [item setState:newState]; | |
1079 } | |
1080 | |
1081 // Update the checked/Unchecked state of items in the encoding menu. | |
1082 // On Windows, this logic is part of |EncodingMenuModel| in | |
1083 // browser/ui/views/toolbar_view.h. | |
1084 EncodingMenuController encoding_controller; | |
1085 if (encoding_controller.DoesCommandBelongToEncodingMenu(tag)) { | |
1086 DCHECK(browser_.get()); | |
1087 Profile* profile = browser_->profile(); | |
1088 DCHECK(profile); | |
1089 WebContents* current_tab = | |
1090 browser_->tab_strip_model()->GetActiveWebContents(); | |
1091 if (!current_tab) | |
1092 return; | |
1093 | |
1094 const std::string encoding = current_tab->GetEncoding(); | |
1095 | |
1096 bool toggled = encoding_controller.IsItemChecked(profile, encoding, tag); | |
1097 NSInteger oldState = [(NSMenuItem*)item state]; | |
1098 NSInteger newState = toggled ? NSOnState : NSOffState; | |
1099 if (oldState != newState) | |
1100 [item setState:newState]; | |
1101 } | |
1102 } | |
1103 | |
1104 // Called to validate menu and toolbar items when this window is key. All the | |
1105 // items we care about have been set with the |-commandDispatch:| or | |
1106 // |-commandDispatchUsingKeyModifiers:| actions and a target of FirstResponder | |
1107 // in IB. If it's not one of those, let it continue up the responder chain to be | |
1108 // handled elsewhere. We pull out the tag as the cross-platform constant to | |
1109 // differentiate and dispatch the various commands. | |
1110 // NOTE: we might have to handle state for app-wide menu items, | |
1111 // although we could cheat and directly ask the app controller if our | |
1112 // command_updater doesn't support the command. This may or may not be an issue, | |
1113 // too early to tell. | |
1114 - (BOOL)validateUserInterfaceItem:(id<NSValidatedUserInterfaceItem>)item { | |
1115 SEL action = [item action]; | |
1116 BOOL enable = NO; | |
1117 if (action == @selector(commandDispatch:) || | |
1118 action == @selector(commandDispatchUsingKeyModifiers:)) { | |
1119 NSInteger tag = [item tag]; | |
1120 if (chrome::SupportsCommand(browser_.get(), tag)) { | |
1121 // Generate return value (enabled state) | |
1122 enable = chrome::IsCommandEnabled(browser_.get(), tag); | |
1123 switch (tag) { | |
1124 case IDC_CLOSE_TAB: | |
1125 // Disable "close tab" if the receiving window is not tabbed. | |
1126 // We simply check whether the item has a keyboard shortcut set here; | |
1127 // app_controller_mac.mm actually determines whether the item should | |
1128 // be enabled. | |
1129 if (NSMenuItem* menuItem = base::mac::ObjCCast<NSMenuItem>(item)) | |
1130 enable &= !![[menuItem keyEquivalent] length]; | |
1131 break; | |
1132 case IDC_FULLSCREEN: { | |
1133 if (NSMenuItem* menuItem = base::mac::ObjCCast<NSMenuItem>(item)) { | |
1134 if (chrome::mac::SupportsSystemFullscreen()) { | |
1135 [menuItem setTitle:[self titleForFullscreenMenuItem]]; | |
1136 } else { | |
1137 [menuItem setHidden:YES]; | |
1138 } | |
1139 } | |
1140 break; | |
1141 } | |
1142 case IDC_PRESENTATION_MODE: { | |
1143 if (NSMenuItem* menuItem = base::mac::ObjCCast<NSMenuItem>(item)) { | |
1144 [menuItem setTitle:[self titleForFullscreenMenuItem]]; | |
1145 | |
1146 if (chrome::mac::SupportsSystemFullscreen()) | |
1147 [menuItem setAlternate:YES]; | |
1148 } | |
1149 break; | |
1150 } | |
1151 case IDC_SHOW_SIGNIN: { | |
1152 Profile* original_profile = | |
1153 browser_->profile()->GetOriginalProfile(); | |
1154 [AppController updateSigninItem:item | |
1155 shouldShow:enable | |
1156 currentProfile:original_profile]; | |
1157 break; | |
1158 } | |
1159 case IDC_BOOKMARK_PAGE: { | |
1160 // Extensions have the ability to hide the bookmark page menu item. | |
1161 // This only affects the bookmark page menu item under the main menu. | |
1162 // The bookmark page menu item under the wrench menu has its | |
1163 // visibility controlled by WrenchMenuModel. | |
1164 bool shouldHide = | |
1165 chrome::ShouldRemoveBookmarkThisPageUI(browser_->profile()); | |
1166 NSMenuItem* menuItem = base::mac::ObjCCast<NSMenuItem>(item); | |
1167 [menuItem setHidden:shouldHide]; | |
1168 break; | |
1169 } | |
1170 case IDC_BOOKMARK_ALL_TABS: { | |
1171 // Extensions have the ability to hide the bookmark all tabs menu | |
1172 // item. This only affects the bookmark page menu item under the main | |
1173 // menu. The bookmark page menu item under the wrench menu has its | |
1174 // visibility controlled by WrenchMenuModel. | |
1175 bool shouldHide = | |
1176 chrome::ShouldRemoveBookmarkOpenPagesUI(browser_->profile()); | |
1177 NSMenuItem* menuItem = base::mac::ObjCCast<NSMenuItem>(item); | |
1178 [menuItem setHidden:shouldHide]; | |
1179 break; | |
1180 } | |
1181 default: | |
1182 // Special handling for the contents of the Text Encoding submenu. On | |
1183 // Mac OS, instead of enabling/disabling the top-level menu item, we | |
1184 // enable/disable the submenu's contents (per Apple's HIG). | |
1185 EncodingMenuController encoding_controller; | |
1186 if (encoding_controller.DoesCommandBelongToEncodingMenu(tag)) { | |
1187 enable &= chrome::IsCommandEnabled(browser_.get(), | |
1188 IDC_ENCODING_MENU) ? YES : NO; | |
1189 } | |
1190 } | |
1191 | |
1192 // If the item is toggleable, find its toggle state and | |
1193 // try to update it. This is a little awkward, but the alternative is | |
1194 // to check after a commandDispatch, which seems worse. | |
1195 [self updateToggleStateWithTag:tag forItem:item]; | |
1196 } | |
1197 } | |
1198 return enable; | |
1199 } | |
1200 | |
1201 // Called when the user picks a menu or toolbar item when this window is key. | |
1202 // Calls through to the browser object to execute the command. This assumes that | |
1203 // the command is supported and doesn't check, otherwise it would have been | |
1204 // disabled in the UI in validateUserInterfaceItem:. | |
1205 - (void)commandDispatch:(id)sender { | |
1206 DCHECK(sender); | |
1207 // Identify the actual BWC to which the command should be dispatched. It might | |
1208 // belong to a background window, yet this controller gets it because it is | |
1209 // the foreground window's controller and thus in the responder chain. Some | |
1210 // senders don't have this problem (for example, menus only operate on the | |
1211 // foreground window), so this is only an issue for senders that are part of | |
1212 // windows. | |
1213 BrowserWindowController* targetController = self; | |
1214 if ([sender respondsToSelector:@selector(window)]) | |
1215 targetController = [[sender window] windowController]; | |
1216 DCHECK([targetController isKindOfClass:[BrowserWindowController class]]); | |
1217 DCHECK(targetController->browser_.get()); | |
1218 | |
1219 // When system fullscreen is available, it supercedes presentation mode. | |
1220 int tag = [sender tag]; | |
1221 if (tag == IDC_PRESENTATION_MODE && chrome::mac::SupportsSystemFullscreen()) | |
1222 tag = IDC_FULLSCREEN; | |
1223 | |
1224 chrome::ExecuteCommand(targetController->browser_.get(), tag); | |
1225 } | |
1226 | |
1227 // Same as |-commandDispatch:|, but executes commands using a disposition | |
1228 // determined by the key flags. If the window is in the background and the | |
1229 // command key is down, ignore the command key, but process any other modifiers. | |
1230 - (void)commandDispatchUsingKeyModifiers:(id)sender { | |
1231 DCHECK(sender); | |
1232 | |
1233 if (![sender isEnabled]) { | |
1234 // This code is reachable e.g. if the user mashes the back button, queuing | |
1235 // up a bunch of events before the button's enabled state is updated: | |
1236 // http://crbug.com/63254 | |
1237 return; | |
1238 } | |
1239 | |
1240 // See comment above for why we do this. | |
1241 BrowserWindowController* targetController = self; | |
1242 if ([sender respondsToSelector:@selector(window)]) | |
1243 targetController = [[sender window] windowController]; | |
1244 DCHECK([targetController isKindOfClass:[BrowserWindowController class]]); | |
1245 DCHECK(targetController->browser_.get()); | |
1246 | |
1247 NSInteger command = [sender tag]; | |
1248 NSUInteger modifierFlags = [[NSApp currentEvent] modifierFlags]; | |
1249 if ((command == IDC_RELOAD) && | |
1250 (modifierFlags & (NSShiftKeyMask | NSControlKeyMask))) { | |
1251 command = IDC_RELOAD_IGNORING_CACHE; | |
1252 // Mask off Shift and Control so they don't affect the disposition below. | |
1253 modifierFlags &= ~(NSShiftKeyMask | NSControlKeyMask); | |
1254 } | |
1255 if (![[sender window] isMainWindow]) { | |
1256 // Remove the command key from the flags, it means "keep the window in | |
1257 // the background" in this case. | |
1258 modifierFlags &= ~NSCommandKeyMask; | |
1259 } | |
1260 chrome::ExecuteCommandWithDisposition( | |
1261 targetController->browser_.get(), command, | |
1262 ui::WindowOpenDispositionFromNSEventWithFlags( | |
1263 [NSApp currentEvent], modifierFlags)); | |
1264 } | |
1265 | |
1266 - (BOOL)handledByExtensionCommand:(NSEvent*)event | 1058 - (BOOL)handledByExtensionCommand:(NSEvent*)event |
1267 priority:(ui::AcceleratorManager::HandlerPriority)priority { | 1059 priority:(ui::AcceleratorManager::HandlerPriority)priority { |
1268 return extension_keybinding_registry_->ProcessKeyEvent( | 1060 return extension_keybinding_registry_->ProcessKeyEvent( |
1269 content::NativeWebKeyboardEvent(event), priority); | 1061 content::NativeWebKeyboardEvent(event), priority); |
1270 } | 1062 } |
1271 | 1063 |
1272 // StatusBubble delegate method: tell the status bubble the frame it should | 1064 // StatusBubble delegate method: tell the status bubble the frame it should |
1273 // position itself in. | 1065 // position itself in. |
1274 - (NSRect)statusBubbleBaseFrame { | 1066 - (NSRect)statusBubbleBaseFrame { |
1275 NSView* view = [overlayableContentsController_ view]; | 1067 NSView* view = [overlayableContentsController_ view]; |
(...skipping 991 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2267 | 2059 |
2268 - (BOOL)supportsBookmarkBar { | 2060 - (BOOL)supportsBookmarkBar { |
2269 return [self supportsWindowFeature:Browser::FEATURE_BOOKMARKBAR]; | 2061 return [self supportsWindowFeature:Browser::FEATURE_BOOKMARKBAR]; |
2270 } | 2062 } |
2271 | 2063 |
2272 - (BOOL)isTabbedWindow { | 2064 - (BOOL)isTabbedWindow { |
2273 return browser_->is_type_tabbed(); | 2065 return browser_->is_type_tabbed(); |
2274 } | 2066 } |
2275 | 2067 |
2276 @end // @implementation BrowserWindowController(WindowType) | 2068 @end // @implementation BrowserWindowController(WindowType) |
OLD | NEW |