dynamic color/pixmap/whatever of titlebar button

I’d like to dynamically change the color of a titlebar button, dependent on some
state the window is in (which is managed with a State variable).

How can I do this? I’ve read the manual head to tail and diagonally, but it hasn’t
become very clear how to do this elegantly and in a simple way, and on top of
that all my attempts so far failed.

Basically, the button should be more an indicator of a state. It would be nice if
I could still click on it as with a real button, but for now I’d settle with anything
that just changes color/pixmap whenever a state is true (or false) for the window.

Thanks for any pointers.


[color=red]Edited by theBlackDragon:
–>Moved from Basic questions[/color]

Hmm. This depends whether you’re using vectors or pixmaps, or indeed pngs. You cannot change the background colour of a button which uses vectors. But what you can do (possibly) is change the background colour of a png. But there are some caveats to be aware of:

  1. The PNGs would have to be predefined with an appropriate background.

  2. It might not give the effect you wanted – especially if the buttons are small.

I suppose you could script 1. above, using convert(1), but it depends. Anyway to do what you want, you probably want to use FvwmEvent. You can then get FvwmEvent to listen for certain “triggers” that can then be tested to see what actions need to be performed.

Since I don’t know the precise details of what it is you’re wanting to test, I’d suggest an initial FvwmEvent config of something like:

DestroyModuleConfig FvwmEvent-State: *
*FvwmEvent-State: PassId
*FvwmEvent-State: Delay 1
*FvwmEvent-State: configure_window 
*FvwmEvent-State: focus_change     FvwmToggleStatePixmap
*FvwmEvent-State: add_window       FvwmToggleStatePixmap

Here, what that is saying is that there is a one second delay before the initial conditions are looked for. This is done so that we don’t get ourselves into a loop that might otheriwse cause us grief.

Ignoring that for the moment, the next thing we need to consider is how your decors are going to be arranged. What I would do, is rather than write out separate decors for each case, simply define a variable Fvwm can use. So at the top of your ~/.fvwm2rc file, you might have something like:

SetEnv fvwm_button ~/.fvwm/icons/default.png

Then in your default decor definition, you might have something like:

AddToDecor NormalDecor
+ BorderStyle Simple
+ TitleStyle  -- Raised
+ ButtonStyle Reset
+ ButtonStyle All -- Raised
+ ButtonStyle 1 Active    Pixmap [b]$[fvwm_button][/b]
+ ButtonStyle 1 Inactive Pixmap [b]$[fvwm_button][/b] 
+ ButtonStyle 3 Active    Pixmap mini-go.xpm
+ ButtonStyle 3 Inactive  Vector 3 60x20@0 60x40@0 80x40@1 80x60@0 60x60@0 60x80@0 40x80@0 40x60@1 20x60@0 20x40@1 40x40@1 40x20@1 60x20@1
+ ButtonStyle 6 Active    Pixmap mini-rball.xpm
+ ButtonStyle 6 Inactive  Vector 5 40x40@1 60x40@1 60x60@0 40x60@0 40x40@1
+ ButtonStyle 4 Active    Pixmap mini-iconify.xpm
+ ButtonStyle 4 InActive  Vector 5 25x25@1 25x75@1 75x75@0 75x25@0 25x25@1
+ ButtonStyle 2 Active    Pixmap mini-x.xpm
+ ButtonStyle 2 InActive  Vector 17 20x20@1 30x20@1 50x40@1 70x20@1 80x20@1 80x30@0 60x50@0 80x70@1 80x80@0 70x80@0 50x60@0 30x80@0 20x80@0 20x70@0 40x50@1 20x30@0 20x20@1

It’s the parts in bold in the decor that are the key – for whichever button you’re wanting to have changed, you will have to change your decor like at the top.

So having done that, all we need to do now, is to create a function that gets run when the FvwmEvent we defined earlier is triggered. Now, you said you wanted to test on the value of a State – that’s fine. I’ll just show you an example for if it were a sticky window, say:

DestroyFunc FvwmToggleStatePixmap
AddToFunc   FvwmToggleStatePixmap
+ I Any (CurrentDesk Sticky AcceptsFocus) SetEnv fvwm_button ~/.fvwm/some_other_name.png
+ I All (CurrentDesk Sticky AcceptsFocus) WindowStyle UseDecor NormalDecor

In that way, if the function doesn’t match any sticky windows, the value of $[fvwm_button] is never updated, and hence your button on your windows never changes.

You can obviously adapt this to suit your needs, even for State-aware windows as well.


– Thomas Adam.[/b]

This is another using Mwm states with xpm -files (I don’t see why it wouldn’t work with png-files, too):

imagepath $FVWM_USERDIR/images:+:/usr/X11R6/share/fvwm/pixmaps

style           *               MwmButtons, MwmFunctions

Colorset        0               Vgradient 128 honeydew3 honeydew4, fg white
Colorset        1               Vgradient 128 gray darkgrey, fgsh gray

# Style         button# [state]         [style]                         [-- [!] flag ...]
titlestyle              active          (colorset 0) \
                        inactive        (colorset 1)                    -- flat
borderstyle             active          (colorset 0) \
                        inactive        (colorset 1)                    -- usetitlestyle hiddenhandles noinset

buttonstyle     1                                                       - MwmDecorMenu
buttonstyle     2                                                       - Clear
buttonstyle     3                                                       - MwmDecorShade
buttonstyle     4                                                       - MwmDecorMax
buttonstyle     5                                                       - MwmDecorStick
buttonstyle     6                                                       - MwmDecorMin
buttonstyle     1                       miniicon
buttonstyle     2       inactive        (pixmap mini.x2.xpm) \
                        active          (pixmap mini.x2.xpm)
buttonstyle     3       inactive        (pixmap mini.shade1.xpm) \
                        active          (pixmap mini.shade1.xpm)
buttonstyle     4       inactive        (pixmap mini.resize3.xpm) \
                        active          (pixmap mini.resize3.xpm)
buttonstyle     5       inactive        (pixmap mini.stick.xpm) \
                        active          (pixmap mini.stick.xpm)
buttonstyle     6       inactive        (pixmap mini.iconify1.xpm) \
                        active          (pixmap mini.iconify1.xpm)
buttonstyle     all     toggledinactive (colorset 1) \
                        toggledactive   (colorset 0)
buttonstyle     2       toggledinactive (pixmap mini.x2.xpm) \
                        toggledinactive (pixmap mini.x2.xpm)
addbuttonstyle  3       toggledinactive (pixmap mini.maximize-vert1.xpm) \
                        toggledactive   (pixmap mini.maximize-vert1.xpm)
addbuttonstyle  4       toggledinactive (pixmap mini.maximize1.xpm) \
                        toggledactive   (pixmap mini.maximize1.xpm)
addbuttonstyle  5       toggledinactive (pixmap mini.stickpressed.xpm) \
                        toggledactive   (pixmap mini.stickpressed.xpm)
buttonstyle     all                                                     -- flat usetitlestyle