Change Electron's menu item's status dynamically

Like in any standard native application, also my electron’s application needs to change the status (enabled/dsabled) of several menu item, based on live usage results.

I am setting up my menu in main.js:

function createWindow () {
...
...
  require('./menu/mainmenu');
}

The MenuItem I need to change is defined in mainmenu:

{ label: "Show Colors",  
        accelerator: 'CmdOrCtrl+1', 
        enabled: getStatus(),
        click() {getWebviewWebContents().send('switchToColors');} 
 },

where getStatus() is function returning false or true.

All this is not working in Electron, as the menu is created at application start and it can’t be modified at all. I believe this is a serious lack, as dynamic menu items are very common (i.e.: menu checkboxes, enabled/disabled, etc).

Is there any workaround for this?

Here is Solutions:

We have many solutions to this problem, But we recommend you to use the first solution because it is tested & true solution that will 100% work for you.

Solution 1

I have fixed this by setting an Id to the menu item,

{ label: "Show Colors",  
        id: 'color-scale',
        accelerator: 'CmdOrCtrl+1', 
        enabled: getStatus(),
        click() {getWebviewWebContents().send('switchToColors');} 
 },

and getting the menu item with:

myItem = menu.getMenuItemById('color-scale')

Then, when I need to enable/disable it programmatically, I am using:

myItem.enabled = true

or

myItem.enabled = false

Solution 2

The only workaround so far I aware and using is reconstruct whole menu each time menuitem changes. This is not very ergonomics friendly, but works suffeciently enough and doesn’t cause lot of overhead.

Solution 3

Here is my solution:

main.js (main process)

const menuTemplate = [{
    label: 'Options',
    submenu: [
       {
         label: 'Config',
         enabled: false,
         click() { //do stuff }
       }
    ]
}];

// Enable menu items when user login. Fetching value from renderer process
ipcMain.on('logged-in', (event, args) => {
    if (args !== true) {
        return;
    }

    // Modify menu item status
    menuTemplate[0].submenu[0].enabled = true;

    // Rebuild menu
    const menu = Menu.buildFromTemplate(menuTemplate);
    Menu.setApplicationMenu(menu);
});

Note: Use and implement solution 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply