FVWM Tips

I am not too good at these things, so bear with me. I’ve been seeing more and more configs (both in terms of answering questions on these forums, and via IRC, with ad-hoc email, etc.) that seem to be redefining existing functionality for no good reason other than (I assume) ignorance.

So here’s a few things to bear in mind (in no particular order):

  1. SetEnv.

Ah yes. SetEnv. I would never had imagined how such an insignificant command would annoy me so much, especially through its apparent mis-use. It seems more and more people are defining things like this:

SetEnv fvwm_home $[HOME]/.fvwm

Which is innocent enough, and indeed works. Except for the fact that it’s completely unnecessary. FVWM defines for you (which you yourself can change) the environment variable FVWM_USERDIR which by default will point to ~/.fvwm – so why in hell people seem to think setting “fvwm_home” is doing themselves any good is beyond me.

Now consider for the moment the implications of doing so. By and large it’s fine, because you presumably wrote the configuration, right? Well, yes, but what happens when you decide to share your all singing all dancing, brand-new complex function you spent the past two days trying to write? What if it contains a reference to “fvwm_home”? The person deciding to try that function is going to come unstuck because he or she may not have “fvwm_home” defined. You should always rely on using “FVWM_USERDIR” where you need to reference a likely and pre-defined location for personal configuration files.

If you’re one of these people whom uses a split configuration file via a series of Read commands, and hence had relied on something like:

Read $[fvwm_home]$[some_other_location]/file1

Read understands (and expands) the variable “$.” relative to a path – so you can use that as well to further increase neutrality.

Not to mention that it leaves endless environment variables defined which might only ever get used once.

  1. InitFunction versus StartFunction versus RestartFunction

Unless you’re someone as foolish as I am, and are still using FVWM 2.4.19, FVWM 1.24 and FVWM 2.2.5, this is going to be of consideration to you. OK, I joke. This is really only of importance to the small minority of people running FVWM stable (2.4.19). For the rest of you running 2.5.X (at the time I writing I would hope 2.5.16) then you need to be made aware of the following:

You don’t need to use InitFunction

Gasp! It’s true. In FVWM 2.4.X, you do need to use it because the Test command does not include tests for Init, Reboot, etc. However for FVWM 2.5.X, forget InitFunction, and incorporate it into your StartFunction. Here’s an example:

DestroyFunc InitFunction
AddToFunc   InitFunction
+ I Exec exec xsetroot -solid pink
+ I Exec exec xconsole

DestroyFunc  StartFunction
AddToFunc    StartFunction
+ I Module FvwmProxy
+ I Module FvwmButtons myBar

Put the two together, and from within your StartFunction you can define what’s in InitFunction via the use of the following:

+ I Test (Init) ...

Hence:

DestroyFunc  StartFunction
AddToFunc    StartFunction
+ I Module FvwmProxy
+ I Module FvwmButtons myBar
+ I Test (Init) Exec exec xsetroot -solid pink
+ I Test (Init) Exec exec xconsole

And that’s it. There you have it. You now have a StartFuction which FVWM reads at Init, Reboot and Exit. The same logic applies for RestartFunction:

You don’t need to use RestartFunction

What is even more perplexing about this is I have seen a lot of configs which define the following:

DestroyFunc  StartFunction
AddToFunc    StartFunction
+ I Exec exec xterm -T Wooo -ls

DestroyFunc   RestartFunction
AddToFunc     RestartFunction
+ I Exec exec xterm -T Woo -ls

Now, guess what this does. That’s right, when you reboot FVWM you get two copies of the same xterm running. That’s because, again, StartFunction is read by FVWM at initialisation and reboots. FVWM hence re-reads RestartFunction and StartFunction and does the same thing twice. How do you get around this. Easy: remove the definition for RestartFunction entirely. If that application is only intended to be started during a restart (slightly odd scenario) then use:

DestroyFunc  StartFunction
AddToFunc    StartFunction
+ I Test (Restart) Exec exec xterm -T Woo -ls
  1. Exec exec and the dreaded FvwmCommand versus PipeRead.

This one baffles me profoundly. The classic observation of this is with some of the many different incantations of Thumbnail functions that exist. Here’s a snippet:

DestroyFunc Thumbnail
AddToFunc   Thumbnail
+ I Exec nice 19...; some_other_shell_commands; FvwmCommand 'WindowStyle foo, bar'

ARGH! What the hell is that all about? For the love of God, learn how to use PipeRead. Please? It’s not that hard. Consider what’s happening with the above. Exec forces a shell, some idiotic processing goes on (probably running convert a few times) and then FvwmCommand forces FVWM to be told instructions via FIFO. How dull, when all this time PipeRead would have saved you all of the superluousness of it all.

PipeRead forces a shell, but more importantly one is then able to “echo” commands back to FVWM. Not only does this synchronise things (especially if the PipeRead command exists within a function) but it means you don’t have to worry about sending commands back indirectly via FvwmCommand. FvwmCommand is only useful if you’re calling some external script that doesn’t rely on directly ending with FVWM (or where you don’t want it to block with PipeRead).

If you ever find yourself writing:

+ I Exec ...; FvwmCommand '....'

You want PipeRead.

  1. I’m too good to use ImagePath.

This one always makes me laugh, and it comes back to point 1, with SetEnv. Again, most people delight in doing something like this:

SetEnv fvwm_home $[HOME]/.fvwm
SetEnv fvwm_images $[HOME]/.images
SetEnv fvwm_icons $[fvwm_home]/.icons

Style some_app Icon $[fvwm_icons]/icon.png

When actually all you need to do is this:

# Remove all those damn SetEnv commands
ImagePath $[FVWM_USERDIR]/.icons:+

