-2

The code example below for a main.js Electron file successfully changes the item label of the one item in menu Menu upon item click, but not its checked status when run in Electron Fiddle. As can be seen in the console dump, the checked property of menuTemplate has successfully been changed, but the checkmark is not displayed. Why does the modification of the label work but not the checked status?

I have noticed that Electron puts little icons to the left of menu items sometimes – can that behaviour interfere, and if so, can it be disabled?

Electron Fiddle 0.39.0

Electron 41.4.0

MacOS 26.5

const { app, BrowserWindow,Menu } = require('electron')
const path = require('node:path')
const isMac = process.platform === 'darwin'
var itemToggle = false; // variable to toggle between states

const menuTemplate = [
   ...(isMac
    ? [{
        label: app.name,
        submenu: [
          {label: 'Quit ',
            accelerator: 'Cmd+Q',
            click: function(){
              setValObj.quit = true;
              closeAndQuit();
            }
          }
        ]
      }]
    : []), {
    label: 'Menu',
    submenu: [
      {
        label:"Item",
        checked: false,
        click: () => {
          itemToggle = !itemToggle;
          let label = "Item"
          if(itemToggle){label = "Another Item"} // toggle item label – works
          menuTemplate[1].submenu[0].label = label; 
          menuTemplate[1].submenu[0].checked = itemToggle; // toggle checkmark – registers in the var but is not implemented
          setMenuFromTemplate(menuTemplate);
          console.log(JSON.stringify(menuTemplate));
        }
      }
    ]
  }
];

function setMenuFromTemplate(template){
  menu = Menu.buildFromTemplate(template)
  Menu.setApplicationMenu(menu)
}

function createWindow () {
  const mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    /*webPreferences: {
      preload: path.join(__dirname, 'preload.js')
    }*/
  })

  mainWindow.loadFile('index.html')
}

app.whenReady().then(() => {
  createWindow();
  setMenuFromTemplate(menuTemplate)

  app.on('activate', function () {
    if (BrowserWindow.getAllWindows().length === 0) createWindow()
  })
})

app.on('window-all-closed', function () {
  if (process.platform !== 'darwin') app.quit()
})

2
  • Have you tried setting a type property? The documentation seems to indicate that the behaviour you're expecting only is implemented for checkbox and radio type menu items. Can't check whether this actually is needed right now, so I'm not posting this as an answer. Commented Jun 6 at 18:26
  • @AlexanderLeithner Yes, that fixed it. I thought I had read somewhere that this type requirement is obsolete nowadays... also, I did attempt it, but obviously I must have made some error in the code on that occasion. Thanks! Commented Jun 6 at 19:06

1 Answer 1

0

As per suggestion by @AlexanderLeithner in the comments to the post, adding a type: checkbox property-value pair to the item enabled checkmarking. If there is another, more updated way to achieve this, please do not hesitate to comment.

const { app, BrowserWindow,Menu } = require('electron')
const path = require('node:path')
const isMac = process.platform === 'darwin'
var itemToggle = false; // variable to toggle between states

const menuTemplate = [
   ...(isMac
    ? [{
        label: app.name,
        submenu: [
          {label: 'Quit ',
            accelerator: 'Cmd+Q',
            click: function(){
              setValObj.quit = true;
              closeAndQuit();
            }
          }
        ]
      }]
    : []), {
    label: 'Menu',
    submenu: [
      {
        label:"Item",
        type:"checkbox", /*this property was missing*/
        checked: false,
        click: () => {
          itemToggle = !itemToggle;
          let label = "Item"
          if(itemToggle){label = "Another Item"} // toggle item label – works
          menuTemplate[1].submenu[0].label = label; 
          menuTemplate[1].submenu[0].checked = itemToggle; // toggle checkmark – registers in the var but is not implemented
          setMenuFromTemplate(menuTemplate);
          console.log(JSON.stringify(menuTemplate));
        }
      }
    ]
  }
];

function setMenuFromTemplate(template){
  menu = Menu.buildFromTemplate(template)
  Menu.setApplicationMenu(menu)
}

function createWindow () {
  const mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    /*webPreferences: {
      preload: path.join(__dirname, 'preload.js')
    }*/
  })

  mainWindow.loadFile('index.html')
}

app.whenReady().then(() => {
  createWindow();
  setMenuFromTemplate(menuTemplate)

  app.on('activate', function () {
    if (BrowserWindow.getAllWindows().length === 0) createWindow()
  })
})

app.on('window-all-closed', function () {
  if (process.platform !== 'darwin') app.quit()
})
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.