Feature request: reuse menu items instead of recreating them
There are some issues around destroying and recreating menus while they are open which can be unfortunate when a plugin updates. Problems such as:
- The menu is fixed when you open it, and won't show updates until it's closed and reopened
- This is also true of the menubar icon, it won't update while the menu is open
- Webviews are destroyed when updates are received, making them disappear unexpectedly
I could, perhaps, file separate issues for these. However, I think they could all be solved by recycling objects instead of recreating them. I have a rough idea of how we might approach this:
- Use a diffing algorithm on the current output vs the previous output
- Step through the diff, skipping over menu items that are unchanged
- On encountering a diff line that starts with a
+or-, apply some logic to the corresponding menu item a. If the menu item has changes, apply them to the existing menu item b. If it is a simple deletion (no similarities or the next diff line is also a-), remove the menu item c. If it is a simple insertion, create a new menu item at that location
I understand that this is a potentially complex feature. However, I think it would be a great addition, especially for streamable plugins. In addition to fixing some existing quirks, it would make menus more dynamic and lay the foundations for potential future features such as #412.
The diffing algorithm itself isn't a problem. What I suspect would be a huge block is updating live the menus that are open. I don't think NSMenu is designed to do that, so it's probably a lot of hacking and dancing around. SwiftUI based menubar extra API is even more restrictive.
If you want to tackle this, it would make sense to build a small standalone test project to test if NSMenu can be reasonably updated when presented.
I might have a go at that when I get some time. I know the application Help menu has a search box that updates the menu in real time with search results, although that could be a different view embedded that updates. It certainly looks like the normal NSMenu though.