The attached patch implements feature request 1051168. With this patch applied you can have a menu entry like the following:
[submenu] (External Media)
[include] (|fbmount -menu)
[end]
Note the pipe character in the path. Whenever the menu is opened, the shell command following the pipe is executed and its stdout output is parsed for the include. In the above example (the program fbmount is included in the patch) the command "fbmount -menu" is executed which will create a menu for all removable media such as USB sticks with entries that look like this
[_] USB stick 1
[X] USB stick 2
where the [_] or [X] shows whether or not the respective media is mounted. If such a menu entry is selected, the media is mounted or unmounted via p(u)mount.
A nice mounting solution for people who want something simple that does not require hal, dbus, etc. To make full use of this, you should probably
create a file /etc/udev/rules.d/99-usb-beep.rules with the following single line:
ACTION=="add", SUBSYSTEM=="block", KERNEL=="sd*[0-9]", SUBSYSTEMS=="usb", RUN="/lib/ude
and a shell script /lib/udev/beep with the following contents:
#!/bin/sh
echo $'\a' >/dev/console
This will make your system beep whenever a device you inserted is ready to be mounted, so that you won't have to open and close the fluxbox menu waiting for the devices to appear.
The patch is for git revision e2d52a39485d0ab9d5cb5ae027372b612eb32e60 but applies (except for the manpage stuff) even to 1.1.1.
initial comment:
i dislike the pipe thing at general, if the command blocks then fluxbox blocks which sux, window - management wise :) i prefer external apps creating the menu-stuff (cron, anachron etc) and fluxbox uses [include] and end of story.
anyway, regarding your patch:
* fbmount: can you write that in /bin/sh as well? and it belongs to into a separate feature-request/patch. and thats only working on linux, isn't it?
* isLoaded(): is that good enough to check for 0? .is_open() is a bit different than just not beeing 0
* provide a flag and a function call to determine if that menu entry is actually a pipe command, something like isPipe(). hardcodeing filename[0] == '|' is not 'good style'
general comments:
* blocking commands .. we need a solution for that.
* commands creating invalid syntax .. we need good reporting about which pipe-command caused this
and maybe the '|' is a bit hard to spot and using [pipe] instead of [include] would be .. better :)
I'm not actively working on this feature. It's actually a couple years back that I wrote it. It's just that I upgraded fluxbox now and decided to take the time to publish the patch in case someone is interested.
About isLoaded(): Since the fluxbox code has no comments specifying the method's contract, I can only guess what it's supposed to do. I'm pretty sure that when I wrote the patch I reviewed the callers of that function and verified that they were happy with the new implementation. But that was years ago. For the current version I just git-rebased and was happy to find that the only conflict was in the manpage.
About syntax and implementation: You're right, of course, but when I wrote the feature it was just to scratch an itch and I wanted to get it done with as little work as possible and as little touching of the code (to keep the patch working and to avoid the hassle of constantly resolving merge conflicts when updating). To fit this feature properly into fluxbox would require that I become a lot more intimate with the fluxbox code.
About the blocking problem in general: The only proper solution I see is to have the menu run as a separate thread/process, possibly even living in its own binary like fbrun. But that's a pretty heavyweight solution with all the added IPC that would entail. Certainly not justified simply to get dynamic menus. There would have to be other benefits to justify such a refactoring and I don't see that at the moment.
About dynamic menus vs. generated includes: The USB stuff could certainly be converted so that it's run directly by udev to generate an include for the fluxbox menu. But there are other applications for dynamic menus. For instance just yesterday I've written a dynamic menu script that implements a task manager. It creates a menu that has a submenu for every running task and the submenu allows to send signals to that task. This would not be feasible without dynamic menus since the process list changes too fast. Of course it's all just little toys.
I'm NOT arguing that dynamic menus are a must-have for fluxbox, just that they allow someone who can write shell scripts to do a lot of fun things quickly.