thephpdev
thephpdev

Reputation: 1117

Native Menus not showing OS X Electron

I used the electron-quick-start to create an Electron app, and I want the only native menu to show to be the 'Edit' menu, with the usual suspects inside.

However, after searching and exhausting all relevant Google results for 'electron menu not working', I'm at a loss.

My current main.js file:

const {app, Menu, BrowserWindow} = require('electron')

// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let mainWindow;

app.setName('mathulator');

function createWindow () {
  // Create the browser window.
  mainWindow = new BrowserWindow({width: 900, height: 550})

  // and load the index.html of the app.
  mainWindow.loadURL(`file://${__dirname}/index.html`)

  // In this file you can include the rest of your app's specific main process
  // code. You can also put them in separate files and require them here.

  const template = [
    {
        label: 'Mathulator',
        submenu: [
            {
                role: 'quit'
            }
        ]
    },
    {
      label: 'Edit',
      submenu: [
        {
          role: 'undo'
        },
        {
          role: 'redo'
        },
        {
          type: 'separator'
        },
        {
          role: 'cut'
        },
        {
          role: 'copy'
        },
        {
          role: 'paste'
        },
        {
          role: 'pasteandmatchstyle'
        },
        {
          role: 'delete'
        },
        {
          role: 'selectall'
        }
      ]
    }
   ]

  mainWindow.setMenu(Menu.buildFromTemplate(template))

  // Emitted when the window is closed.
  mainWindow.on('closed', function () {
    // Dereference the window object, usually you would store windows
    // in an array if your app supports multi windows, this is the time
    // when you should delete the corresponding element.
    mainWindow = null
  })
}

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on('ready', createWindow)

// Quit when all windows are closed.
app.on('window-all-closed', function () {
  // On OS X it is common for applications and their menu bar
  // to stay active until the user quits explicitly with Cmd + Q
  if (process.platform !== 'darwin') {
    app.quit()
  }
})

app.on('activate', function () {
  // On OS X it's common to re-create a window in the app when the
  // dock icon is clicked and there are no other windows open.
  if (mainWindow === null) {
    createWindow()
  }
})

I've also packaged it up with electron-packager, to no avail.

I'm running it in the main.js file, which from what I can gather from the masses of either vague or convoluted information around the web, is the main process and therefore one in which I should create the menus.

I also tried doing it in render.js, which I saw suggested. To no avail. It'll either show up with the default electron-quick-start menu, or just a simple menu named after the app, containing one item labelled 'Quit'.

What might I be doing wrong, and what might I have misunderstood from the available information?


Edit: I actually attached the wrong file, tried using Menu.setApplicationMenu() the first time, like so:

const {app, Menu, BrowserWindow} = require('electron')

// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let mainWindow;

app.setName('mathulator');

function createWindow () {
    // Create the browser window.
    mainWindow = new BrowserWindow({width: 900, height: 550});

    // and load the index.html of the app.
    mainWindow.loadURL(`file://${__dirname}/index.html`);

    // Emitted when the window is closed.
    mainWindow.on('closed', function () {
        // Dereference the window object, usually you would store windows
        // in an array if your app supports multi windows, this is the time
        // when you should delete the corresponding element.
        mainWindow = null;
    });
}

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on('ready', createWindow);

// Quit when all windows are closed.
app.on('window-all-closed', function () {
    // On OS X it is common for applications and their menu bar
    // to stay active until the user quits explicitly with Cmd + Q
    if (process.platform !== 'darwin') {
        app.quit();
    }
})

app.on('activate', function () {
    // On OS X it's common to re-create a window in the app when the
    // dock icon is clicked and there are no other windows open.
    if (mainWindow === null) {
        createWindow();
    }
})

const template = [
    {
        label: 'Mathulator',
        submenu: [
            {
                role: 'quit'
            }
        ]
    },
    {
        label: 'Edit',
        submenu: [
            {
                role: 'undo'
            },
            {
                role: 'redo'
            },
            {
                type: 'separator'
            },
            {
                role: 'cut'
            },
            {
                role: 'copy'
            },
            {
                role: 'paste'
            },
            {
                role: 'pasteandmatchstyle'
            },
            {
                role: 'delete'
            },
            {
                role: 'selectall'
            }
        ]
    }
];

Menu.setApplicationMenu(Menu.buildFromTemplate(template));

Upvotes: 5

Views: 4393

Answers (4)

David Dehghan
David Dehghan

Reputation: 24835

Note that on OSX the menu is not on the window itself but on the top of dosktop.

I lost bunch of time trying to troubleshoot why it was not showing up.

Upvotes: 3

tanxiuguang
tanxiuguang

Reputation: 65

maybe you set LSUIElement to 1, that means an agent app, that is, an app that should not appear in the Dock. Change the LSUIElement to 0, the build app's menu will show up.

electron build config

mac: {
            icon: 'build/icons/icon.icons',
            extendInfo: {
              LSUIElement: 0
            }
          }

detail of LSUIElement is here https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/LaunchServicesKeys.html#//apple_ref/doc/uid/20001431-108256

Upvotes: 0

Daniel
Daniel

Reputation: 18682

As @Vadim Macagon stated in comment, make sure that the call to Menu.setApplicationMenu() is in createWindow(). For me it fixed the problem.

Upvotes: 0

Vadim Macagon
Vadim Macagon

Reputation: 14847

The issue here is that BrowserWindow.setMenu() is only available on Windows and Linux. On macOS you should use Menu.setApplicationMenu().

Upvotes: 7

Related Questions