OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/apps/app_shim_menu_controller_mac.h" | 5 #import "chrome/browser/ui/cocoa/apps/app_shim_menu_controller_mac.h" |
6 | 6 |
7 #include "base/mac/scoped_nsautorelease_pool.h" | 7 #include "base/mac/scoped_nsautorelease_pool.h" |
8 #include "base/strings/sys_string_conversions.h" | 8 #include "base/strings/sys_string_conversions.h" |
9 #include "base/strings/utf_string_conversions.h" | 9 #include "base/strings/utf_string_conversions.h" |
10 #include "chrome/app/chrome_command_ids.h" | 10 #include "chrome/app/chrome_command_ids.h" |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
133 | 133 |
134 @property(readonly, nonatomic) NSMenuItem* menuItem; | 134 @property(readonly, nonatomic) NSMenuItem* menuItem; |
135 | 135 |
136 // Get the source item using the tags and create the menu item. | 136 // Get the source item using the tags and create the menu item. |
137 - (id)initWithController:(AppShimMenuController*)controller | 137 - (id)initWithController:(AppShimMenuController*)controller |
138 menuTag:(NSInteger)menuTag | 138 menuTag:(NSInteger)menuTag |
139 itemTag:(NSInteger)itemTag | 139 itemTag:(NSInteger)itemTag |
140 resourceId:(int)resourceId | 140 resourceId:(int)resourceId |
141 action:(SEL)action | 141 action:(SEL)action |
142 keyEquivalent:(NSString*)keyEquivalent; | 142 keyEquivalent:(NSString*)keyEquivalent; |
| 143 // Retain the source item given |menuTag| and |sourceItemTag|. Copy |
| 144 // the menu item given |menuTag| and |targetItemTag|. |
| 145 // This is useful when we want a doppelganger with a different source item. |
| 146 // For example, if there are conflicting key equivalents. |
| 147 - (id)initWithMenuTag:(NSInteger)menuTag |
| 148 sourceItemTag:(NSInteger)sourceItemTag |
| 149 targetItemTag:(NSInteger)targetItemTag |
| 150 keyEquivalent:(NSString*)keyEquivalent; |
143 // Set the title using |resourceId_| and unset the source item's key equivalent. | 151 // Set the title using |resourceId_| and unset the source item's key equivalent. |
144 - (void)enableForApp:(const extensions::Extension*)app; | 152 - (void)enableForApp:(const extensions::Extension*)app; |
145 // Restore the source item's key equivalent. | 153 // Restore the source item's key equivalent. |
146 - (void)disable; | 154 - (void)disable; |
147 @end | 155 @end |
148 | 156 |
149 @implementation DoppelgangerMenuItem | 157 @implementation DoppelgangerMenuItem |
150 | 158 |
151 - (NSMenuItem*)menuItem { | 159 - (NSMenuItem*)menuItem { |
152 return menuItem_; | 160 return menuItem_; |
(...skipping 13 matching lines...) Expand all Loading... |
166 initWithTitle:[sourceItem_ title] | 174 initWithTitle:[sourceItem_ title] |
167 action:action | 175 action:action |
168 keyEquivalent:keyEquivalent]); | 176 keyEquivalent:keyEquivalent]); |
169 [menuItem_ setTarget:controller]; | 177 [menuItem_ setTarget:controller]; |
170 [menuItem_ setTag:itemTag]; | 178 [menuItem_ setTag:itemTag]; |
171 resourceId_ = resourceId; | 179 resourceId_ = resourceId; |
172 } | 180 } |
173 return self; | 181 return self; |
174 } | 182 } |
175 | 183 |
| 184 - (id)initWithMenuTag:(NSInteger)menuTag |
| 185 sourceItemTag:(NSInteger)sourceItemTag |
| 186 targetItemTag:(NSInteger)targetItemTag |
| 187 keyEquivalent:(NSString*)keyEquivalent { |
| 188 if ((self = [super init])) { |
| 189 menuItem_.reset([GetItemByTag(menuTag, targetItemTag) copy]); |
| 190 sourceItem_.reset([GetItemByTag(menuTag, sourceItemTag) retain]); |
| 191 DCHECK(menuItem_); |
| 192 DCHECK(sourceItem_); |
| 193 sourceKeyEquivalent_.reset([[sourceItem_ keyEquivalent] copy]); |
| 194 } |
| 195 return self; |
| 196 } |
| 197 |
176 - (void)enableForApp:(const extensions::Extension*)app { | 198 - (void)enableForApp:(const extensions::Extension*)app { |
177 // It seems that two menu items that have the same key equivalent must also | 199 // It seems that two menu items that have the same key equivalent must also |
178 // have the same action for the keyboard shortcut to work. (This refers to the | 200 // have the same action for the keyboard shortcut to work. (This refers to the |
179 // original keyboard shortcut, regardless of any overrides set in OSX). | 201 // original keyboard shortcut, regardless of any overrides set in OSX). |
180 // In order to let the app menu items have a different action, we remove the | 202 // In order to let the app menu items have a different action, we remove the |
181 // key equivalent of the original items and restore them later. | 203 // key equivalent of the original items and restore them later. |
182 [sourceItem_ setKeyEquivalent:@""]; | 204 [sourceItem_ setKeyEquivalent:@""]; |
183 if (!resourceId_) | 205 if (!resourceId_) |
184 return; | 206 return; |
185 | 207 |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
253 resourceId:IDS_EXIT_MAC | 275 resourceId:IDS_EXIT_MAC |
254 action:@selector(quitCurrentPlatformApp) | 276 action:@selector(quitCurrentPlatformApp) |
255 keyEquivalent:@"q"]); | 277 keyEquivalent:@"q"]); |
256 newDoppelganger_.reset([[DoppelgangerMenuItem alloc] | 278 newDoppelganger_.reset([[DoppelgangerMenuItem alloc] |
257 initWithController:self | 279 initWithController:self |
258 menuTag:IDC_FILE_MENU | 280 menuTag:IDC_FILE_MENU |
259 itemTag:IDC_NEW_WINDOW | 281 itemTag:IDC_NEW_WINDOW |
260 resourceId:0 | 282 resourceId:0 |
261 action:nil | 283 action:nil |
262 keyEquivalent:@"n"]); | 284 keyEquivalent:@"n"]); |
| 285 // Since the "Close Window" menu item will have the same shortcut as "Close |
| 286 // Tab" on the Chrome menu, we need to create a doppelganger. |
| 287 closeWindowDoppelganger_.reset([[DoppelgangerMenuItem alloc] |
| 288 initWithMenuTag:IDC_FILE_MENU |
| 289 sourceItemTag:IDC_CLOSE_TAB |
| 290 targetItemTag:IDC_CLOSE_WINDOW |
| 291 keyEquivalent:@"w"]); |
263 // For apps, the "Window" part of "New Window" is dropped to match the default | 292 // For apps, the "Window" part of "New Window" is dropped to match the default |
264 // menu set given to Cocoa Apps. | 293 // menu set given to Cocoa Apps. |
265 [[newDoppelganger_ menuItem] setTitle:l10n_util::GetNSString(IDS_NEW_MAC)]; | 294 [[newDoppelganger_ menuItem] setTitle:l10n_util::GetNSString(IDS_NEW_MAC)]; |
266 openDoppelganger_.reset([[DoppelgangerMenuItem alloc] | 295 openDoppelganger_.reset([[DoppelgangerMenuItem alloc] |
267 initWithController:self | 296 initWithController:self |
268 menuTag:IDC_FILE_MENU | 297 menuTag:IDC_FILE_MENU |
269 itemTag:IDC_OPEN_FILE | 298 itemTag:IDC_OPEN_FILE |
270 resourceId:0 | 299 resourceId:0 |
271 action:nil | 300 action:nil |
272 keyEquivalent:@"o"]); | 301 keyEquivalent:@"o"]); |
(...skipping 18 matching lines...) Expand all Loading... |
291 [appMenu addItem:[NSMenuItem separatorItem]]; | 320 [appMenu addItem:[NSMenuItem separatorItem]]; |
292 [appMenu addItem:[hideDoppelganger_ menuItem]]; | 321 [appMenu addItem:[hideDoppelganger_ menuItem]]; |
293 [appMenu addItem:[NSMenuItem separatorItem]]; | 322 [appMenu addItem:[NSMenuItem separatorItem]]; |
294 [appMenu addItem:[quitDoppelganger_ menuItem]]; | 323 [appMenu addItem:[quitDoppelganger_ menuItem]]; |
295 | 324 |
296 // File menu. | 325 // File menu. |
297 fileMenuItem_.reset([NewTopLevelItemFrom(IDC_FILE_MENU) retain]); | 326 fileMenuItem_.reset([NewTopLevelItemFrom(IDC_FILE_MENU) retain]); |
298 [[fileMenuItem_ submenu] addItem:[newDoppelganger_ menuItem]]; | 327 [[fileMenuItem_ submenu] addItem:[newDoppelganger_ menuItem]]; |
299 [[fileMenuItem_ submenu] addItem:[openDoppelganger_ menuItem]]; | 328 [[fileMenuItem_ submenu] addItem:[openDoppelganger_ menuItem]]; |
300 [[fileMenuItem_ submenu] addItem:[NSMenuItem separatorItem]]; | 329 [[fileMenuItem_ submenu] addItem:[NSMenuItem separatorItem]]; |
301 AddDuplicateItem(fileMenuItem_, IDC_FILE_MENU, IDC_CLOSE_WINDOW); | 330 [[fileMenuItem_ submenu] addItem:[closeWindowDoppelganger_ menuItem]]; |
302 // Set the expected key equivalent explicitly here because | |
303 // -[AppControllerMac adjustCloseWindowMenuItemKeyEquivalent:] sets it to | |
304 // "W" (Cmd+Shift+w) when a tabbed window has focus; it will change it back | |
305 // to Cmd+w when a non-tabbed window has focus. | |
306 NSMenuItem* closeWindowMenuItem = | |
307 [[fileMenuItem_ submenu] itemWithTag:IDC_CLOSE_WINDOW]; | |
308 [closeWindowMenuItem setKeyEquivalent:@"w"]; | |
309 [closeWindowMenuItem setKeyEquivalentModifierMask:NSCommandKeyMask]; | |
310 | 331 |
311 // Edit menu. We copy the menu because the last two items, "Start Dictation" | 332 // Edit menu. We copy the menu because the last two items, "Start Dictation" |
312 // and "Special Characters" are added by OSX, so we can't copy them | 333 // and "Special Characters" are added by OSX, so we can't copy them |
313 // explicitly. | 334 // explicitly. |
314 editMenuItem_.reset([[[NSApp mainMenu] itemWithTag:IDC_EDIT_MENU] copy]); | 335 editMenuItem_.reset([[[NSApp mainMenu] itemWithTag:IDC_EDIT_MENU] copy]); |
315 | 336 |
316 // View menu. Remove "Always Show Bookmark Bar" and separator. | 337 // View menu. Remove "Always Show Bookmark Bar" and separator. |
317 viewMenuItem_.reset([[[NSApp mainMenu] itemWithTag:IDC_VIEW_MENU] copy]); | 338 viewMenuItem_.reset([[[NSApp mainMenu] itemWithTag:IDC_VIEW_MENU] copy]); |
318 RemoveMenuItemWithTag(viewMenuItem_, IDC_SHOW_BOOKMARK_BAR, YES); | 339 RemoveMenuItemWithTag(viewMenuItem_, IDC_SHOW_BOOKMARK_BAR, YES); |
319 | 340 |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
400 // Hide Chrome menu items. | 421 // Hide Chrome menu items. |
401 NSMenu* mainMenu = [NSApp mainMenu]; | 422 NSMenu* mainMenu = [NSApp mainMenu]; |
402 for (NSMenuItem* item in [mainMenu itemArray]) | 423 for (NSMenuItem* item in [mainMenu itemArray]) |
403 [item setHidden:YES]; | 424 [item setHidden:YES]; |
404 | 425 |
405 [aboutDoppelganger_ enableForApp:app]; | 426 [aboutDoppelganger_ enableForApp:app]; |
406 [hideDoppelganger_ enableForApp:app]; | 427 [hideDoppelganger_ enableForApp:app]; |
407 [quitDoppelganger_ enableForApp:app]; | 428 [quitDoppelganger_ enableForApp:app]; |
408 [newDoppelganger_ enableForApp:app]; | 429 [newDoppelganger_ enableForApp:app]; |
409 [openDoppelganger_ enableForApp:app]; | 430 [openDoppelganger_ enableForApp:app]; |
| 431 [closeWindowDoppelganger_ enableForApp:app]; |
410 | 432 |
411 [appMenuItem_ setTitle:appId]; | 433 [appMenuItem_ setTitle:appId]; |
412 [[appMenuItem_ submenu] setTitle:title]; | 434 [[appMenuItem_ submenu] setTitle:title]; |
413 | 435 |
414 [mainMenu addItem:appMenuItem_]; | 436 [mainMenu addItem:appMenuItem_]; |
415 [mainMenu addItem:fileMenuItem_]; | 437 [mainMenu addItem:fileMenuItem_]; |
416 | 438 |
417 SetItemWithTagVisible(editMenuItem_, | 439 SetItemWithTagVisible(editMenuItem_, |
418 IDC_CONTENT_CONTEXT_PASTE_AND_MATCH_STYLE, | 440 IDC_CONTENT_CONTEXT_PASTE_AND_MATCH_STYLE, |
419 app->is_hosted_app(), true); | 441 app->is_hosted_app(), true); |
(...skipping 26 matching lines...) Expand all Loading... |
446 | 468 |
447 // Restore the Chrome main menu bar. | 469 // Restore the Chrome main menu bar. |
448 for (NSMenuItem* item in [mainMenu itemArray]) | 470 for (NSMenuItem* item in [mainMenu itemArray]) |
449 [item setHidden:NO]; | 471 [item setHidden:NO]; |
450 | 472 |
451 [aboutDoppelganger_ disable]; | 473 [aboutDoppelganger_ disable]; |
452 [hideDoppelganger_ disable]; | 474 [hideDoppelganger_ disable]; |
453 [quitDoppelganger_ disable]; | 475 [quitDoppelganger_ disable]; |
454 [newDoppelganger_ disable]; | 476 [newDoppelganger_ disable]; |
455 [openDoppelganger_ disable]; | 477 [openDoppelganger_ disable]; |
| 478 [closeWindowDoppelganger_ disable]; |
456 } | 479 } |
457 | 480 |
458 - (void)quitCurrentPlatformApp { | 481 - (void)quitCurrentPlatformApp { |
459 extensions::AppWindow* appWindow = | 482 extensions::AppWindow* appWindow = |
460 AppWindowRegistryUtil::GetAppWindowForNativeWindowAnyProfile( | 483 AppWindowRegistryUtil::GetAppWindowForNativeWindowAnyProfile( |
461 [NSApp keyWindow]); | 484 [NSApp keyWindow]); |
462 if (appWindow) { | 485 if (appWindow) { |
463 apps::ExtensionAppShimHandler::QuitAppForWindow(appWindow); | 486 apps::ExtensionAppShimHandler::QuitAppForWindow(appWindow); |
464 } else { | 487 } else { |
465 Browser* browser = chrome::FindBrowserWithWindow([NSApp keyWindow]); | 488 Browser* browser = chrome::FindBrowserWithWindow([NSApp keyWindow]); |
(...skipping 23 matching lines...) Expand all Loading... |
489 | 512 |
490 - (void)focusCurrentPlatformApp { | 513 - (void)focusCurrentPlatformApp { |
491 extensions::AppWindow* appWindow = | 514 extensions::AppWindow* appWindow = |
492 AppWindowRegistryUtil::GetAppWindowForNativeWindowAnyProfile( | 515 AppWindowRegistryUtil::GetAppWindowForNativeWindowAnyProfile( |
493 [NSApp keyWindow]); | 516 [NSApp keyWindow]); |
494 if (appWindow) | 517 if (appWindow) |
495 apps::ExtensionAppShimHandler::FocusAppForWindow(appWindow); | 518 apps::ExtensionAppShimHandler::FocusAppForWindow(appWindow); |
496 } | 519 } |
497 | 520 |
498 @end | 521 @end |
OLD | NEW |