Browse Source

Merge pull request #6154 from electron/quit-role

Add quit menu item role
Kevin Sawicki 8 years ago
parent
commit
59ff3dc2f3

+ 1 - 0
atom/browser/ui/cocoa/atom_menu_controller.mm

@@ -38,6 +38,7 @@ Role kRolesMap[] = {
   { @selector(performMiniaturize:), "minimize" },
   { @selector(performClose:), "close" },
   { @selector(performZoom:), "zoom" },
+  { @selector(terminate:), "quit" },
 };
 
 }  // namespace

+ 13 - 1
default_app/main.js

@@ -214,7 +214,7 @@ app.once('ready', () => {
         {
           label: 'Quit ' + app.getName(),
           accelerator: 'Command+Q',
-          click () { app.quit() }
+          role: 'quit'
         }
       ]
     })
@@ -243,6 +243,18 @@ app.once('ready', () => {
     ]
   }
 
+  if (process.platform === 'win32') {
+    template.unshift({
+      label: 'File',
+      submenu: [
+        {
+          label: 'Exit',
+          role: 'quit'
+        }
+      ]
+    })
+  }
+
   const menu = Menu.buildFromTemplate(template)
   Menu.setApplicationMenu(menu)
 })

+ 1 - 0
docs/api/menu-item.md

@@ -51,6 +51,7 @@ The `role` property can have following values:
 * `delete`
 * `minimize` - Minimize current window
 * `close` - Close current window
+* `quit`- Quit the application
 
 On macOS `role` can also have following additional values:
 

+ 22 - 16
lib/browser/api/menu-item.js

@@ -1,11 +1,9 @@
 'use strict'
 
-var MenuItem, methodInBrowserWindow, nextCommandId, rolesMap
-
-nextCommandId = 0
+let nextCommandId = 0
 
 // Maps role to methods of webContents
-rolesMap = {
+const rolesMap = {
   undo: 'undo',
   redo: 'redo',
   cut: 'cut',
@@ -15,22 +13,27 @@ rolesMap = {
   selectall: 'selectAll',
   minimize: 'minimize',
   close: 'close',
-  delete: 'delete'
+  delete: 'delete',
+  quit: 'quit'
 }
 
 // Maps methods that should be called directly on the BrowserWindow instance
-methodInBrowserWindow = {
+const methodInBrowserWindow = {
   minimize: true,
   close: true
 }
 
-MenuItem = (function () {
+const methodInApp = {
+  quit: true
+}
+
+const MenuItem = (function () {
   MenuItem.types = ['normal', 'separator', 'submenu', 'checkbox', 'radio']
 
   function MenuItem (options) {
-    var click, ref
-    const Menu = require('electron').Menu
-    click = options.click
+    const {app, Menu} = require('electron')
+
+    const click = options.click
     this.selector = options.selector
     this.type = options.type
     this.role = options.role
@@ -48,7 +51,7 @@ MenuItem = (function () {
     if ((this.type == null) && (this.submenu != null)) {
       this.type = 'submenu'
     }
-    if (this.type === 'submenu' && ((ref = this.submenu) != null ? ref.constructor : void 0) !== Menu) {
+    if (this.type === 'submenu' && (this.submenu != null ? this.submenu.constructor : void 0) !== Menu) {
       throw new Error('Invalid submenu')
     }
     this.overrideReadOnlyProperty('type', 'normal')
@@ -67,16 +70,19 @@ MenuItem = (function () {
     this.commandId = ++nextCommandId
     this.click = (focusedWindow) => {
       // Manually flip the checked flags when clicked.
-      var methodName, ref1, ref2
-      if ((ref1 = this.type) === 'checkbox' || ref1 === 'radio') {
+      if (this.type === 'checkbox' || this.type === 'radio') {
         this.checked = !this.checked
       }
+
       if (this.role && rolesMap[this.role] && process.platform !== 'darwin' && (focusedWindow != null)) {
-        methodName = rolesMap[this.role]
-        if (methodInBrowserWindow[methodName]) {
+        const methodName = rolesMap[this.role]
+        if (methodInApp[methodName]) {
+          return app[methodName]()
+        } else if (methodInBrowserWindow[methodName]) {
           return focusedWindow[methodName]()
         } else {
-          return (ref2 = focusedWindow.webContents) != null ? ref2[methodName]() : void 0
+          const {webContents} = focusedWindow
+          return webContents != null ? webContents[methodName]() : void 0
         }
       } else if (typeof click === 'function') {
         return click(this, focusedWindow)