| Index: chrome/browser/ui/cocoa/apps/app_shim_menu_controller_mac.mm
|
| diff --git a/chrome/browser/ui/cocoa/apps/app_shim_menu_controller_mac.mm b/chrome/browser/ui/cocoa/apps/app_shim_menu_controller_mac.mm
|
| index bcc272e0029b835baffa84ae0a3c02a9dd97575e..5332b0978ec34059775253238ce3809ee40819b4 100644
|
| --- a/chrome/browser/ui/cocoa/apps/app_shim_menu_controller_mac.mm
|
| +++ b/chrome/browser/ui/cocoa/apps/app_shim_menu_controller_mac.mm
|
| @@ -53,6 +53,83 @@ void AddDuplicateItem(NSMenuItem* top_level_item,
|
|
|
| } // namespace
|
|
|
| +// Used by AppShimMenuController to manage menu items that are a copy of a
|
| +// Chrome menu item but with a different action. This manages unsetting and
|
| +// restoring the original item's key equivalent, so that we can use the same
|
| +// key equivalent in the copied item with a different action.
|
| +@interface DoppelgangerMenuItem : NSObject {
|
| + @private
|
| + base::scoped_nsobject<NSMenuItem> menuItem_;
|
| + base::scoped_nsobject<NSMenuItem> sourceItem_;
|
| + base::scoped_nsobject<NSString> sourceKeyEquivalent_;
|
| + int resourceId_;
|
| +}
|
| +
|
| +@property(readonly, nonatomic) NSMenuItem* menuItem;
|
| +
|
| +// Get the source item using the tags and create the menu item.
|
| +- (id)initWithController:(AppShimMenuController*)controller
|
| + menuTag:(NSInteger)menuTag
|
| + itemTag:(NSInteger)itemTag
|
| + resourceId:(int)resourceId
|
| + action:(SEL)action
|
| + keyEquivalent:(NSString*)keyEquivalent;
|
| +// Set the title using |resourceId_| and unset the source item's key equivalent.
|
| +- (void)enableForApp:(const extensions::Extension*)app;
|
| +// Restore the source item's key equivalent.
|
| +- (void)disable;
|
| +@end
|
| +
|
| +@implementation DoppelgangerMenuItem
|
| +
|
| +- (NSMenuItem*)menuItem {
|
| + return menuItem_;
|
| +}
|
| +
|
| +- (id)initWithController:(AppShimMenuController*)controller
|
| + menuTag:(NSInteger)menuTag
|
| + itemTag:(NSInteger)itemTag
|
| + resourceId:(int)resourceId
|
| + action:(SEL)action
|
| + keyEquivalent:(NSString*)keyEquivalent {
|
| + if ((self = [super init])) {
|
| + sourceItem_.reset([GetItemByTag(menuTag, itemTag) retain]);
|
| + DCHECK(sourceItem_);
|
| + sourceKeyEquivalent_.reset([[sourceItem_ keyEquivalent] copy]);
|
| + menuItem_.reset([[NSMenuItem alloc]
|
| + initWithTitle:@""
|
| + action:action
|
| + keyEquivalent:keyEquivalent]);
|
| + [menuItem_ setTarget:controller];
|
| + [menuItem_ setTag:itemTag];
|
| + resourceId_ = resourceId;
|
| + }
|
| + return self;
|
| +}
|
| +
|
| +- (void)enableForApp:(const extensions::Extension*)app {
|
| + // It seems that two menu items that have the same key equivalent must also
|
| + // have the same action for the keyboard shortcut to work. (This refers to the
|
| + // original keyboard shortcut, regardless of any overrides set in OSX).
|
| + // In order to let the app menu items have a different action, we remove the
|
| + // key equivalent of the original items and restore them later.
|
| + [sourceItem_ setKeyEquivalent:@""];
|
| + if (!resourceId_)
|
| + return;
|
| +
|
| + [menuItem_ setTitle:l10n_util::GetNSStringF(resourceId_,
|
| + base::UTF8ToUTF16(app->name()))];
|
| +}
|
| +
|
| +- (void)disable {
|
| + // Restore the keyboard shortcut to Chrome. This just needs to be set back to
|
| + // the original keyboard shortcut, regardless of any overrides in OSX. The
|
| + // overrides still work as they are based on the title of the menu item.
|
| + [sourceItem_ setKeyEquivalent:sourceKeyEquivalent_];
|
| +}
|
| +
|
| +@end
|
| +
|
| @interface AppShimMenuController ()
|
| // Construct the NSMenuItems for apps.
|
| - (void)buildAppMenuItems;
|
| @@ -67,6 +144,8 @@ void AddDuplicateItem(NSMenuItem* top_level_item,
|
| - (void)removeMenuItems:(NSString*)appId;
|
| // If the currently focused window belongs to a platform app, quit the app.
|
| - (void)quitCurrentPlatformApp;
|
| +// If the currently focused window belongs to a platform app, hide the app.
|
| +- (void)hideCurrentPlatformApp;
|
| @end
|
|
|
| @implementation AppShimMenuController
|
| @@ -85,24 +164,32 @@ void AddDuplicateItem(NSMenuItem* top_level_item,
|
| }
|
|
|
| - (void)buildAppMenuItems {
|
| - // Find the "Quit Chrome" menu item.
|
| - chromeMenuQuitItem_.reset([GetItemByTag(IDC_CHROME_MENU, IDC_EXIT) retain]);
|
| - DCHECK(chromeMenuQuitItem_);
|
| + hideDoppelganger_.reset([[DoppelgangerMenuItem alloc]
|
| + initWithController:self
|
| + menuTag:IDC_CHROME_MENU
|
| + itemTag:IDC_HIDE_APP
|
| + resourceId:IDS_HIDE_APP_MAC
|
| + action:@selector(hideCurrentPlatformApp)
|
| + keyEquivalent:@"h"]);
|
| + quitDoppelganger_.reset([[DoppelgangerMenuItem alloc]
|
| + initWithController:self
|
| + menuTag:IDC_CHROME_MENU
|
| + itemTag:IDC_EXIT
|
| + resourceId:IDS_EXIT_MAC
|
| + action:@selector(quitCurrentPlatformApp)
|
| + keyEquivalent:@"q"]);
|
|
|
| // The app's menu.
|
| appMenuItem_.reset([[NSMenuItem alloc] initWithTitle:@""
|
| action:nil
|
| keyEquivalent:@""]);
|
| base::scoped_nsobject<NSMenu> appMenu([[NSMenu alloc] initWithTitle:@""]);
|
| - [appMenu setAutoenablesItems:NO];
|
| - NSMenuItem* appMenuQuitItem =
|
| - [appMenu addItemWithTitle:@""
|
| - action:@selector(quitCurrentPlatformApp)
|
| - keyEquivalent:@"q"];
|
| - [appMenuQuitItem setKeyEquivalentModifierMask:
|
| - [chromeMenuQuitItem_ keyEquivalentModifierMask]];
|
| - [appMenuQuitItem setTarget:self];
|
| [appMenuItem_ setSubmenu:appMenu];
|
| + [appMenu setAutoenablesItems:NO];
|
| +
|
| + [appMenu addItem:[hideDoppelganger_ menuItem]];
|
| + [appMenu addItem:[NSMenuItem separatorItem]];
|
| + [appMenu addItem:[quitDoppelganger_ menuItem]];
|
|
|
| // File menu.
|
| fileMenuItem_.reset([NewTopLevelItemFrom(IDC_FILE_MENU) retain]);
|
| @@ -185,17 +272,8 @@ void AddDuplicateItem(NSMenuItem* top_level_item,
|
| for (NSMenuItem* item in [mainMenu itemArray])
|
| [item setHidden:YES];
|
|
|
| - NSString* localizedQuitApp =
|
| - l10n_util::GetNSStringF(IDS_EXIT_MAC, base::UTF8ToUTF16(app->name()));
|
| - NSMenuItem* appMenuQuitItem = [[[appMenuItem_ submenu] itemArray] lastObject];
|
| - [appMenuQuitItem setTitle:localizedQuitApp];
|
| -
|
| - // It seems that two menu items that have the same key equivalent must also
|
| - // have the same action for the keyboard shortcut to work. (This refers to the
|
| - // original keyboard shortcut, regardless of any overrides set in OSX).
|
| - // In order to let the appMenuQuitItem have a different action, we remove the
|
| - // key equivalent from the chromeMenuQuitItem and restore it later.
|
| - [chromeMenuQuitItem_ setKeyEquivalent:@""];
|
| + [hideDoppelganger_ enableForApp:app];
|
| + [quitDoppelganger_ enableForApp:app];
|
|
|
| [appMenuItem_ setTitle:appId];
|
| [[appMenuItem_ submenu] setTitle:title];
|
| @@ -222,10 +300,8 @@ void AddDuplicateItem(NSMenuItem* top_level_item,
|
| for (NSMenuItem* item in [mainMenu itemArray])
|
| [item setHidden:NO];
|
|
|
| - // Restore the keyboard shortcut to Chrome. This just needs to be set back to
|
| - // the original keyboard shortcut, regardless of any overrides in OSX. The
|
| - // overrides still work as they are based on the title of the menu item.
|
| - [chromeMenuQuitItem_ setKeyEquivalent:@"q"];
|
| + [hideDoppelganger_ disable];
|
| + [quitDoppelganger_ disable];
|
| }
|
|
|
| - (void)quitCurrentPlatformApp {
|
| @@ -236,4 +312,12 @@ void AddDuplicateItem(NSMenuItem* top_level_item,
|
| apps::ExtensionAppShimHandler::QuitAppForWindow(shellWindow);
|
| }
|
|
|
| +- (void)hideCurrentPlatformApp {
|
| + apps::ShellWindow* shellWindow =
|
| + apps::ShellWindowRegistry::GetShellWindowForNativeWindowAnyProfile(
|
| + [NSApp keyWindow]);
|
| + if (shellWindow)
|
| + apps::ExtensionAppShimHandler::HideAppForWindow(shellWindow);
|
| +}
|
| +
|
| @end
|
|
|