Jayesh
Jayesh

Reputation: 53335

How to change items in Electron Application menu at runtime?

My electron app has an application menu which has "Open Recent" entries as submenu. The entries in this submenu give 10 most recently accessed documents. I populate this menu when the application starts and all works well. However in order to qualify for being "most recently" accessed documents, I've to refresh this list from time to time and not just at the application start. How can I achieve this?

There are two specific sub-questions to this

  1. When can I update this? I was looking for some callback when the user clicks on the top level menu entry, where I could run the code to refresh this list. But I couldn't get that to work. The only callback the MenuItem has is 'click' and it doesn't seem to work if it has a submenu defined. A workaround for this is invoking setInterval and updating the menu entries at periodic times, say 1 min. But if there's a callback where I can do this, I will prefer that.
  2. How can I update this? I create a new Menu using Menu.buildFromTemplate() and then assign it to the submenu entry in the application menu hierarchy (I've saved the reference to the application menu when first time I created it). But this doesn't work.

Upvotes: 4

Views: 5955

Answers (2)

webcpu
webcpu

Reputation: 3422

Menu.setApplicationMenu is what you are looking for. You can call it after you made changes to your menu.

const menu = Menu.buildFromTemplate(template);
Menu.setApplicationMenu(menu);

Upvotes: 1

spring
spring

Reputation: 18487

It seems like setMenu is your only option. As for when to do it – for an "Open Recent" features, I would think you could do it when a document is opened (or after it has been closed): add the document to the menu template and call setMenu again.


This is from 2014 but it sounds like it is the defined behavior:

Modifying Menu object after setMenu can produce unregistered/dangling accelerators #846

The proper way in atom-shell to update menu bar or application menu is to call BrowserWindow.setMenu or app.setApplicationMenu after you modified Menu object every time.

This is because Menu actually acts as a model, and the native menu is not created until you call setMenu, so if you change the model without updating the native menu, bad things can happen. We use this design because it perfectly represents the menu library used by Chromium, and most menus are static.

But I think we should find a way to prevent the crash and make it clear in documents.

And:

I'm closing this since we don't support changing menu object after calling setMenu, the behavior is undefined if user does that.

Upvotes: 3

Related Questions