Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(230)

Side by Side Diff: chrome/browser/ui/cocoa/apps/app_shim_menu_controller_mac.mm

Issue 23514021: Add Hide to app menu. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Save original key equivalent. Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/ui/cocoa/apps/app_shim_menu_controller_mac.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "apps/app_shim/extension_app_shim_handler_mac.h" 7 #include "apps/app_shim/extension_app_shim_handler_mac.h"
8 #include "apps/shell_window.h" 8 #include "apps/shell_window.h"
9 #include "apps/shell_window_registry.h" 9 #include "apps/shell_window_registry.h"
10 #include "base/strings/sys_string_conversions.h" 10 #include "base/strings/sys_string_conversions.h"
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
46 NSInteger menu_tag, 46 NSInteger menu_tag,
47 NSInteger item_tag) { 47 NSInteger item_tag) {
48 base::scoped_nsobject<NSMenuItem> item( 48 base::scoped_nsobject<NSMenuItem> item(
49 [GetItemByTag(menu_tag, item_tag) copy]); 49 [GetItemByTag(menu_tag, item_tag) copy]);
50 DCHECK(item); 50 DCHECK(item);
51 [[top_level_item submenu] addItem:item]; 51 [[top_level_item submenu] addItem:item];
52 } 52 }
53 53
54 } // namespace 54 } // namespace
55 55
56 // Used by AppShimMenuController to manage menu items that are a copy of a
57 // Chrome menu item but with a different action. This manages unsetting and
58 // restoring the original item's key equivalent, so that we can use the same
59 // key equivalent in the copied item with a different action.
60 @interface DoppelgangerMenuItem : NSObject {
61 @private
62 base::scoped_nsobject<NSMenuItem> menuItem_;
63 base::scoped_nsobject<NSMenuItem> sourceItem_;
64 base::scoped_nsobject<NSString> sourceKeyEquivalent_;
65 int resourceId_;
66 }
67
68 @property(readonly, nonatomic) NSMenuItem* menuItem;
69
70 // Get the source item using the tags and create the menu item.
71 - (id)initWithController:(AppShimMenuController*)controller
72 menuTag:(NSInteger)menuTag
73 itemTag:(NSInteger)itemTag
74 resourceId:(int)resourceId
75 action:(SEL)action
76 keyEquivalent:(NSString*)keyEquivalent;
77 // Set the title using |resourceId_| and unset the source item's key equivalent.
78 - (void)enableForApp:(const extensions::Extension*)app;
79 // Restore the source item's key equivalent.
80 - (void)disable;
81 @end
82
83 @implementation DoppelgangerMenuItem
84
85 - (NSMenuItem*)menuItem {
86 return menuItem_;
87 }
88
89 - (id)initWithController:(AppShimMenuController*)controller
90 menuTag:(NSInteger)menuTag
91 itemTag:(NSInteger)itemTag
92 resourceId:(int)resourceId
93 action:(SEL)action
94 keyEquivalent:(NSString*)keyEquivalent {
95 if ((self = [super init])) {
96 sourceItem_.reset([GetItemByTag(menuTag, itemTag) retain]);
97 DCHECK(sourceItem_);
98 sourceKeyEquivalent_.reset([[sourceItem_ keyEquivalent] copy]);
99 menuItem_.reset([[NSMenuItem alloc]
100 initWithTitle:@""
101 action:action
102 keyEquivalent:keyEquivalent]);
103 [menuItem_ setTarget:controller];
104 [menuItem_ setTag:itemTag];
105 resourceId_ = resourceId;
106 }
107 return self;
108 }
109
110 - (void)enableForApp:(const extensions::Extension*)app {
111 // It seems that two menu items that have the same key equivalent must also
112 // have the same action for the keyboard shortcut to work. (This refers to the
113 // original keyboard shortcut, regardless of any overrides set in OSX).
114 // In order to let the app menu items have a different action, we remove the
115 // key equivalent of the original items and restore them later.
116 [sourceItem_ setKeyEquivalent:@""];
117 if (!resourceId_)
118 return;
119
120 [menuItem_ setTitle:l10n_util::GetNSStringF(resourceId_,
121 base::UTF8ToUTF16(app->name()))];
122 }
123
124 - (void)disable {
125 // Restore the keyboard shortcut to Chrome. This just needs to be set back to
126 // the original keyboard shortcut, regardless of any overrides in OSX. The
127 // overrides still work as they are based on the title of the menu item.
128 [sourceItem_ setKeyEquivalent:sourceKeyEquivalent_];
129 }
130
131 @end
132
56 @interface AppShimMenuController () 133 @interface AppShimMenuController ()
57 // Construct the NSMenuItems for apps. 134 // Construct the NSMenuItems for apps.
58 - (void)buildAppMenuItems; 135 - (void)buildAppMenuItems;
59 // Register for NSWindow notifications. 136 // Register for NSWindow notifications.
60 - (void)registerEventHandlers; 137 - (void)registerEventHandlers;
61 // If the window is an app window, add or remove menu items. 138 // If the window is an app window, add or remove menu items.
62 - (void)windowMainStatusChanged:(NSNotification*)notification; 139 - (void)windowMainStatusChanged:(NSNotification*)notification;
63 // Add menu items for an app and hide Chrome menu items. 140 // Add menu items for an app and hide Chrome menu items.
64 - (void)addMenuItems:(const extensions::Extension*)app; 141 - (void)addMenuItems:(const extensions::Extension*)app;
65 // If the window belongs to the currently focused app, remove the menu items and 142 // If the window belongs to the currently focused app, remove the menu items and
66 // unhide Chrome menu items. 143 // unhide Chrome menu items.
67 - (void)removeMenuItems:(NSString*)appId; 144 - (void)removeMenuItems:(NSString*)appId;
68 // If the currently focused window belongs to a platform app, quit the app. 145 // If the currently focused window belongs to a platform app, quit the app.
69 - (void)quitCurrentPlatformApp; 146 - (void)quitCurrentPlatformApp;
147 // If the currently focused window belongs to a platform app, hide the app.
148 - (void)hideCurrentPlatformApp;
70 @end 149 @end
71 150
72 @implementation AppShimMenuController 151 @implementation AppShimMenuController
73 152
74 - (id)init { 153 - (id)init {
75 if ((self = [super init])) { 154 if ((self = [super init])) {
76 [self buildAppMenuItems]; 155 [self buildAppMenuItems];
77 [self registerEventHandlers]; 156 [self registerEventHandlers];
78 } 157 }
79 return self; 158 return self;
80 } 159 }
81 160
82 - (void)dealloc { 161 - (void)dealloc {
83 [[NSNotificationCenter defaultCenter] removeObserver:self]; 162 [[NSNotificationCenter defaultCenter] removeObserver:self];
84 [super dealloc]; 163 [super dealloc];
85 } 164 }
86 165
87 - (void)buildAppMenuItems { 166 - (void)buildAppMenuItems {
88 // Find the "Quit Chrome" menu item. 167 hideDoppelganger_.reset([[DoppelgangerMenuItem alloc]
89 chromeMenuQuitItem_.reset([GetItemByTag(IDC_CHROME_MENU, IDC_EXIT) retain]); 168 initWithController:self
90 DCHECK(chromeMenuQuitItem_); 169 menuTag:IDC_CHROME_MENU
170 itemTag:IDC_HIDE_APP
171 resourceId:IDS_HIDE_APP_MAC
172 action:@selector(hideCurrentPlatformApp)
173 keyEquivalent:@"h"]);
174 quitDoppelganger_.reset([[DoppelgangerMenuItem alloc]
175 initWithController:self
176 menuTag:IDC_CHROME_MENU
177 itemTag:IDC_EXIT
178 resourceId:IDS_EXIT_MAC
179 action:@selector(quitCurrentPlatformApp)
180 keyEquivalent:@"q"]);
91 181
92 // The app's menu. 182 // The app's menu.
93 appMenuItem_.reset([[NSMenuItem alloc] initWithTitle:@"" 183 appMenuItem_.reset([[NSMenuItem alloc] initWithTitle:@""
94 action:nil 184 action:nil
95 keyEquivalent:@""]); 185 keyEquivalent:@""]);
96 base::scoped_nsobject<NSMenu> appMenu([[NSMenu alloc] initWithTitle:@""]); 186 base::scoped_nsobject<NSMenu> appMenu([[NSMenu alloc] initWithTitle:@""]);
187 [appMenuItem_ setSubmenu:appMenu];
97 [appMenu setAutoenablesItems:NO]; 188 [appMenu setAutoenablesItems:NO];
98 NSMenuItem* appMenuQuitItem = 189
99 [appMenu addItemWithTitle:@"" 190 [appMenu addItem:[hideDoppelganger_ menuItem]];
100 action:@selector(quitCurrentPlatformApp) 191 [appMenu addItem:[NSMenuItem separatorItem]];
101 keyEquivalent:@"q"]; 192 [appMenu addItem:[quitDoppelganger_ menuItem]];
102 [appMenuQuitItem setKeyEquivalentModifierMask:
103 [chromeMenuQuitItem_ keyEquivalentModifierMask]];
104 [appMenuQuitItem setTarget:self];
105 [appMenuItem_ setSubmenu:appMenu];
106 193
107 // File menu. 194 // File menu.
108 fileMenuItem_.reset([NewTopLevelItemFrom(IDC_FILE_MENU) retain]); 195 fileMenuItem_.reset([NewTopLevelItemFrom(IDC_FILE_MENU) retain]);
109 AddDuplicateItem(fileMenuItem_, IDC_FILE_MENU, IDC_CLOSE_WINDOW); 196 AddDuplicateItem(fileMenuItem_, IDC_FILE_MENU, IDC_CLOSE_WINDOW);
110 197
111 // Edit menu. 198 // Edit menu.
112 editMenuItem_.reset([NewTopLevelItemFrom(IDC_EDIT_MENU) retain]); 199 editMenuItem_.reset([NewTopLevelItemFrom(IDC_EDIT_MENU) retain]);
113 AddDuplicateItem(editMenuItem_, IDC_EDIT_MENU, IDC_CONTENT_CONTEXT_UNDO); 200 AddDuplicateItem(editMenuItem_, IDC_EDIT_MENU, IDC_CONTENT_CONTEXT_UNDO);
114 AddDuplicateItem(editMenuItem_, IDC_EDIT_MENU, IDC_CONTENT_CONTEXT_REDO); 201 AddDuplicateItem(editMenuItem_, IDC_EDIT_MENU, IDC_CONTENT_CONTEXT_REDO);
115 [[editMenuItem_ submenu] addItem:[NSMenuItem separatorItem]]; 202 [[editMenuItem_ submenu] addItem:[NSMenuItem separatorItem]];
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 return; 265 return;
179 266
180 [self removeMenuItems:appId_]; 267 [self removeMenuItems:appId_];
181 appId_.reset([appId copy]); 268 appId_.reset([appId copy]);
182 269
183 // Hide Chrome menu items. 270 // Hide Chrome menu items.
184 NSMenu* mainMenu = [NSApp mainMenu]; 271 NSMenu* mainMenu = [NSApp mainMenu];
185 for (NSMenuItem* item in [mainMenu itemArray]) 272 for (NSMenuItem* item in [mainMenu itemArray])
186 [item setHidden:YES]; 273 [item setHidden:YES];
187 274
188 NSString* localizedQuitApp = 275 [hideDoppelganger_ enableForApp:app];
189 l10n_util::GetNSStringF(IDS_EXIT_MAC, base::UTF8ToUTF16(app->name())); 276 [quitDoppelganger_ enableForApp:app];
190 NSMenuItem* appMenuQuitItem = [[[appMenuItem_ submenu] itemArray] lastObject];
191 [appMenuQuitItem setTitle:localizedQuitApp];
192
193 // It seems that two menu items that have the same key equivalent must also
194 // have the same action for the keyboard shortcut to work. (This refers to the
195 // original keyboard shortcut, regardless of any overrides set in OSX).
196 // In order to let the appMenuQuitItem have a different action, we remove the
197 // key equivalent from the chromeMenuQuitItem and restore it later.
198 [chromeMenuQuitItem_ setKeyEquivalent:@""];
199 277
200 [appMenuItem_ setTitle:appId]; 278 [appMenuItem_ setTitle:appId];
201 [[appMenuItem_ submenu] setTitle:title]; 279 [[appMenuItem_ submenu] setTitle:title];
202 280
203 [mainMenu addItem:appMenuItem_]; 281 [mainMenu addItem:appMenuItem_];
204 [mainMenu addItem:fileMenuItem_]; 282 [mainMenu addItem:fileMenuItem_];
205 [mainMenu addItem:editMenuItem_]; 283 [mainMenu addItem:editMenuItem_];
206 [mainMenu addItem:windowMenuItem_]; 284 [mainMenu addItem:windowMenuItem_];
207 } 285 }
208 286
209 - (void)removeMenuItems:(NSString*)appId { 287 - (void)removeMenuItems:(NSString*)appId {
210 if (![appId_ isEqualToString:appId]) 288 if (![appId_ isEqualToString:appId])
211 return; 289 return;
212 290
213 appId_.reset(); 291 appId_.reset();
214 292
215 NSMenu* mainMenu = [NSApp mainMenu]; 293 NSMenu* mainMenu = [NSApp mainMenu];
216 [mainMenu removeItem:appMenuItem_]; 294 [mainMenu removeItem:appMenuItem_];
217 [mainMenu removeItem:fileMenuItem_]; 295 [mainMenu removeItem:fileMenuItem_];
218 [mainMenu removeItem:editMenuItem_]; 296 [mainMenu removeItem:editMenuItem_];
219 [mainMenu removeItem:windowMenuItem_]; 297 [mainMenu removeItem:windowMenuItem_];
220 298
221 // Restore the Chrome main menu bar. 299 // Restore the Chrome main menu bar.
222 for (NSMenuItem* item in [mainMenu itemArray]) 300 for (NSMenuItem* item in [mainMenu itemArray])
223 [item setHidden:NO]; 301 [item setHidden:NO];
224 302
225 // Restore the keyboard shortcut to Chrome. This just needs to be set back to 303 [hideDoppelganger_ disable];
226 // the original keyboard shortcut, regardless of any overrides in OSX. The 304 [quitDoppelganger_ disable];
227 // overrides still work as they are based on the title of the menu item.
228 [chromeMenuQuitItem_ setKeyEquivalent:@"q"];
229 } 305 }
230 306
231 - (void)quitCurrentPlatformApp { 307 - (void)quitCurrentPlatformApp {
232 apps::ShellWindow* shellWindow = 308 apps::ShellWindow* shellWindow =
233 apps::ShellWindowRegistry::GetShellWindowForNativeWindowAnyProfile( 309 apps::ShellWindowRegistry::GetShellWindowForNativeWindowAnyProfile(
234 [NSApp keyWindow]); 310 [NSApp keyWindow]);
235 if (shellWindow) 311 if (shellWindow)
236 apps::ExtensionAppShimHandler::QuitAppForWindow(shellWindow); 312 apps::ExtensionAppShimHandler::QuitAppForWindow(shellWindow);
237 } 313 }
238 314
315 - (void)hideCurrentPlatformApp {
316 apps::ShellWindow* shellWindow =
317 apps::ShellWindowRegistry::GetShellWindowForNativeWindowAnyProfile(
318 [NSApp keyWindow]);
319 if (shellWindow)
320 apps::ExtensionAppShimHandler::HideAppForWindow(shellWindow);
321 }
322
239 @end 323 @end
OLDNEW
« no previous file with comments | « chrome/browser/ui/cocoa/apps/app_shim_menu_controller_mac.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698