Then you can do stuff like this:

Style some_app Icon icon.png

And FVWM will know where to look by traversing the directories listed in the ImagePath.

If I think of any more, I’ll let you know.

– Thomas Adam

Excellent tips, thanks Thomas. :slight_smile:
(I just realized I’ve made some mistakes in the past… ) :blush:

One question which has bothered me pretty long:
could you be kind and explain why exactly does one need DestroyFunc/Menu/etc. , ie. what are the consequences of not using them?
If not doing any changes to them on the fly.

They’re useful in clearing any previous definitions for the named menu/function/etc. Without them, AddTo{Func,Menu} are cumulative in that they’ll define (if none exists) and then continually add to the definition of the menu or function they’re defining. In most circumstances this is fine, although imagine what happens when a file is read from within FVWM (during its lifetime) – if a Destroy{Menu,Func} command did not exist, any subsequent AddTo{Func,Menu} commands would append to the definition, possibly tainting or giving incorrect results.

– Thomas Adam

So I wanted to post a short note about this; I’ve had some private feedback about the initial points which I made. Overall feedback was good, so I am pleased the some of you have understood the points I’ve been trying to get across. At the end of the day they are only suggestions, however it seems that one or two of you are confused about the whole {Start,Init,Restart,Exit}Function.

The only reason I advocate the sensible (and logical) use of StartFunction to declare things in rather than using separate Init and Restart functions is because having the use of StartFunctgion supercedes them, and renders them superfluous; and as such, I would like to see Init and Restart and friends removed from, say, FVWM 2.6.X. I daresay this will happen, so get used to the idea. When you consider that, if you don’t use StartFunction, then to make programs run across Init and Reboot you have to do this:

DestroyFunc InitFunction 
AddToFunc   InitFunction
+ I Exec exec some_app

DestroyFunc  RestartFunction
AddToFunc    RestartFunction
+ I Exec exec some_app

But as has already been discussed by me, this leads to some issues:

  1. You have to be aware of what the difference between an Init and a Reboot is.
  2. Unless you use SetEnv, you have two different areas to maintain state between the running applications in each case.
  3. If you add StartFunction in your config without realising it, and then add a call to exec some_app, it will load numerous times.

So it’s entirely up to you – either you can continue with completely separating out the common functions from StartFunction, or you can follow something like a good suggestion and use StartFunction which is what I would consider to be the proper method.

– Thomas Adam

so i read this, and its useful. does this also apply to fvwm 2.4 or does no one use that?

would you recommned 2.4 fvwm or not? i am just curious.

also your writing is quite harsh in some things. people are not idiots or stupid for using setenv maybe you should rewrite it to be less insulting

Look at the very first paragraph in my initial post – you’ll notice that it mentions it’s only applicable to FVWM 2.5.X

It depends what you mean, of course. FVWM 2.4.X is very stable, but lacks a lot of newer features almost all newcomers to FVWM expect, having used some other random window manager. There are though, several instances where I have suggested people use FVWM 2.4.X given their circumstances. (Don’t ask for details, you won’t get any).

In the general sense though, using FVWM 2.5.X is what I would recommend.

I still use FVWM 1.24 due to posterity and for the fact that it resembles MWM more closely than 2.4.X in terms of decor rendering.

No, I won’t rewrite any of it. Free speech allows me to say whatever the hell I like.

– Thomas Adam

Hi Thomas,

You make quite a few excellent points in your post. However I seem to disagree with your “PipeRead” tip. As you say above, I use Exec and FvwmCommand for thumbnailing. However I have a rather slow machine at home, so resizing the xwd screenshot is slow and laggy as hell.

I use PipeRead to synchronously take a screenshot (using xwd) of the window in question. Then I use Exec + FvwmCommand to resize this screenshot, and composite it with the appropriate mini-icon in the background. If I used piperead, I would have to resize the screenshot synchronously, which makes me have to wait a few seconds every time I minimize the window.

The only situation where this Exec + FvwmCommand situation is useful is when you want to execute some time consuming code in the background. Otherwise, as you rightly say, we should be using PipeRead

GI

The reason you want PipeRead is to ensure synchronosity. Without it, there’s a chance one command will run out of synch from another, and hence the whole thing goes to pot. If you search the forums for… ‘thumbnails’ and view a thread from the user ‘stardotstar’, you’ll see exactly why PipeRead is important for just this situation.

[…]

– Thomas Adam

Actually, the only reason you want PipeRead is to actually take the window screenshot. This step is quite quick, even on my slow home computer.

However, once you have the screenshot you can manipulate it as desired asynchronously. Resizing the screenshot (and putting a mini-icon on it for example) is quite slow on my home computer, and sometimes takes almost one second.

If I used PipeRead for this step too, fvwm would do nothing while my slow computer was creating the thumbnail! Which would make things laggy as hell. Which is where Exec + FvwmCommand come in handy. For instance, what I have in mind is something like:

AddToFunc Thumbnail
+ I (commands to raise the window)
+ I PipeRead 'xwd ...' (take the window screenshot and save it to a file)
+ I Iconify True
+ I Exec 'convert ...; FvwmCommand ...'

The (super slow) “convert…” part resizes the icon as desired in the background. Once the icon is ready, the FvwmCommand part installs it.

This works flawlessly on my system (even with shaded / obscured windows). The minor annoyance is that thumbnails “show up” about a second after the window is minimized. However I don’t have to “wait” for the thumbnail to “show up”. I can happily work on whatever it is I’m doing in the mean time.

I don’t see how Exec + FvwmCommand can (or should) be avoided in this situation.

GI

It depends what you’re doing.

– Thomas Adam