mlvwm
mlvwm copied to clipboard
Consider adding dynamic applications menus or menu items
Currently, one has to manually add menu items that exec applications if they want to list & launch applications from a menu. In mlvwmrc
, an "Apple" menu is provided by the various themes, but also needs to be manually updated. I'm considering using or implementing a tool for mlvwmrc
to generate application menu items, but that would still need to be run manually and would require a restart of mlvwm
to update the menu items.
It might be most helpful if mlvwm
could dynamically generate & update application menu items. In terms of customization, it'd probably be best to add a built-in command that could be used in menus (or as a submenu?) which would just include the dynamic list of applications.
Of course, to implement this, we'd need a way (or ways) to get a list of applications installed locally and preferably get 16x16 px icons for applications. If there's a way to get a class of application (e.g. "application", "utility", etc.), that'd be a bonus. According to the helloSystem project, there a number of APIs that can/need to be used:
- DBusMenu spec:
- libdbusmenu-qt (Qt)
- libdbusmenu (Qt & GTK+)
- StatusNotifierItem spec:
- org.gtk.Menus
- ApplicationIndicators
- ...
There's a lot to research & understand. There are also applications like MenuLibre which allow editing desktop & menu entries.
I really don't want to require DBus, Glib, GTK, or Qt for mlvwm
, so that might kill this idea pretty quickly.
In a recent discussion with Lucas de Sena and Thomas Adam on Mastodon, I mentioned wanting to implement some sort of dynamic menu functionality (this issue).
The next step here is to see how the current Menu
built-in function is implemented, so last night I did some testing to see what happens if multiple Menu
built-in functions are called with the same name. I started with the following basic config file:
Menu Default-File, Label "File", Left
"Test 1" NonSelect, Gray, Action Nop
END
Menu Default-File, Label "File", Left
"" NonSelect
"Test 2" NonSelect, Gray, Action Nop
END
MenuBar default
Default-File
END
Style
"*" MiniIcon mini-x.xpm, MenuBar default
END
When loading, I did not receive any errors, but only the first Default-File
menu appeared in the menu bar. Commenting out the first Default-File
menu resulted in only the second menu appearing in the menu bar. This and some more experimenting confirmed the following:
- Only the first
Menu
defined with a particular name will be used - Any additional
Menu
s defined with the same as a prior one will NOT:- Add menu items to the previously-defined
Menu
- Replace menu items in the previously-defined
Menu
- Result in any errors in processing the configuration
- Add menu items to the previously-defined
Digging further into SetMenu()
in mlvwm/menus.c
, I see that every call to the Menu
built-in function will:
- Allocate memory for a new, temporary
MenuLabel
- Set this temporary
MenuLabel
as either theScr.MenuLabelRoot
(if there isn't already one) or walk the linked list ofMenuLabel
s and link it to the lastMenuLabel
(appending it to the linked list) - Until an
END
keyword is encountered, parses each line and callsAddMenuItem()
This means that multiple Menu
calls with the same name will result in the duplicate being appended to the linked list of menus, but it appears that only the first menu in the linked list with a particular name will be used. I still need to trace out exactly where this happens.
This certainly aligns with the naming of the internal SetMenu()
function.
On a related note, in addition to AddMenuItem()
, ChangeMenuItemLabel
and DelMenuItem()
internal functions are implemented and used in some functions in event.c
& functions.c
. So, we certainly have what we need to implement dynamic menus of some kind.
NOTE: The Read
built-in function CANNOT be used within Menu
or MenuBar
blocks.
A further discovery made in the aforementioned Mastodon thread is that FVWM has a ReadPipe
function. See ReadPipe
in the FVWM
manual page.
As mentioned, mlvwm
doesn't support Read
within Menu
or MenuBar
blocks, so implementing ReadPipe
wouldn't necessarily address this issue on its own, but it would be helpful in allowing external applications or scripts to dynamically provide mlvwm
configurations on-the-fly. Food for thought.
This is related to Issues #45 & #47 in that it probably has the same type of memory leak. I'll have to double-check.
Also, like #45 and considering the fvwm
implementation of AdToMenu
& DestroyMenu
built-in functions, I'm thinking the easiest initial solution would be to update the Menu
built-in command to create or append, then add a new DestroyMenu
built-in that will destroy a specific named menu. This would allow a named menu to be created, appended to in subsequent calls, and destroyed if you want to rebuild it entirely.