I thought it’d be worthwhile posting a note about this here, rather than anywhere else. For a few weeks now, especially via the plethora of email I tend to get about FVWM, and also with questions on IRC, has been mostly about the idea of context: what one is, and why there’s so many commands such as ThisWindow, Current, Pick, etc., and when best to use them, if at all.
What is a context?
When we speak of context, we mean an implied meaning, or object. In FVWM’s case, this could just about be anything, and all it means is that a command, or groups of commands (if they’re functions) expect a particular target on which to operate.
In key and mouse bindings, for instance, one can have two types of context. One of them is a window-specific context (that the key or mouse binding only applies to, as opposed to globally in FVWM). The other could apply to a part of a window (such as the client window, or the frame, or the sides, etc.) – this is seen all the time in things like this:
Key Up WTSF 3 WindowShade North
Which means that by press modifier 3 and the up arrow key, shades the window if the pointer happens to be in the client window (W), the titlebar (T) the sides (S) or the frame (F). If it were anywhere else, nothing would happen.
If the binding had been window-specific, as in:
Mouse (myterminal) T CM Echo hello
Then that would imply two thing: One, that in order for that binding to work, the window myterminal would have to be focused. And secondly, the titlebar of it would only be considered when pressing Ctrl © and Meta (M) in order for that binding to be considered.
There’s many more instances where this applies. Look at the menu command, for instance. There’s all manner of different contexts which can be conditionally applied (think of the Rectangle command, for instance).
Context and Conditional Commands
(Or, as I like to call it, Function Context.)
Almost all commands you could issue in FVWM rely on there being a known context; typically a window-context. So for example, suppose you had a function which displayed the name of a window:
DestroyFunc FuncDisplayName AddToFunc FuncDisplayName + I Echo "This window is called: $[w.name]"
And let’s assume that you were binding this to run every time a window received focus, as in:
DestroyModuleConfig FE-showname:* *FE-showname: Cmd Function *FE-showname: focus_change FuncDisplayName Module FE-showname
If you looked to STDERR (which is typically going to be in ~/.xsession-errors on most distros), you’d probably see a good number of lines there, as in:
[FVWM][Echo]: The window is: 'irssi' [FVWM][Echo]: The window is: 'sn'
This will work with most focus models, such as ClickToFocus or SloppyFocus. Now for a moment though assume that MouseFocus was in use:
Style * MouseFocus
MouseFocus works exactly like SloppyFocus, save for the fact that when the pointer enters into the root window, the previously focused window is defocused. Of course, in terms of our function though, the following will get displayed to STDERR:
[FVWM][Echo]: The window is: $[w.name]
This is because the context the function is now running in unexpected. Yes, the root window is still a window, and yes, it still receives events, but in terms of the function it’s not running within a known window context of client applications. Oops. Probably not what was intended at all. Luckily though, there’s a few ways of forcing and ensuring context.
ThisWindow, Current, Pick…
It’s typically not enough to assume that if a window has focus that a running command, or set of commands (if it’s a function) is enough to make sure that those commands will apply to that window. If you take any function, such as:
DestroyFunc MyFunction AddToFunc MyFunction + I Beep
Calling that from FvwmEvent, or as a binding to a window title, or whatever you wish will typically always imply a correct context in that it runs in a window. Just that it might not be the one you were expecting. To enforce a context or to at least ensure one, you can use one of two commands: ThisWindow or Current.
ThisWindow works on the window implied in the function context (that’s the window the function is told to run on). It’s useful to use in situations involving FvwmEvent on listeners such as add_window, enter_window, leave_window where it could be that the window isn’t always focused, or has the NeverFocus style set. Yep, ThisWindow implies !Focused when matching a window.
So for instance, assume you wanted to use FvwmEvent to make the computer beep whenever a window is mapped to the screen:
DestroyModuleConfig FE-beep:* *FE-beep: add_window Beep
That would work. Now let’s assume you wanted to make it work only for a
window named ‘foo’, you could just change that to:
*FE-beep: add_window "ThisWindow (foo) Beep"
It’s not always enough to assume when the window is mapped that it’s going to have focus (unless the GrabFocus style is in use) – and since we need to check for a known window in the above example, the ThisWindow command suits us nicely.
This operates like ThisWindow, except that it only applies to the currently focused window.
The Pick command is great. This works exactly like ThisWindow except that unless the function context is known beforehand, FVWM will prompt you to select a windowto operate on. If it does have a context already, then it will just run whatever it has been told to do so.
This commands is most useful in menus where it might not be entirely obvious if there’s a window context or not, as in:
AddToMenu MyMenu Close "Pick Close"
Hopefully that has been of some help to those of you who was asking (you know who you are).
– Thomas Adam