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]); | |
tapted
2015/02/04 23:55:59
DCHECK(menuItem_);
DCHECK(sourceItem_);
ObjC like
mitchellj
2015/02/05 00:01:34
Done.
| |
191 sourceKeyEquivalent_.reset([[sourceItem_ keyEquivalent] copy]); | |
192 resourceId_ = 0; | |
tapted
2015/02/04 23:55:59
nit: this is redundant for ObjC (it's guaranteed t
mitchellj
2015/02/05 00:01:34
Done.
| |
193 } | |
194 return self; | |
195 } | |
196 | |
176 - (void)enableForApp:(const extensions::Extension*)app { | 197 - (void)enableForApp:(const extensions::Extension*)app { |
177 // It seems that two menu items that have the same key equivalent must also | 198 // 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 | 199 // 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). | 200 // 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 | 201 // 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. | 202 // key equivalent of the original items and restore them later. |
182 [sourceItem_ setKeyEquivalent:@""]; | 203 [sourceItem_ setKeyEquivalent:@""]; |
183 if (!resourceId_) | 204 if (!resourceId_) |
184 return; | 205 return; |
185 | 206 |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
253 resourceId:IDS_EXIT_MAC | 274 resourceId:IDS_EXIT_MAC |
254 action:@selector(quitCurrentPlatformApp) | 275 action:@selector(quitCurrentPlatformApp) |
255 keyEquivalent:@"q"]); | 276 keyEquivalent:@"q"]); |
256 newDoppelganger_.reset([[DoppelgangerMenuItem alloc] | 277 newDoppelganger_.reset([[DoppelgangerMenuItem alloc] |
257 initWithController:self | 278 initWithController:self |
258 menuTag:IDC_FILE_MENU | 279 menuTag:IDC_FILE_MENU |
259 itemTag:IDC_NEW_WINDOW | 280 itemTag:IDC_NEW_WINDOW |
260 resourceId:0 | 281 resourceId:0 |
261 action:nil | 282 action:nil |
262 keyEquivalent:@"n"]); | 283 keyEquivalent:@"n"]); |
284 // Since the "Close Window" menu item will have the same shortcut as "Close | |
285 // Tab" on the Chrome menu, we need to create a doppelganger. | |
286 closeWindowDoppelganger_.reset([[DoppelgangerMenuItem alloc] | |
287 initWithMenuTag:IDC_FILE_MENU | |
288 sourceItemTag:IDC_CLOSE_TAB | |
289 targetItemTag:IDC_CLOSE_WINDOW | |
290 keyEquivalent:@"w"]); | |
263 // For apps, the "Window" part of "New Window" is dropped to match the default | 291 // For apps, the "Window" part of "New Window" is dropped to match the default |
264 // menu set given to Cocoa Apps. | 292 // menu set given to Cocoa Apps. |
265 [[newDoppelganger_ menuItem] setTitle:l10n_util::GetNSString(IDS_NEW_MAC)]; | 293 [[newDoppelganger_ menuItem] setTitle:l10n_util::GetNSString(IDS_NEW_MAC)]; |
266 openDoppelganger_.reset([[DoppelgangerMenuItem alloc] | 294 openDoppelganger_.reset([[DoppelgangerMenuItem alloc] |
267 initWithController:self | 295 initWithController:self |
268 menuTag:IDC_FILE_MENU | 296 menuTag:IDC_FILE_MENU |
269 itemTag:IDC_OPEN_FILE | 297 itemTag:IDC_OPEN_FILE |
270 resourceId:0 | 298 resourceId:0 |
271 action:nil | 299 action:nil |
272 keyEquivalent:@"o"]); | 300 keyEquivalent:@"o"]); |
(...skipping 18 matching lines...) Expand all Loading... | |
291 [appMenu addItem:[NSMenuItem separatorItem]]; | 319 [appMenu addItem:[NSMenuItem separatorItem]]; |
292 [appMenu addItem:[hideDoppelganger_ menuItem]]; | 320 [appMenu addItem:[hideDoppelganger_ menuItem]]; |
293 [appMenu addItem:[NSMenuItem separatorItem]]; | 321 [appMenu addItem:[NSMenuItem separatorItem]]; |
294 [appMenu addItem:[quitDoppelganger_ menuItem]]; | 322 [appMenu addItem:[quitDoppelganger_ menuItem]]; |
295 | 323 |
296 // File menu. | 324 // File menu. |
297 fileMenuItem_.reset([NewTopLevelItemFrom(IDC_FILE_MENU) retain]); | 325 fileMenuItem_.reset([NewTopLevelItemFrom(IDC_FILE_MENU) retain]); |
298 [[fileMenuItem_ submenu] addItem:[newDoppelganger_ menuItem]]; | 326 [[fileMenuItem_ submenu] addItem:[newDoppelganger_ menuItem]]; |
299 [[fileMenuItem_ submenu] addItem:[openDoppelganger_ menuItem]]; | 327 [[fileMenuItem_ submenu] addItem:[openDoppelganger_ menuItem]]; |
300 [[fileMenuItem_ submenu] addItem:[NSMenuItem separatorItem]]; | 328 [[fileMenuItem_ submenu] addItem:[NSMenuItem separatorItem]]; |
301 AddDuplicateItem(fileMenuItem_, IDC_FILE_MENU, IDC_CLOSE_WINDOW); | 329 [[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 | 330 |
311 // Edit menu. We copy the menu because the last two items, "Start Dictation" | 331 // 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 | 332 // and "Special Characters" are added by OSX, so we can't copy them |
313 // explicitly. | 333 // explicitly. |
314 editMenuItem_.reset([[[NSApp mainMenu] itemWithTag:IDC_EDIT_MENU] copy]); | 334 editMenuItem_.reset([[[NSApp mainMenu] itemWithTag:IDC_EDIT_MENU] copy]); |
315 | 335 |
316 // View menu. Remove "Always Show Bookmark Bar" and separator. | 336 // View menu. Remove "Always Show Bookmark Bar" and separator. |
317 viewMenuItem_.reset([[[NSApp mainMenu] itemWithTag:IDC_VIEW_MENU] copy]); | 337 viewMenuItem_.reset([[[NSApp mainMenu] itemWithTag:IDC_VIEW_MENU] copy]); |
318 RemoveMenuItemWithTag(viewMenuItem_, IDC_SHOW_BOOKMARK_BAR, YES); | 338 RemoveMenuItemWithTag(viewMenuItem_, IDC_SHOW_BOOKMARK_BAR, YES); |
319 | 339 |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
400 // Hide Chrome menu items. | 420 // Hide Chrome menu items. |
401 NSMenu* mainMenu = [NSApp mainMenu]; | 421 NSMenu* mainMenu = [NSApp mainMenu]; |
402 for (NSMenuItem* item in [mainMenu itemArray]) | 422 for (NSMenuItem* item in [mainMenu itemArray]) |
403 [item setHidden:YES]; | 423 [item setHidden:YES]; |
404 | 424 |
405 [aboutDoppelganger_ enableForApp:app]; | 425 [aboutDoppelganger_ enableForApp:app]; |
406 [hideDoppelganger_ enableForApp:app]; | 426 [hideDoppelganger_ enableForApp:app]; |
407 [quitDoppelganger_ enableForApp:app]; | 427 [quitDoppelganger_ enableForApp:app]; |
408 [newDoppelganger_ enableForApp:app]; | 428 [newDoppelganger_ enableForApp:app]; |
409 [openDoppelganger_ enableForApp:app]; | 429 [openDoppelganger_ enableForApp:app]; |
430 [closeWindowDoppelganger_ enableForApp:app]; | |
410 | 431 |
411 [appMenuItem_ setTitle:appId]; | 432 [appMenuItem_ setTitle:appId]; |
412 [[appMenuItem_ submenu] setTitle:title]; | 433 [[appMenuItem_ submenu] setTitle:title]; |
413 | 434 |
414 [mainMenu addItem:appMenuItem_]; | 435 [mainMenu addItem:appMenuItem_]; |
415 [mainMenu addItem:fileMenuItem_]; | 436 [mainMenu addItem:fileMenuItem_]; |
416 | 437 |
417 SetItemWithTagVisible(editMenuItem_, | 438 SetItemWithTagVisible(editMenuItem_, |
418 IDC_CONTENT_CONTEXT_PASTE_AND_MATCH_STYLE, | 439 IDC_CONTENT_CONTEXT_PASTE_AND_MATCH_STYLE, |
419 app->is_hosted_app(), true); | 440 app->is_hosted_app(), true); |
(...skipping 26 matching lines...) Expand all Loading... | |
446 | 467 |
447 // Restore the Chrome main menu bar. | 468 // Restore the Chrome main menu bar. |
448 for (NSMenuItem* item in [mainMenu itemArray]) | 469 for (NSMenuItem* item in [mainMenu itemArray]) |
449 [item setHidden:NO]; | 470 [item setHidden:NO]; |
450 | 471 |
451 [aboutDoppelganger_ disable]; | 472 [aboutDoppelganger_ disable]; |
452 [hideDoppelganger_ disable]; | 473 [hideDoppelganger_ disable]; |
453 [quitDoppelganger_ disable]; | 474 [quitDoppelganger_ disable]; |
454 [newDoppelganger_ disable]; | 475 [newDoppelganger_ disable]; |
455 [openDoppelganger_ disable]; | 476 [openDoppelganger_ disable]; |
477 [closeWindowDoppelganger_ disable]; | |
456 } | 478 } |
457 | 479 |
458 - (void)quitCurrentPlatformApp { | 480 - (void)quitCurrentPlatformApp { |
459 extensions::AppWindow* appWindow = | 481 extensions::AppWindow* appWindow = |
460 AppWindowRegistryUtil::GetAppWindowForNativeWindowAnyProfile( | 482 AppWindowRegistryUtil::GetAppWindowForNativeWindowAnyProfile( |
461 [NSApp keyWindow]); | 483 [NSApp keyWindow]); |
462 if (appWindow) { | 484 if (appWindow) { |
463 apps::ExtensionAppShimHandler::QuitAppForWindow(appWindow); | 485 apps::ExtensionAppShimHandler::QuitAppForWindow(appWindow); |
464 } else { | 486 } else { |
465 Browser* browser = chrome::FindBrowserWithWindow([NSApp keyWindow]); | 487 Browser* browser = chrome::FindBrowserWithWindow([NSApp keyWindow]); |
(...skipping 23 matching lines...) Expand all Loading... | |
489 | 511 |
490 - (void)focusCurrentPlatformApp { | 512 - (void)focusCurrentPlatformApp { |
491 extensions::AppWindow* appWindow = | 513 extensions::AppWindow* appWindow = |
492 AppWindowRegistryUtil::GetAppWindowForNativeWindowAnyProfile( | 514 AppWindowRegistryUtil::GetAppWindowForNativeWindowAnyProfile( |
493 [NSApp keyWindow]); | 515 [NSApp keyWindow]); |
494 if (appWindow) | 516 if (appWindow) |
495 apps::ExtensionAppShimHandler::FocusAppForWindow(appWindow); | 517 apps::ExtensionAppShimHandler::FocusAppForWindow(appWindow); |
496 } | 518 } |
497 | 519 |
498 @end | 520 @end |
OLD | NEW |