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 "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" |
11 #include "base/strings/utf_string_conversions.h" | 11 #include "base/strings/utf_string_conversions.h" |
12 #include "chrome/app/chrome_command_ids.h" | |
12 #import "chrome/browser/ui/cocoa/apps/native_app_window_cocoa.h" | 13 #import "chrome/browser/ui/cocoa/apps/native_app_window_cocoa.h" |
13 #include "chrome/common/extensions/extension.h" | 14 #include "chrome/common/extensions/extension.h" |
14 #include "grit/generated_resources.h" | 15 #include "grit/generated_resources.h" |
15 #include "ui/base/l10n/l10n_util.h" | 16 #include "ui/base/l10n/l10n_util.h" |
16 #include "ui/base/l10n/l10n_util_mac.h" | 17 #include "ui/base/l10n/l10n_util_mac.h" |
17 | 18 |
19 namespace { | |
20 | |
21 // Gets an item from the main menu given the tag of the top level item | |
22 // |menu_tag| and the tag of the item |item_tag|. | |
23 NSMenuItem* GetItemByTag(NSInteger menu_tag, NSInteger item_tag) { | |
24 return [[[[NSApp mainMenu] itemWithTag:menu_tag] submenu] | |
25 itemWithTag:item_tag]; | |
26 } | |
27 | |
28 // Finds a top level menu item using |menu_tag| and creates a new NSMenuItem | |
29 // with the same title, action, and key equivalent. | |
30 NSMenuItem* DuplicateTopLevelItem(NSInteger menu_tag) { | |
31 NSMenuItem* original = [[NSApp mainMenu] itemWithTag:menu_tag]; | |
32 base::scoped_nsobject<NSMenuItem> item([[NSMenuItem alloc] | |
33 initWithTitle:[original title] | |
34 action:[original action] | |
35 keyEquivalent:[original keyEquivalent]]); | |
tapted
2013/08/29 06:06:19
Can top-level items have key equivalents, or actio
jackhou1
2013/08/29 06:30:03
Done.
| |
36 if ([original hasSubmenu]) { | |
tapted
2013/08/29 06:06:19
DCHECK? I think later code assumes that a submenu
jackhou1
2013/08/29 06:30:03
Done.
| |
37 base::scoped_nsobject<NSMenu> sub_menu([[NSMenu alloc] | |
38 initWithTitle:[[original submenu] title]]); | |
39 [item setSubmenu:sub_menu]; | |
40 } | |
41 return item.autorelease(); | |
42 } | |
43 | |
44 // Finds an item using |menu_tag| and |item_tag| and adds a duplicate of it to | |
45 // the submenu of |top_level_item|. | |
46 NSMenuItem* AddDuplicateItem(NSMenuItem* top_level_item, | |
tapted
2013/08/29 06:06:19
return void?
jackhou1
2013/08/29 06:30:03
Done.
| |
47 NSInteger menu_tag, | |
48 NSInteger item_tag) { | |
49 base::scoped_nsobject<NSMenuItem> item( | |
50 [GetItemByTag(menu_tag, item_tag) copy]); | |
51 [[top_level_item submenu] addItem:item]; | |
52 return item; | |
53 } | |
54 | |
55 } // namespace | |
56 | |
18 @interface AppShimMenuController () | 57 @interface AppShimMenuController () |
19 // Construct the NSMenuItems for apps. | 58 // Construct the NSMenuItems for apps. |
20 - (void)buildAppMenuItems; | 59 - (void)buildAppMenuItems; |
21 // Register for NSWindow notifications. | 60 // Register for NSWindow notifications. |
22 - (void)registerEventHandlers; | 61 - (void)registerEventHandlers; |
23 // If the window is an app window, add or remove menu items. | 62 // If the window is an app window, add or remove menu items. |
24 - (void)windowMainStatusChanged:(NSNotification*)notification; | 63 - (void)windowMainStatusChanged:(NSNotification*)notification; |
25 // Add menu items for an app and hide Chrome menu items. | 64 // Add menu items for an app and hide Chrome menu items. |
26 - (void)addMenuItems:(const extensions::Extension*)app; | 65 - (void)addMenuItems:(const extensions::Extension*)app; |
27 // If the window belongs to the currently focused app, remove the menu items and | 66 // If the window belongs to the currently focused app, remove the menu items and |
(...skipping 13 matching lines...) Expand all Loading... | |
41 return self; | 80 return self; |
42 } | 81 } |
43 | 82 |
44 - (void)dealloc { | 83 - (void)dealloc { |
45 [[NSNotificationCenter defaultCenter] removeObserver:self]; | 84 [[NSNotificationCenter defaultCenter] removeObserver:self]; |
46 [super dealloc]; | 85 [super dealloc]; |
47 } | 86 } |
48 | 87 |
49 - (void)buildAppMenuItems { | 88 - (void)buildAppMenuItems { |
50 // Find the "Quit Chrome" menu item. | 89 // Find the "Quit Chrome" menu item. |
51 NSMenu* chromeMenu = [[[NSApp mainMenu] itemAtIndex:0] submenu]; | 90 NSMenuItem* chromeMenuQuitItem = GetItemByTag(IDC_CHROME_MENU, IDC_EXIT); |
tapted
2013/08/29 06:06:19
nit: probably don't need this temporary any more
jackhou1
2013/08/29 06:30:03
Done.
| |
52 for (NSMenuItem* item in [chromeMenu itemArray]) { | 91 chromeMenuQuitItem_.reset([chromeMenuQuitItem retain]); |
53 if ([item action] == @selector(terminate:)) { | |
54 chromeMenuQuitItem_.reset([item retain]); | |
55 break; | |
56 } | |
57 } | |
58 DCHECK(chromeMenuQuitItem_); | 92 DCHECK(chromeMenuQuitItem_); |
59 | 93 |
94 // The app's menu. | |
60 appMenuItem_.reset([[NSMenuItem alloc] initWithTitle:@"" | 95 appMenuItem_.reset([[NSMenuItem alloc] initWithTitle:@"" |
61 action:nil | 96 action:nil |
62 keyEquivalent:@""]); | 97 keyEquivalent:@""]); |
63 base::scoped_nsobject<NSMenu> appMenu([[NSMenu alloc] initWithTitle:@""]); | 98 base::scoped_nsobject<NSMenu> appMenu([[NSMenu alloc] initWithTitle:@""]); |
64 [appMenu setAutoenablesItems:NO]; | 99 [appMenu setAutoenablesItems:NO]; |
65 NSMenuItem* appMenuQuitItem = | 100 NSMenuItem* appMenuQuitItem = |
66 [appMenu addItemWithTitle:@"" | 101 [appMenu addItemWithTitle:@"" |
67 action:@selector(quitCurrentPlatformApp) | 102 action:@selector(quitCurrentPlatformApp) |
68 keyEquivalent:@"q"]; | 103 keyEquivalent:@"q"]; |
69 [appMenuQuitItem setKeyEquivalentModifierMask: | 104 [appMenuQuitItem setKeyEquivalentModifierMask: |
70 [chromeMenuQuitItem_ keyEquivalentModifierMask]]; | 105 [chromeMenuQuitItem_ keyEquivalentModifierMask]]; |
71 [appMenuQuitItem setTarget:self]; | 106 [appMenuQuitItem setTarget:self]; |
72 [appMenuItem_ setSubmenu:appMenu]; | 107 [appMenuItem_ setSubmenu:appMenu]; |
108 | |
109 // File menu. | |
110 fileMenuItem_.reset([DuplicateTopLevelItem(IDC_FILE_MENU) retain]); | |
111 AddDuplicateItem(fileMenuItem_, IDC_FILE_MENU, IDC_CLOSE_WINDOW); | |
112 | |
113 // Edit menu. | |
114 editMenuItem_.reset([DuplicateTopLevelItem(IDC_EDIT_MENU) retain]); | |
115 AddDuplicateItem(editMenuItem_, IDC_EDIT_MENU, IDC_CONTENT_CONTEXT_UNDO); | |
116 AddDuplicateItem(editMenuItem_, IDC_EDIT_MENU, IDC_CONTENT_CONTEXT_REDO); | |
117 [[editMenuItem_ submenu] addItem:[NSMenuItem separatorItem]]; | |
118 AddDuplicateItem(editMenuItem_, IDC_EDIT_MENU, IDC_CONTENT_CONTEXT_CUT); | |
119 AddDuplicateItem(editMenuItem_, IDC_EDIT_MENU, IDC_CONTENT_CONTEXT_COPY); | |
120 AddDuplicateItem(editMenuItem_, IDC_EDIT_MENU, IDC_CONTENT_CONTEXT_PASTE); | |
121 AddDuplicateItem(editMenuItem_, IDC_EDIT_MENU, IDC_CONTENT_CONTEXT_DELETE); | |
122 AddDuplicateItem(editMenuItem_, IDC_EDIT_MENU, IDC_CONTENT_CONTEXT_SELECTALL); | |
123 | |
124 // Window menu. | |
125 windowMenuItem_.reset([DuplicateTopLevelItem(IDC_WINDOW_MENU) retain]); | |
126 AddDuplicateItem(windowMenuItem_, IDC_WINDOW_MENU, IDC_MINIMIZE); | |
127 AddDuplicateItem(windowMenuItem_, IDC_WINDOW_MENU, IDC_MAXIMIZE); | |
128 [[windowMenuItem_ submenu] addItem:[NSMenuItem separatorItem]]; | |
129 AddDuplicateItem(windowMenuItem_, IDC_WINDOW_MENU, IDC_ALL_WINDOWS_FRONT); | |
73 } | 130 } |
74 | 131 |
75 - (void)registerEventHandlers { | 132 - (void)registerEventHandlers { |
76 [[NSNotificationCenter defaultCenter] | 133 [[NSNotificationCenter defaultCenter] |
77 addObserver:self | 134 addObserver:self |
78 selector:@selector(windowMainStatusChanged:) | 135 selector:@selector(windowMainStatusChanged:) |
79 name:NSWindowDidBecomeMainNotification | 136 name:NSWindowDidBecomeMainNotification |
80 object:nil]; | 137 object:nil]; |
81 | 138 |
82 [[NSNotificationCenter defaultCenter] | 139 [[NSNotificationCenter defaultCenter] |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
137 | 194 |
138 // It seems that two menu items that have the same key equivalent must also | 195 // It seems that two menu items that have the same key equivalent must also |
139 // have the same action for the keyboard shortcut to work. (This refers to the | 196 // have the same action for the keyboard shortcut to work. (This refers to the |
140 // original keyboard shortcut, regardless of any overrides set in OSX). | 197 // original keyboard shortcut, regardless of any overrides set in OSX). |
141 // In order to let the appMenuQuitItem have a different action, we remove the | 198 // In order to let the appMenuQuitItem have a different action, we remove the |
142 // key equivalent from the chromeMenuQuitItem and restore it later. | 199 // key equivalent from the chromeMenuQuitItem and restore it later. |
143 [chromeMenuQuitItem_ setKeyEquivalent:@""]; | 200 [chromeMenuQuitItem_ setKeyEquivalent:@""]; |
144 | 201 |
145 [appMenuItem_ setTitle:appId]; | 202 [appMenuItem_ setTitle:appId]; |
146 [[appMenuItem_ submenu] setTitle:title]; | 203 [[appMenuItem_ submenu] setTitle:title]; |
204 | |
147 [mainMenu addItem:appMenuItem_]; | 205 [mainMenu addItem:appMenuItem_]; |
206 [mainMenu addItem:fileMenuItem_]; | |
207 [mainMenu addItem:editMenuItem_]; | |
208 [mainMenu addItem:windowMenuItem_]; | |
148 } | 209 } |
149 | 210 |
150 - (void)removeMenuItems:(NSString*)appId { | 211 - (void)removeMenuItems:(NSString*)appId { |
151 if (![appId_ isEqualToString:appId]) | 212 if (![appId_ isEqualToString:appId]) |
152 return; | 213 return; |
153 | 214 |
154 appId_.reset(); | 215 appId_.reset(); |
155 | 216 |
156 NSMenu* mainMenu = [NSApp mainMenu]; | 217 NSMenu* mainMenu = [NSApp mainMenu]; |
157 [mainMenu removeItem:appMenuItem_]; | 218 [mainMenu removeItem:appMenuItem_]; |
219 [mainMenu removeItem:fileMenuItem_]; | |
220 [mainMenu removeItem:editMenuItem_]; | |
221 [mainMenu removeItem:windowMenuItem_]; | |
158 | 222 |
159 // Restore the Chrome main menu bar. | 223 // Restore the Chrome main menu bar. |
160 for (NSMenuItem* item in [mainMenu itemArray]) | 224 for (NSMenuItem* item in [mainMenu itemArray]) |
161 [item setHidden:NO]; | 225 [item setHidden:NO]; |
162 | 226 |
163 // Restore the keyboard shortcut to Chrome. This just needs to be set back to | 227 // Restore the keyboard shortcut to Chrome. This just needs to be set back to |
164 // the original keyboard shortcut, regardless of any overrides in OSX. The | 228 // the original keyboard shortcut, regardless of any overrides in OSX. The |
165 // overrides still work as they are based on the title of the menu item. | 229 // overrides still work as they are based on the title of the menu item. |
166 [chromeMenuQuitItem_ setKeyEquivalent:@"q"]; | 230 [chromeMenuQuitItem_ setKeyEquivalent:@"q"]; |
167 } | 231 } |
168 | 232 |
169 - (void)quitCurrentPlatformApp { | 233 - (void)quitCurrentPlatformApp { |
170 apps::ShellWindow* shellWindow = | 234 apps::ShellWindow* shellWindow = |
171 apps::ShellWindowRegistry::GetShellWindowForNativeWindowAnyProfile( | 235 apps::ShellWindowRegistry::GetShellWindowForNativeWindowAnyProfile( |
172 [NSApp keyWindow]); | 236 [NSApp keyWindow]); |
173 if (shellWindow) | 237 if (shellWindow) |
174 apps::ExtensionAppShimHandler::QuitAppForWindow(shellWindow); | 238 apps::ExtensionAppShimHandler::QuitAppForWindow(shellWindow); |
175 } | 239 } |
176 | 240 |
177 @end | 241 @end |
OLD | NEW |