Merge pull request #11166 from sethlu/openrecent
feat: Recent documents menu item
This commit is contained in:
commit
b161a4f515
4 changed files with 106 additions and 6 deletions
|
@ -50,10 +50,17 @@ Role kRolesMap[] = {
|
||||||
{ @selector(selectPreviousTab:), "selectprevioustab" },
|
{ @selector(selectPreviousTab:), "selectprevioustab" },
|
||||||
{ @selector(mergeAllWindows:), "mergeallwindows" },
|
{ @selector(mergeAllWindows:), "mergeallwindows" },
|
||||||
{ @selector(moveTabToNewWindow:), "movetabtonewwindow" },
|
{ @selector(moveTabToNewWindow:), "movetabtonewwindow" },
|
||||||
|
{ @selector(clearRecentDocuments:), "clearrecentdocuments" },
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
// Menu item is located for ease of removing it from the parent owner
|
||||||
|
static base::scoped_nsobject<NSMenuItem> recentDocumentsMenuItem_;
|
||||||
|
|
||||||
|
// Submenu retained to be swapped back to |recentDocumentsMenuItem_|
|
||||||
|
static base::scoped_nsobject<NSMenu> recentDocumentsMenuSwap_;
|
||||||
|
|
||||||
@implementation AtomMenuController
|
@implementation AtomMenuController
|
||||||
|
|
||||||
@synthesize model = model_;
|
@synthesize model = model_;
|
||||||
|
@ -75,7 +82,8 @@ Role kRolesMap[] = {
|
||||||
// while its context menu is still open.
|
// while its context menu is still open.
|
||||||
[self cancel];
|
[self cancel];
|
||||||
|
|
||||||
model_ = nullptr;
|
model_ = nil;
|
||||||
|
|
||||||
[super dealloc];
|
[super dealloc];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,6 +95,14 @@ Role kRolesMap[] = {
|
||||||
if (!menu_)
|
if (!menu_)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (!recentDocumentsMenuItem_) {
|
||||||
|
// Locate & retain the recent documents menu item
|
||||||
|
recentDocumentsMenuItem_.reset([[[[[NSApp mainMenu]
|
||||||
|
itemWithTitle:@"Electron"] submenu]
|
||||||
|
itemWithTitle:@"Open Recent"]
|
||||||
|
retain]);
|
||||||
|
}
|
||||||
|
|
||||||
model_ = model;
|
model_ = model;
|
||||||
[menu_ removeAllItems];
|
[menu_ removeAllItems];
|
||||||
|
|
||||||
|
@ -132,6 +148,42 @@ Role kRolesMap[] = {
|
||||||
[menu insertItem:separator atIndex:index];
|
[menu insertItem:separator atIndex:index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Empties the source menu items to the destination.
|
||||||
|
- (void)moveMenuItems:(NSMenu*)source
|
||||||
|
to:(NSMenu*)destination {
|
||||||
|
const long count = [source numberOfItems];
|
||||||
|
for (long index = 0; index < count; index++) {
|
||||||
|
NSMenuItem* removedItem = [[[source itemAtIndex:0] retain] autorelease];
|
||||||
|
[source removeItemAtIndex:0];
|
||||||
|
[destination addItem:removedItem];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Replaces the item's submenu instance with the singleton recent documents
|
||||||
|
// menu. Previously replaced menu items will be recovered.
|
||||||
|
- (void)replaceSubmenuShowingRecentDocuments:(NSMenuItem*)item {
|
||||||
|
NSMenu* recentDocumentsMenu = [[[recentDocumentsMenuItem_ submenu]
|
||||||
|
retain] autorelease];
|
||||||
|
|
||||||
|
// Remove menu items in recent documents back to swap menu
|
||||||
|
[self moveMenuItems:recentDocumentsMenu
|
||||||
|
to:recentDocumentsMenuSwap_];
|
||||||
|
// Swap back the submenu
|
||||||
|
[recentDocumentsMenuItem_ setSubmenu:recentDocumentsMenuSwap_];
|
||||||
|
|
||||||
|
// Retain the item's submenu for a future recovery
|
||||||
|
recentDocumentsMenuSwap_.reset([[item submenu] retain]);
|
||||||
|
|
||||||
|
// Repopulate with items from the submenu to be replaced
|
||||||
|
[self moveMenuItems:recentDocumentsMenuSwap_
|
||||||
|
to:recentDocumentsMenu];
|
||||||
|
// Replace submenu
|
||||||
|
[item setSubmenu:recentDocumentsMenu];
|
||||||
|
|
||||||
|
// Remember the new menu item that carries the recent documents menu
|
||||||
|
recentDocumentsMenuItem_.reset([item retain]);
|
||||||
|
}
|
||||||
|
|
||||||
// Adds an item or a hierarchical menu to the item at the |index|,
|
// Adds an item or a hierarchical menu to the item at the |index|,
|
||||||
// associated with the entry in the model identified by |modelIndex|.
|
// associated with the entry in the model identified by |modelIndex|.
|
||||||
- (void)addItemToMenu:(NSMenu*)menu
|
- (void)addItemToMenu:(NSMenu*)menu
|
||||||
|
@ -139,6 +191,7 @@ Role kRolesMap[] = {
|
||||||
fromModel:(atom::AtomMenuModel*)model {
|
fromModel:(atom::AtomMenuModel*)model {
|
||||||
base::string16 label16 = model->GetLabelAt(index);
|
base::string16 label16 = model->GetLabelAt(index);
|
||||||
NSString* label = l10n_util::FixUpWindowsStyleLabel(label16);
|
NSString* label = l10n_util::FixUpWindowsStyleLabel(label16);
|
||||||
|
|
||||||
base::scoped_nsobject<NSMenuItem> item(
|
base::scoped_nsobject<NSMenuItem> item(
|
||||||
[[NSMenuItem alloc] initWithTitle:label
|
[[NSMenuItem alloc] initWithTitle:label
|
||||||
action:@selector(itemSelected:)
|
action:@selector(itemSelected:)
|
||||||
|
@ -149,6 +202,7 @@ Role kRolesMap[] = {
|
||||||
if (model->GetIconAt(index, &icon) && !icon.IsEmpty())
|
if (model->GetIconAt(index, &icon) && !icon.IsEmpty())
|
||||||
[item setImage:icon.ToNSImage()];
|
[item setImage:icon.ToNSImage()];
|
||||||
|
|
||||||
|
base::string16 role = model->GetRoleAt(index);
|
||||||
atom::AtomMenuModel::ItemType type = model->GetTypeAt(index);
|
atom::AtomMenuModel::ItemType type = model->GetTypeAt(index);
|
||||||
if (type == atom::AtomMenuModel::TYPE_SUBMENU) {
|
if (type == atom::AtomMenuModel::TYPE_SUBMENU) {
|
||||||
// Recursively build a submenu from the sub-model at this index.
|
// Recursively build a submenu from the sub-model at this index.
|
||||||
|
@ -161,14 +215,14 @@ Role kRolesMap[] = {
|
||||||
[item setSubmenu:submenu];
|
[item setSubmenu:submenu];
|
||||||
|
|
||||||
// Set submenu's role.
|
// Set submenu's role.
|
||||||
base::string16 role = model->GetRoleAt(index);
|
|
||||||
if (role == base::ASCIIToUTF16("window") && [submenu numberOfItems])
|
if (role == base::ASCIIToUTF16("window") && [submenu numberOfItems])
|
||||||
[NSApp setWindowsMenu:submenu];
|
[NSApp setWindowsMenu:submenu];
|
||||||
else if (role == base::ASCIIToUTF16("help"))
|
else if (role == base::ASCIIToUTF16("help"))
|
||||||
[NSApp setHelpMenu:submenu];
|
[NSApp setHelpMenu:submenu];
|
||||||
|
else if (role == base::ASCIIToUTF16("services"))
|
||||||
if (role == base::ASCIIToUTF16("services"))
|
|
||||||
[NSApp setServicesMenu:submenu];
|
[NSApp setServicesMenu:submenu];
|
||||||
|
else if (role == base::ASCIIToUTF16("recentdocuments"))
|
||||||
|
[self replaceSubmenuShowingRecentDocuments:item];
|
||||||
} else {
|
} else {
|
||||||
// The MenuModel works on indexes so we can't just set the command id as the
|
// The MenuModel works on indexes so we can't just set the command id as the
|
||||||
// tag like we do in other menus. Also set the represented object to be
|
// tag like we do in other menus. Also set the represented object to be
|
||||||
|
@ -192,7 +246,6 @@ Role kRolesMap[] = {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set menu item's role.
|
// Set menu item's role.
|
||||||
base::string16 role = model->GetRoleAt(index);
|
|
||||||
[item setTarget:self];
|
[item setTarget:self];
|
||||||
if (!role.empty()) {
|
if (!role.empty()) {
|
||||||
for (const Role& pair : kRolesMap) {
|
for (const Role& pair : kRolesMap) {
|
||||||
|
|
|
@ -65,6 +65,22 @@
|
||||||
<reference key="NSOnImage" ref="229763992"/>
|
<reference key="NSOnImage" ref="229763992"/>
|
||||||
<reference key="NSMixedImage" ref="909111550"/>
|
<reference key="NSMixedImage" ref="909111550"/>
|
||||||
</object>
|
</object>
|
||||||
|
<object class="NSMenuItem" id="1025936716">
|
||||||
|
<reference key="NSMenu" ref="110575045"/>
|
||||||
|
<string key="NSTitle">Open Recent</string>
|
||||||
|
<string key="NSKeyEquiv"/>
|
||||||
|
<int key="NSKeyEquivModMask">1048576</int>
|
||||||
|
<int key="NSMnemonicLoc">2147483647</int>
|
||||||
|
<bool key="NSIsHidden">YES</bool>
|
||||||
|
<reference key="NSOnImage" ref="229763992"/>
|
||||||
|
<reference key="NSMixedImage" ref="909111550"/>
|
||||||
|
<string key="NSAction">submenuAction:</string>
|
||||||
|
<object class="NSMenu" key="NSSubmenu" id="1065607017">
|
||||||
|
<string key="NSTitle">Open Recent</string>
|
||||||
|
<array class="NSMutableArray" key="NSMenuItems"></array>
|
||||||
|
<string key="NSName">_NSRecentDocumentsMenu</string>
|
||||||
|
</object>
|
||||||
|
</object>
|
||||||
</array>
|
</array>
|
||||||
<string key="NSName">_NSAppleMenu</string>
|
<string key="NSName">_NSAppleMenu</string>
|
||||||
</object>
|
</object>
|
||||||
|
@ -115,6 +131,7 @@
|
||||||
<reference key="object" ref="903638069"/>
|
<reference key="object" ref="903638069"/>
|
||||||
<reference key="parent" ref="0"/>
|
<reference key="parent" ref="0"/>
|
||||||
</object>
|
</object>
|
||||||
|
<!-- NSMenu Main Menu -->
|
||||||
<object class="IBObjectRecord">
|
<object class="IBObjectRecord">
|
||||||
<int key="objectID">29</int>
|
<int key="objectID">29</int>
|
||||||
<reference key="object" ref="649796088"/>
|
<reference key="object" ref="649796088"/>
|
||||||
|
@ -123,6 +140,7 @@
|
||||||
</array>
|
</array>
|
||||||
<reference key="parent" ref="0"/>
|
<reference key="parent" ref="0"/>
|
||||||
</object>
|
</object>
|
||||||
|
<!-- NSMenuItem Electron -->
|
||||||
<object class="IBObjectRecord">
|
<object class="IBObjectRecord">
|
||||||
<int key="objectID">56</int>
|
<int key="objectID">56</int>
|
||||||
<reference key="object" ref="694149608"/>
|
<reference key="object" ref="694149608"/>
|
||||||
|
@ -131,30 +149,51 @@
|
||||||
</array>
|
</array>
|
||||||
<reference key="parent" ref="649796088"/>
|
<reference key="parent" ref="649796088"/>
|
||||||
</object>
|
</object>
|
||||||
|
<!-- NSMenu Electron -->
|
||||||
<object class="IBObjectRecord">
|
<object class="IBObjectRecord">
|
||||||
<int key="objectID">57</int>
|
<int key="objectID">57</int>
|
||||||
<reference key="object" ref="110575045"/>
|
<reference key="object" ref="110575045"/>
|
||||||
<array class="NSMutableArray" key="children">
|
<array class="NSMutableArray" key="children">
|
||||||
<reference ref="632727374"/>
|
<reference ref="632727374"/>
|
||||||
|
<reference ref="1025936716"/>
|
||||||
</array>
|
</array>
|
||||||
<reference key="parent" ref="694149608"/>
|
<reference key="parent" ref="694149608"/>
|
||||||
</object>
|
</object>
|
||||||
|
<!-- NSMenuItem Quit -->
|
||||||
<object class="IBObjectRecord">
|
<object class="IBObjectRecord">
|
||||||
<int key="objectID">136</int>
|
<int key="objectID">136</int>
|
||||||
<reference key="object" ref="632727374"/>
|
<reference key="object" ref="632727374"/>
|
||||||
<reference key="parent" ref="110575045"/>
|
<reference key="parent" ref="110575045"/>
|
||||||
</object>
|
</object>
|
||||||
|
<!-- NSMenuItem Open Recent -->
|
||||||
|
<object class="IBObjectRecord">
|
||||||
|
<int key="objectID">124</int>
|
||||||
|
<reference key="object" ref="1025936716"/>
|
||||||
|
<array class="NSMutableArray" key="children">
|
||||||
|
<reference ref="1065607017"/>
|
||||||
|
</array>
|
||||||
|
<reference key="parent" ref="110575045"/>
|
||||||
|
</object>
|
||||||
|
<!-- NSMenu Open Recent -->
|
||||||
|
<object class="IBObjectRecord">
|
||||||
|
<int key="objectID">125</int>
|
||||||
|
<reference key="object" ref="1065607017"/>
|
||||||
|
<array class="NSMutableArray" key="children"></array>
|
||||||
|
<reference key="parent" ref="1025936716"/>
|
||||||
|
</object>
|
||||||
</array>
|
</array>
|
||||||
</object>
|
</object>
|
||||||
<dictionary class="NSMutableDictionary" key="flattenedProperties">
|
<dictionary class="NSMutableDictionary" key="flattenedProperties">
|
||||||
<string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
<string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||||
<string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
<string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||||
<string key="-3.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
<string key="-3.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||||
<string key="136.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
|
||||||
<string key="29.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
<string key="29.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||||
<string key="371.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
<string key="371.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||||
<string key="56.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
<string key="56.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||||
<string key="57.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
<string key="57.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||||
|
<string key="136.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||||
|
<string key="124.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||||
|
<string key="125.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||||
</dictionary>
|
</dictionary>
|
||||||
<dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
|
<dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
|
||||||
<nil key="activeLocalization"/>
|
<nil key="activeLocalization"/>
|
||||||
|
|
|
@ -88,6 +88,8 @@ The following additional roles are available on macOS:
|
||||||
* `window` - The submenu is a "Window" menu
|
* `window` - The submenu is a "Window" menu
|
||||||
* `help` - The submenu is a "Help" menu
|
* `help` - The submenu is a "Help" menu
|
||||||
* `services` - The submenu is a "Services" menu
|
* `services` - The submenu is a "Services" menu
|
||||||
|
* `recentdocuments` - The submenu is an "Open Recent" menu
|
||||||
|
* `clearrecentdocuments` - Map to the `clearRecentDocuments` action
|
||||||
|
|
||||||
When specifying a `role` on macOS, `label` and `accelerator` are the only
|
When specifying a `role` on macOS, `label` and `accelerator` are the only
|
||||||
options that will affect the menu item. All other options will be ignored.
|
options that will affect the menu item. All other options will be ignored.
|
||||||
|
|
|
@ -102,6 +102,12 @@ const roles = {
|
||||||
services: {
|
services: {
|
||||||
label: 'Services'
|
label: 'Services'
|
||||||
},
|
},
|
||||||
|
recentdocuments: {
|
||||||
|
label: 'Open Recent'
|
||||||
|
},
|
||||||
|
clearrecentdocuments: {
|
||||||
|
label: 'Clear Menu'
|
||||||
|
},
|
||||||
startspeaking: {
|
startspeaking: {
|
||||||
label: 'Start Speaking'
|
label: 'Start Speaking'
|
||||||
},
|
},
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue