New Module: FvwmMonitor

FvwmMonitor creates a button sized window suitable for swallowing by FvwmButtons. It acts as a combination monitor applet and application launcher for multiple conditions and/or applications

FvwmMonitor allows the user to define a list of condtions (mailbox, battery power, cpu temp, whatever you choose) to monitor. Each condition has a number of possible states with the current state being selected by a user defined test. Each state can have its own icon, and its own mouse actions.

The module cycles slowly throught the states displaying each in turn for a few seconds. important states may be marked as critical and will displatyed in preference to non-critical states. uninteresting but logically necessary states may be marked as trivial and will not be displayed at all.

Further details are in the tarball. The manual page is in FvwmMonitor.html

This is brand new folks, and still pretty rough. Still, on the basis of “release early and release often” I’m posting this here as it. I’ve had it successfully monitoring local mail, my POP3 account and battery life.

Testing and feedback would be very much appreciated. If you feel like hacking on it, patches too.

Nuff said. Enjoy!

[color=red]Edited by theBlackDragon:
–> Moved from Complex Functions
–> Fixed the link that got broken due to some phpBB oddness[/color]

OK. I’ve updated the tarball, so this might be a good time to talk about how to actually use this sucker.

What it does is combine an arbitary number of buttons into one single button that cycles through all its icons. You can set mouse actions for individual icons, and you can have variant icons based on system states such as battery power, disk usage and email status.

FvwmMonitor uses the standard fvwm module configuration method, so you can control the module operation from your fvwm config. It works by defining conditions to monitor, and states that condition may occupy. One possible condition would be NewMail which has two conditions: true and false. Another might be battery charge, with conditions 00, 10, 20, and so in through to 90 and 100. You can also define tests to determine the current state of any condition, and mouse actions to be executed when an icon is clicked

Let’s have an example. Let’s start with a simple terminal launcher. Since our launcher is always going to look the same and always do the same thing, we don’t need to define any states, just the condition.

*FvwmMonitor: Condition Terminal, Icon l33t_LOG_tux.png
*FvwmMonitor: Condition Terminal, Mouse(1) "Exec xterm -bg black -fg purple"
*FvwmMonitor: Condition Terminal, Mouse(3) "module FvwmConsole"

That gives us a a button with a tux icon [1,2] which launches a term on a left click and a console on a right click. The Mouse actions are sent to fvwm directly. That means if you have invocation funcs to manage all the args for your terms you can call them directly by writing something like this:

*FvwmMonitor: Condition Terminal, Mouse(1) InvokeAterm
*FvwmMonitor: Condition Terminal, Mouse(3) InvokeConsole

To display the icon you can launch it like any other module. However, it’s designed to be swallowed by FvwmButtons

*FvwmButtons: (Swallow "FvwmMonitor" FvwmMonitor FvwmMonitor-Main)

Right. So now we have a picture of a penguin that launches xterms. Unfortunately, that’s nothing we couldn’t have done easier with FvwmButtons. To get the full benefit of this module we need more than one condition.

Let’s add a local mail checker. We’ll create a condition called “LocalMail” with two states: “Full” and “Empty”:

*FvwmMonitor: Condition LocalMail, State(Full) "Icon l33t_MAI_envelope.png"
*FvwmMonitor: Condition LocalMail, State(Empty), "Flag trivial"

Notice that I’ve not given the Empty state an icon. That’s because I’m not interested in being told when my mailbox is empty. Instead, I’ve flagged the state as “trivial”.

There are three levels of importance: trivial, normal and critical. Normal events are not displayed if one or more conditions are in a critical state, while trivial events are not displayed at all. This means that you don’t have to watch five minutes of irrelevancies scroll past before the monitor informs you that your CPU is busy catching fire.

Having defined out two scripts, we need a way to tell the module which state applies at any given time. We do this with Test and PipeTest directives. Let’s assume you’ve got a checker script called “checkmail” and that when run it prints either “Full” or "Empty: We can then write:

*FvwmMonitor: Condition LocalMail, PipeTest "checkmail"

This tells FvwmMonitor to run checkmail as a shell command every so often (10 seconds by default) and select a state based upon the output of the command. If you speak Perl, you can use “Test” instead of “PipeTest” and code the test directly in that language. This has the advantage, like torsmo or gkrellm, of executing in the same process and avoidig the overhead of starting and stopping a monitor script.

We also need to tell the module which output goes with which state, We do that with the Value keyword.

*FvwmMonitor: Condition LocalMail, State(Full) "Value Full"
*FvwmMonitor: Condition LocalMail, State(Empty) "Value Empty"

(Having the values default to the state names is a useful default I’ve just this minute thought of - expect it in the next release)

Of course, if the script returns something else the module won’t know what to display. We can add a default icon to the module to take care of this:

*FvwmMonitor: Icon l33t_DES_skull.png

Which displays a skull and crossbones if something goes wrong.

Finally, let’s add a mouse action to the Full state:

*FvwmMonitor: Condition LocalMail, State(Full) "Mouse(1) 'exec sylpheed'"

Right. If all goes well you should have a penguin icon that launches terms and consoles, unless you have mail in which case it splits its time between the penguin launcher and an email icon which launches a mail reader. Read your mail and it’s a full time terminal launcher again.

Let’s do a couple more. I get my mail over a POP3 connection from my ISP. I like to fetch it manually so I can delete the *$#% spam on the server. So I wrote a button to tell me if there was POP3 mail awaiting:

*FvwmMonitor: Condition Demon, SleepTime 300,
*FvwmMonitor: Condition Demon, Flag trivial
*FvwmMonitor: Condition Demon, State(Empty) "Value 0"
*FvwmMonitor: Condition Demon, State(Full) "Flag Normal, Value 1"
*FvwmMonitor: Condition Demon, State(Full) "Icon l33t_LOG_bsddevil.png"
*FvwmMonitor: Condition Demon, Mouse(1) "exec myat green mailer thead -m"
*FvwmMonitor: Condition Demon, Mouse(3) "*Test"

I’ve set the time to sleep between checks to 300 seconds so my ISP don’t think I’m DOSing them; I’ve used the BSD devil for a mail icon because I couldn’t find a demon internet one that’d fit inside a bubble and still look good, and I’m calling “thead”, my home grown spam filter, and telling it to launch a mail reader when its done - if there’s anything left to read.

One problem with a five minute sleep time is that, after you’ve read your email, it takes forever for the “mail waiting” icon go away. Hence the Mouse 3 action. Actions prefixed by a “*” are interpretted by the module rather than by FVWM. *Test means “perform the test for this action immediately”. So after I read my mail, if it still thinks there’s mail waiting I can right click on it and get it to update itself. This really needs a better solution, but this’ll do for the time being.

For the test, I thought I’d inline the perl code to show how that works. You don’t need perl, remember. If you can code it in bash, it should work using PipeTest. For those who can use perl however…

*FvwmMonitor: Condition Demon, Test "                                   \
        use Net::POP3;                                                  \
        my $pop = Net::POP3->new('');                   \
        my $rc = $pop->login(                                           \
                $ENV{ POP3_USER },                                      \
                $ENV{ POP3_PASS }                                       \
        );                                                              \
        return ($rc == 0 ? 0 : 1);"

The final condition I have on my desktop is a battery level monitor. All the conditions defined so far have been binary ones. For battery level I want 10% chunks from 100% to 00%. I knocked up some icons for the states:

You get the idea.

Now I need to define a condition:

*FvwmMonitor: Condition Battery, Flag normal
*FvwmMonitor: Condition Battery, SleepTime 30

And some states for that condition:

*FvwmMonitor: Condition Battery, State(00) "Value 0, Icon battery_00.png, Flag critical"
*FvwmMonitor: Condition Battery, State(10) "Value 1, Icon battery_10.png, Flag critical"
*FvwmMonitor: Condition Battery, State(20) "Value 2, Icon battery_20.png, Flag critical"
*FvwmMonitor: Condition Battery, State(30) "Value 3, Icon battery_30.png"
*FvwmMonitor: Condition Battery, State(40) "Value 4, Icon battery_40.png"
*FvwmMonitor: Condition Battery, State(50) "Value 5, Icon battery_50.png"
*FvwmMonitor: Condition Battery, State(60) "Value 6, Icon battery_60.png"
*FvwmMonitor: Condition Battery, State(70) "Value 7, Icon battery_70.png"
*FvwmMonitor: Condition Battery, State(80) "Value 8, Icon battery_80.png, Flag trivial"
*FvwmMonitor: Condition Battery, State(90) "Value 9, Icon battery_90.png, Flag trivial"
*FvwmMonitor: Condition Battery, State(100) "Value 10, Icon battery_100.png, Flag trivial"

So I’m not interested in seeing the power level if it’s 80% or higher, while if it’s less than 30% I don’t want to see anything else.

The test, at least in my config, is another swatch of perl returning a value in the range 0 to 10. I could just as easily done it using a bash script. If anyone’s interested in the perl, it’s in the example on the man page.

I also have another monitor icon in my config. This one defines a bunch of conditions, but no states. As such it cycles through a number of launchers, and duplicates the functionality of the MultiButton script I used in config-from-scratch. Except that this one doesn’t need an external script to drive it, and you get to configure which apps and icons it uses from inside your config file which is how things ought to be.

However, since I’ve rabbited on enough for one session, I’ll leave configuring that as an exercise for the interested student :wink:

[1] Except as noted, all icons are taken from the gentoo icon set.
[2] It used to be a terminal icon, but I got bored with it.

I’ll have to give this module a try as soon as I have some more time, this seems like one of those things I won’t be able to live without once I start using it…

This belongs more in “Other scripting languages” as it isn’t really an Fvwm function, so moving.[/color]

Maybe a “module writing” forum? New modules, module writing, general module discussion? I’d like to encourage module authors.

(ok, not the right forum for this comment, either :wink:)

I’ve also been thinking about that. And yes, it doens’t really belong here, but I’ll leave it here, this time :wink:

I finally got some free time to give this module a try and i have to say it is really really neat and usefull. I have one question though instead of displaying icons could it display text. Id like to setup a box that rotates through like time, weather, system temp, and things like that. It would be pretty easy to to have it display with icons but im a text kinda guy. Either way great work.


Thank you :slight_smile:

Text is a good idea. I’m currently in the last stages of writing up FvwmRingMenu. Once I get done with that, I’ll have a look. I want to do some work on it anyway. In particular, dynamic icon generation and if I can figure it out, I want to be able to swallow applets as well. With a bit of luck, text based icons will just be a special case of dynamic icons.

I’ll see what I can do, anyway

Swallowing FvwmScripts would be awsome. Whats FvwmRingMenu if i might ask.


– Thomas Adam

FvwmRingMenu is a module that displays a menu as a popup ring of icons rather than a drop list of text. It was something that I fancied taking a crack at, so I decided to use it as the basis of the perl based modules-from-scratch posts we talked about.

It needs a little more testing, the debug chatter turning off, and some sort of documentation (outside of the howto which is a bit verbose for some purposes). After that, I’ll release it to the world in general.

That sounds really cool. Ill have read your tutorial. Ive had my nose barried in perl tutorials been learning quit abit.


Btw, Nick, can one use your work in their configs? What is needed to give credit?

By all means do. If you want to credit me, something like "Thanks to Nick Fortune from the Fvwm Forums for … ".

Really though, I’m not going to get unduly upset if someone uses my sample configs without attribution. So long as they don’t try and claim they own the modules[1] I’ll be fine. :slight_smile:

[1] Darl McBride - This Means You

What’s wrong with that?

Use of uninitialized value in pattern match (m//) at /home/andrea/.fvwm/mods/ line 74. Use of uninitialized value in pattern match (m//) at /home/andrea/.fvwm/mods/ line 80. Use of uninitialized value in pattern match (m//) at /home/andrea/.fvwm/mods/ line 85. Use of uninitialized value in pattern match (m//) at /home/andrea/.fvwm/mods/ line 89. Use of uninitialized value in concatenation (.) or string at /home/andrea/.fvwm/mods/ line 93. FvwmMonitor: error during configuration near Condition Battery, Flag normal, SleepTime 30, Test my (, ); my = qq(/proc/acpi/battery/BAT0); open IN, qq(/info) or die qq(can't read /info); while(<IN>) {/last\s+full\s+capacity:\s+(\d+)\s+mWh/ or next ; = ; } unexpected keyword: at /home/andrea/.fvwm/mods/ line 93.