400 lines
		
	
	
	
		
			11 KiB
			
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			400 lines
		
	
	
	
		
			11 KiB
			
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| ## Class: Menu
 | |
| 
 | |
| > Create native application menus and context menus.
 | |
| 
 | |
| Process: [Main](../glossary.md#main-process)
 | |
| 
 | |
| ### `new Menu()`
 | |
| 
 | |
| Creates a new menu.
 | |
| 
 | |
| ### Static Methods
 | |
| 
 | |
| The `Menu` class has the following static methods:
 | |
| 
 | |
| #### `Menu.setApplicationMenu(menu)`
 | |
| 
 | |
| * `menu` Menu | null
 | |
| 
 | |
| Sets `menu` as the application menu on macOS. On Windows and Linux, the
 | |
| `menu` will be set as each window's top menu.
 | |
| 
 | |
| Also on Windows and Linux, you can use a `&` in the top-level item name to
 | |
| indicate which letter should get a generated accelerator. For example, using
 | |
| `&File` for the file menu would result in a generated `Alt-F` accelerator that
 | |
| opens the associated menu. The indicated character in the button label gets an
 | |
| underline. The `&` character is not displayed on the button label.
 | |
| 
 | |
| Passing `null` will suppress the default menu. On Windows and Linux,
 | |
| this has the additional effect of removing the menu bar from the window.
 | |
| 
 | |
| **Note:** The default menu will be created automatically if the app does not set one.
 | |
| It contains standard items such as `File`, `Edit`, `View`, `Window` and `Help`.
 | |
| 
 | |
| #### `Menu.getApplicationMenu()`
 | |
| 
 | |
| Returns `Menu | null` - The application menu, if set, or `null`, if not set.
 | |
| 
 | |
| **Note:** The returned `Menu` instance doesn't support dynamic addition or
 | |
| removal of menu items. [Instance properties](#instance-properties) can still
 | |
| be dynamically modified.
 | |
| 
 | |
| #### `Menu.sendActionToFirstResponder(action)` _macOS_
 | |
| 
 | |
| * `action` String
 | |
| 
 | |
| Sends the `action` to the first responder of application. This is used for
 | |
| emulating default macOS menu behaviors. Usually you would use the
 | |
| [`role`](menu-item.md#roles) property of a [`MenuItem`](menu-item.md).
 | |
| 
 | |
| See the [macOS Cocoa Event Handling Guide](https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/EventOverview/EventArchitecture/EventArchitecture.html#//apple_ref/doc/uid/10000060i-CH3-SW7)
 | |
| for more information on macOS' native actions.
 | |
| 
 | |
| #### `Menu.buildFromTemplate(template)`
 | |
| 
 | |
| * `template` (MenuItemConstructorOptions | MenuItem)[]
 | |
| 
 | |
| Returns `Menu`
 | |
| 
 | |
| Generally, the `template` is an array of `options` for constructing a
 | |
| [MenuItem](menu-item.md). The usage can be referenced above.
 | |
| 
 | |
| You can also attach other fields to the element of the `template` and they will become properties of the constructed menu items.
 | |
| 
 | |
| ### Instance Methods
 | |
| 
 | |
| The `menu` object has the following instance methods:
 | |
| 
 | |
| #### `menu.popup([options])`
 | |
| 
 | |
| * `options` Object (optional)
 | |
|   * `window` [BrowserWindow](browser-window.md) (optional) - Default is the focused window.
 | |
|   * `x` Number (optional) - Default is the current mouse cursor position.
 | |
|     Must be declared if `y` is declared.
 | |
|   * `y` Number (optional) - Default is the current mouse cursor position.
 | |
|     Must be declared if `x` is declared.
 | |
|   * `positioningItem` Number (optional) _macOS_ - The index of the menu item to
 | |
|     be positioned under the mouse cursor at the specified coordinates. Default
 | |
|     is -1.
 | |
|   * `callback` Function (optional) - Called when menu is closed.
 | |
| 
 | |
| Pops up this menu as a context menu in the [`BrowserWindow`](browser-window.md).
 | |
| 
 | |
| #### `menu.closePopup([browserWindow])`
 | |
| 
 | |
| * `browserWindow` [BrowserWindow](browser-window.md) (optional) - Default is the focused window.
 | |
| 
 | |
| Closes the context menu in the `browserWindow`.
 | |
| 
 | |
| #### `menu.append(menuItem)`
 | |
| 
 | |
| * `menuItem` [MenuItem](menu-item.md)
 | |
| 
 | |
| Appends the `menuItem` to the menu.
 | |
| 
 | |
| #### `menu.getMenuItemById(id)`
 | |
| 
 | |
| * `id` String
 | |
| 
 | |
| Returns `MenuItem` the item with the specified `id`
 | |
| 
 | |
| #### `menu.insert(pos, menuItem)`
 | |
| 
 | |
| * `pos` Integer
 | |
| * `menuItem` [MenuItem](menu-item.md)
 | |
| 
 | |
| Inserts the `menuItem` to the `pos` position of the menu.
 | |
| 
 | |
| ### Instance Events
 | |
| 
 | |
| Objects created with `new Menu` or returned by `Menu.buildFromTemplate` emit the following events:
 | |
| 
 | |
| **Note:** Some events are only available on specific operating systems and are
 | |
| labeled as such.
 | |
| 
 | |
| #### Event: 'menu-will-show'
 | |
| 
 | |
| Returns:
 | |
| 
 | |
| * `event` Event
 | |
| 
 | |
| Emitted when `menu.popup()` is called.
 | |
| 
 | |
| #### Event: 'menu-will-close'
 | |
| 
 | |
| Returns:
 | |
| 
 | |
| * `event` Event
 | |
| 
 | |
| Emitted when a popup is closed either manually or with `menu.closePopup()`.
 | |
| 
 | |
| ### Instance Properties
 | |
| 
 | |
| `menu` objects also have the following properties:
 | |
| 
 | |
| #### `menu.items`
 | |
| 
 | |
| A `MenuItem[]` array containing the menu's items.
 | |
| 
 | |
| Each `Menu` consists of multiple [`MenuItem`](menu-item.md)s and each `MenuItem`
 | |
| can have a submenu.
 | |
| 
 | |
| ## Examples
 | |
| 
 | |
| The `Menu` class is only available in the main process, but you can also use it
 | |
| in the render process via the [`remote`](remote.md) module.
 | |
| 
 | |
| ### Main process
 | |
| 
 | |
| An example of creating the application menu in the main process with the
 | |
| simple template API:
 | |
| 
 | |
| ```javascript
 | |
| const { app, Menu } = require('electron')
 | |
| 
 | |
| const isMac = process.platform === 'darwin'
 | |
| 
 | |
| const template = [
 | |
|   // { role: 'appMenu' }
 | |
|   ...(isMac ? [{
 | |
|     label: app.name,
 | |
|     submenu: [
 | |
|       { role: 'about' },
 | |
|       { type: 'separator' },
 | |
|       { role: 'services' },
 | |
|       { type: 'separator' },
 | |
|       { role: 'hide' },
 | |
|       { role: 'hideothers' },
 | |
|       { role: 'unhide' },
 | |
|       { type: 'separator' },
 | |
|       { role: 'quit' }
 | |
|     ]
 | |
|   }] : []),
 | |
|   // { role: 'fileMenu' }
 | |
|   {
 | |
|     label: 'File',
 | |
|     submenu: [
 | |
|       isMac ? { role: 'close' } : { role: 'quit' }
 | |
|     ]
 | |
|   },
 | |
|   // { role: 'editMenu' }
 | |
|   {
 | |
|     label: 'Edit',
 | |
|     submenu: [
 | |
|       { role: 'undo' },
 | |
|       { role: 'redo' },
 | |
|       { type: 'separator' },
 | |
|       { role: 'cut' },
 | |
|       { role: 'copy' },
 | |
|       { role: 'paste' },
 | |
|       ...(isMac ? [
 | |
|         { role: 'pasteAndMatchStyle' },
 | |
|         { role: 'delete' },
 | |
|         { role: 'selectAll' },
 | |
|         { type: 'separator' },
 | |
|         {
 | |
|           label: 'Speech',
 | |
|           submenu: [
 | |
|             { role: 'startspeaking' },
 | |
|             { role: 'stopspeaking' }
 | |
|           ]
 | |
|         }
 | |
|       ] : [
 | |
|         { role: 'delete' },
 | |
|         { type: 'separator' },
 | |
|         { role: 'selectAll' }
 | |
|       ])
 | |
|     ]
 | |
|   },
 | |
|   // { role: 'viewMenu' }
 | |
|   {
 | |
|     label: 'View',
 | |
|     submenu: [
 | |
|       { role: 'reload' },
 | |
|       { role: 'forcereload' },
 | |
|       { role: 'toggledevtools' },
 | |
|       { type: 'separator' },
 | |
|       { role: 'resetzoom' },
 | |
|       { role: 'zoomin' },
 | |
|       { role: 'zoomout' },
 | |
|       { type: 'separator' },
 | |
|       { role: 'togglefullscreen' }
 | |
|     ]
 | |
|   },
 | |
|   // { role: 'windowMenu' }
 | |
|   {
 | |
|     label: 'Window',
 | |
|     submenu: [
 | |
|       { role: 'minimize' },
 | |
|       { role: 'zoom' },
 | |
|       ...(isMac ? [
 | |
|         { type: 'separator' },
 | |
|         { role: 'front' },
 | |
|         { type: 'separator' },
 | |
|         { role: 'window' }
 | |
|       ] : [
 | |
|         { role: 'close' }
 | |
|       ])
 | |
|     ]
 | |
|   },
 | |
|   {
 | |
|     role: 'help',
 | |
|     submenu: [
 | |
|       {
 | |
|         label: 'Learn More',
 | |
|         click: async () => {
 | |
|           const { shell } = require('electron')
 | |
|           await shell.openExternal('https://electronjs.org')
 | |
|         }
 | |
|       }
 | |
|     ]
 | |
|   }
 | |
| ]
 | |
| 
 | |
| const menu = Menu.buildFromTemplate(template)
 | |
| Menu.setApplicationMenu(menu)
 | |
| ```
 | |
| 
 | |
| ### Render process
 | |
| 
 | |
| Below is an example of creating a menu dynamically in a web page
 | |
| (render process) by using the [`remote`](remote.md) module, and showing it when
 | |
| the user right clicks the page:
 | |
| 
 | |
| ```html
 | |
| <!-- index.html -->
 | |
| <script>
 | |
| const { remote } = require('electron')
 | |
| const { Menu, MenuItem } = remote
 | |
| 
 | |
| const menu = new Menu()
 | |
| menu.append(new MenuItem({ label: 'MenuItem1', click() { console.log('item 1 clicked') } }))
 | |
| menu.append(new MenuItem({ type: 'separator' }))
 | |
| menu.append(new MenuItem({ label: 'MenuItem2', type: 'checkbox', checked: true }))
 | |
| 
 | |
| window.addEventListener('contextmenu', (e) => {
 | |
|   e.preventDefault()
 | |
|   menu.popup({ window: remote.getCurrentWindow() })
 | |
| }, false)
 | |
| </script>
 | |
| ```
 | |
| 
 | |
| ## Notes on macOS Application Menu
 | |
| 
 | |
| macOS has a completely different style of application menu from Windows and
 | |
| Linux. Here are some notes on making your app's menu more native-like.
 | |
| 
 | |
| ### Standard Menus
 | |
| 
 | |
| On macOS there are many system-defined standard menus, like the [`Services`](https://developer.apple.com/documentation/appkit/nsapplication/1428608-servicesmenu?language=objc) and
 | |
| `Windows` menus. To make your menu a standard menu, you should set your menu's
 | |
| `role` to one of the following and Electron will recognize them and make them
 | |
| become standard menus:
 | |
| 
 | |
| * `window`
 | |
| * `help`
 | |
| * `services`
 | |
| 
 | |
| ### Standard Menu Item Actions
 | |
| 
 | |
| macOS has provided standard actions for some menu items, like `About xxx`,
 | |
| `Hide xxx`, and `Hide Others`. To set the action of a menu item to a standard
 | |
| action, you should set the `role` attribute of the menu item.
 | |
| 
 | |
| ### Main Menu's Name
 | |
| 
 | |
| On macOS the label of the application menu's first item is always your app's
 | |
| name, no matter what label you set. To change it, modify your app bundle's
 | |
| `Info.plist` file. See
 | |
| [About Information Property List Files][AboutInformationPropertyListFiles]
 | |
| for more information.
 | |
| 
 | |
| ## Setting Menu for Specific Browser Window (*Linux* *Windows*)
 | |
| 
 | |
| The [`setMenu` method][setMenu] of browser windows can set the menu of certain
 | |
| browser windows.
 | |
| 
 | |
| ## Menu Item Position
 | |
| 
 | |
| You can make use of `before`, `after`, `beforeGroupContaining`, `afterGroupContaining` and `id` to control how the item will be placed when building a menu with `Menu.buildFromTemplate`.
 | |
| 
 | |
| * `before` - Inserts this item before the item with the specified label. If the
 | |
|   referenced item doesn't exist the item will be inserted at the end of
 | |
|   the menu. Also implies that the menu item in question should be placed in the same “group” as the item.
 | |
| * `after` - Inserts this item after the item with the specified label. If the
 | |
|   referenced item doesn't exist the item will be inserted at the end of
 | |
|   the menu. Also implies that the menu item in question should be placed in the same “group” as the item.
 | |
| * `beforeGroupContaining` - Provides a means for a single context menu to declare
 | |
|   the placement of their containing group before the containing group of the item with the specified label.
 | |
| * `afterGroupContaining` - Provides a means for a single context menu to declare
 | |
|   the placement of their containing group after the containing group of the item with the specified label.
 | |
| 
 | |
| By default, items will be inserted in the order they exist in the template unless one of the specified positioning keywords is used.
 | |
| 
 | |
| ### Examples
 | |
| 
 | |
| Template:
 | |
| 
 | |
| ```javascript
 | |
| [
 | |
|   { id: '1', label: 'one' },
 | |
|   { id: '2', label: 'two' },
 | |
|   { id: '3', label: 'three' },
 | |
|   { id: '4', label: 'four' }
 | |
| ]
 | |
| ```
 | |
| 
 | |
| Menu:
 | |
| 
 | |
| ```sh
 | |
| - 1
 | |
| - 2
 | |
| - 3
 | |
| - 4
 | |
| ```
 | |
| 
 | |
| Template:
 | |
| 
 | |
| ```javascript
 | |
| [
 | |
|   { id: '1', label: 'one' },
 | |
|   { type: 'separator' },
 | |
|   { id: '3', label: 'three', beforeGroupContaining: ['1'] },
 | |
|   { id: '4', label: 'four', afterGroupContaining: ['2'] },
 | |
|   { type: 'separator' },
 | |
|   { id: '2', label: 'two' }
 | |
| ]
 | |
| ```
 | |
| 
 | |
| Menu:
 | |
| 
 | |
| ```sh
 | |
| - 3
 | |
| - 4
 | |
| - ---
 | |
| - 1
 | |
| - ---
 | |
| - 2
 | |
| ```
 | |
| 
 | |
| Template:
 | |
| 
 | |
| ```javascript
 | |
| [
 | |
|   { id: '1', label: 'one', after: ['3'] },
 | |
|   { id: '2', label: 'two', before: ['1'] },
 | |
|   { id: '3', label: 'three' }
 | |
| ]
 | |
| ```
 | |
| 
 | |
| Menu:
 | |
| 
 | |
| ```sh
 | |
| - ---
 | |
| - 3
 | |
| - 2
 | |
| - 1
 | |
| ```
 | |
| 
 | |
| [AboutInformationPropertyListFiles]: https://developer.apple.com/library/ios/documentation/general/Reference/InfoPlistKeyReference/Articles/AboutInformationPropertyListFiles.html
 | |
| [setMenu]: https://github.com/electron/electron/blob/master/docs/api/browser-window.md#winsetmenumenu-linux-windows
 | 
