Dynamic FvwmButtons panels


I am trying to make a FvwmButtons panel which would reconfigure itself upon certain events. Reacting to the events works fine. However, sometimes it happens that the panel turns out to be empty (as semantically expected), which causes the “No buttons defined. Quitting.” error. So far, so good.

The problem is that upon the next reconfiguration (again, as a result of receiving some event), the FvwmButtons instance of the modules is not respawned, so the panel stops working.

The code. First, the button which is used to activate the panel:

*SystemPanel: (2x3, Icon icon.png, Colorset 24, Panel (left) MyPanel "Module FvwmButtons -g -3000-3000 -transient MyPanel")

Now, the function that defines the panel itself:

[code]DestroyFunc RestartMyPanel
AddToFunc RestartMyPanel

  • I DestroyModuleConfig MyPanel: *

  • I *MyPanel: Rows 1

  • I Test (…) *MyPanel: (Icon icon1.png, Colorset 25, Action Func1)

  • I Test (…) *MyPanel: (Icon icon2png, Colorset 26, Action Func2)

  • I Test …

  • I KillModule FvwmButtons MyPanel

The events mentioned above always result in calling RestartMyPanel. As said, everything works fine until MyPanel ends up to be empty after some series of events.

Fvwm 2.5.18. Any ideas?

Many thanks,

– owl

You’re entire config is needed, not the unhelpful snippet you provided.

– Thomas Adam

Thanks for the reply, Thomas. Can you be more specific as well? I assume that not the entire fvwm config is needed (e. g. colorset definitions, FvwmScripts, unrelated functions, path definitions certainly not). Also, I am not saying that fvwm is doing something unexpected.

From the man pages, I think I get the basic concept that panels are started as soon as the button representing the panel is defined and the process implementing the panel stays running from that moment on (please correct me if I’m wrong on this). What I don’t understand is whether either

  • the invoking FvwmButtons instance can be made to respawn the panel process if it dies (e. g. the Respawn, NoOld flags or -transient vs. -transientpanel options), or,
  • there is another/better way to provide the functionality described in the original post.

What I do expect as well is a FvwmButtons’ quitting when there is no button defined for the given instance.

The RestartMyPanel function is fairly complete as given before (I just removed some Test… lines almost identical to the ones posted. The tests work as expected, adding a button to MyPanel when the condition is met. The SystemPanel config is as follows:

DestroyModuleConfig FvwmButtons: SystemPanel
*SystemPanel: Geometry -0+0
*SystemPanel: Columns 6
*SystemPanel: Frame 1
*SystemPanel: BoxSize smart

*SystemPanel: Colorset 10

*SystemPanel: (6x6, Frame 1, Size $[SPWidth] 0,       Swallow(UseOld,NoClose) "FvwmScript.clock" "FvwmScript FvwmScript.clock")

*SystemPanel: (6x12, Frame 1, Size $[SPWidth] $[PagerH], Swallow(UseOld,NoClose) "SystemPager" Nop)

*SystemPanel: (2x3, Icon terminal.png, Action 'Exec "xterm" xterm &')
*SystemPanel: (2x3, Icon iceape.xpm, Action 'Exec Iceape" iceape &')
*SystemPanel: (2x3, Icon gnu-32x32.xpm, Action 'Exec "emacs" exec emacs')
*SystemPanel: (2x3, Colorset 12, Swallow(UseOld,NoClose) xlassie "Exec xlassie -shape -fg blue -hilight red", Action "Exec $[MailCmd]")
*SystemPanel: (2x3, Icon m.png, Action 'Exec sleep 0.3; xset dpms force off')
*SystemPanel: (2x3, Icon apps/gnome-logout.png, Action Logout-or-Winlist)
*SystemPanel: (2x3, Icon kdeclassic/32x32/actions/configure.png, Colorset 24, Panel (left) MyPanel "Module FvwmButtons -g -3000-3000 -transient MyPanel")

Module FvwmButtons SystemPanel

As above, any hints are appreciated. Should you need more from the config, please tell me again.


– owl

You said it was related to specific events? Which? One’s you have defined? Again, I don’t see this from your config snippet. If I ask for your config in its entirety, it’s because of the interaction of the different components, not because it’s going to waste my time.

Please make it available.

– Thomas Adam

Oops… There might be a misunderstanding here. The panel’s reconfiguration is triggered by various events from the filesystem, udev, and others. By this, I do not mean events in the fvwm sense, however. Every event mentioned ends up calling RestartMyPanel somehow, usually via FvwmCommand. The triggering is working fine, again (I tried using Echo’s from within RestartMyPanel). And, the panel works fine (and as expected) until it gets empty (i. e. no condition in RestartMyPanel is satisfied), which is when the MyPanel instance of FvwmButtons dies.

Does it make sense now?

– owl

This will be some race condition then, where you have more than one event calling your RestartMyPanel function. I would rethink how you’re handling that, either using PipeRead, or Read.

– Thomas Adam

I certainly will look at that, thanks for the idea. Without wanting to downplay it, however, at first look it doesn’t seem to be the main problem. The events I check for don’t come very often, usually every 5-10 minutes or so. Plus, the observed behaviour is rather deterministic: as long as at least condition in RestartMyPanel is met (= at least one button defined), everything works fine. As soon as all Test()s fail, MyPanel dies (going out of buttons) and is not respawned again.

To get at least one fixed base for further experiments: would you normally expect SystemPanel (FvwmButtons instance) - given the configuration provided - to respawn MyPanel after it had died? If not automatically, then perhaps upon pressing the appropriate button (which correctly causes MyPanel only to slide out, as long as MyPanel does not die)? Perhaps using some options?

One more note: since the events don’t appear too often and MyPanel is normally not used very often either, a solution which would cause MyPanel to be started again every time the SystemPanel’s button is pressed would probably also be fine.

Many thanks!

– owl

For anyone who might be struggling with similar issues, here’s my solution/workaround: it is simply enough to add

+ I Module FvwmButtons -g -3000-3000 -transient MyPanel

as the last line of the RestartMyPanel function.

The reason is as follows: FvwmButtons does seem to respawn panels which have died after all. However, it does so only once (for obvious reasons), and it does so immediately after it notices the termination of the panel in question.

In this particular case, it means that there are no race conditions or anything spectacular. What happens is only that after MyPanel gets empty (due to some series of events, see previous posts), it dies. Fvwm realises this and tries to respawn. However, this happens too quickly, usually before any further events (which would cause MyPanel to get any buttons back again) happen. Fvwm then gives up.

If any of the developers is reading this: I think this behaviour is just between a bug and a feature. In this case, it would help to make fvwm not respawn a terminated panel immediately, but only when its button is pressed again. However, I do not dare to consider whether this would not break other things elsewhere.

Hope this is useful for anyone around.

– owl

This wouldn’t work anyway – you get an empty button this way.

– Thomas Adam

Well, it wouldn’t work per se. However, it would help in this particular case (and maybe others), although the reason behind that is not really a technical one.

What would happen in a typical scenario is this: when the user presses the button which normally starts MyPanel, and MyPanel has no buttons defined due to certain series of external events, in quits (as it does now). Then, a typical user would probably do something which would probably cause other external events to appear, adding buttons to MyPanel. When the user presses the activating button again, and the attempt to respawn is made only then, the respawn attempt would not fail (contrary to what it does now).

The question is, if such a “use case” is more frequent than perhaps others (I can’t currently think of any, however), which might benefit from current fvwm’s behaviour.

– owl