Config-From-Scratch

A Quick Note: This is the first of a seies of posts I made to the gentoo Fvwm thread, reposted here at the suggestion of tBD. Hope this is the proper topic for these. If not I trust the mods will set me right :wink:
[/note]

A lot of people get put off FVWM, I think, by the default setup. The first time you start it up, you get a basic ugly X11 default mesh background. It looks just like FVWM failed to run at all. If you click on the background you get a very basic menu, but even so, initial facilities are limited.

On the other hand, it doesnā€™t take a lot to get something bareable configured. My current config started out as a barebones config for testing experimental constructs - only came to prefer the experiment to my then main config. Since then Iā€™ve written three more from scratch. Itā€™s fun and you learn a lot each time. So, if the old hands will forgive me, I thought I might talk about setting up a bare minimum FVWM config from scratch.

The first essential, for me, is wallpaper. There are a lot of ways to do this, but the simplest starting out is to use fvwm-root. Thatā€™s a standalone program whic you can call from the command line or from your fvwm config. Youā€™ll need a PNG format wallpaper. If your fave is in jpeg format you can convert it with ImageMagick:

convert foo.jpg foo.png

You can test fvwm-root from the command line. Start up that ugly grey FVWM config, choose xterm from the menu and type

fvwm-root --retain-pixmap foo.png

The ā€œretain pixmapsā€ option is handy if you want transparent terms or menus later on.

Assuming that works, add it into the config file:

DestroyFunc StartFunction
AddToFunc StartFunction
+ I Exec exec fvwm-root --retain-pixmap /path/to/foo.png

Quit and restart to make sure it works. Itā€™s far from slick, but it no longer makes my eyes bleed.

Other essential elements of any of my desktops would be a panel of some sort, a transparent aterm, a pager and a bit of decor for the windows. Itā€™s getting late, but I might have a crack at some of them tomorrow.

[color=red]Edited by theBlackDragon:
ā€“> made sticky as this is a very good starterā€™s guide, which doesnā€™t mean that more experienced users canā€™t learn anything from this, in contrary.[/color]

When developing a config from scratch, the best thing is to use it as you develop it. That way the problems that you solve first are the ones that irritate you most, and the ones that you never get around to arenā€™t really that important. Keep my config file as a symlink. That way you can change the symlink to point at a different set, and reload FVWM to hot swap back to something more functional if thereā€™s something you canā€™t do yet in the new setup. The chances are you wonā€™t have to do that much.

So far, all we have is wallpaper. I can start xterms, and from them I can start my transparent aterms, so thatā€™s not a priority. A more immediate concern is that I have keep clicking titlebars to raise windows. I like auto raise, which means FvwmAuto. Start a console (ā€œIssue FVWM Commandsā€ from the menu) and type

Module FvwmAuto 200

If you like the result, stick it in the config file:

#
# set autoraise
#
AddToFunc StartFunction
+ I Module FvwmAuto 200

That done, I feel ready to handle the next big job which is some sort of launcher for my apps. I find menus a little bit fiddly, so for now letā€™s look at creating a panel with FvwmButtons.

FvwmButtons configurations can be complicated, but the minimal config is surprisingy simple. First you want to destroy any previous config. Weā€™ll use the alias FvwmButtons-Panel for this config, to reduce the chances of conflicting with other FvwmButtons object you may use: DestroyModuleConfig FvwmButtons-Panel: *
Then, since weā€™re creating a panel, we want a series of icons all of which lauch apps if you click on them. For each icon on the paneol, the format is

*FvwmButtons-Panel: (1x1 Icon '/path/to/icon',                   \
        Action(Mouse 1) 'Exec exec /path/to/application args'   \
)        

[color=blue]
Edit: ThomasAdam (20050205)
Added commas after mouse action definitons in FvwmButtons. This is what you should be doing from now on.
[/color]

We can simplify this a bit by setting ImagePath to tell FVWM where to find the icons. The + expands out to the previous value of ImagePath so we donā€™t accidentally clobber the system icon locations.

SetEnv datadir $[HOME]/.fvwm.data
ImagePath $[datadir]/icons:+

Additionally, the $PATH from your environment will be searched for the command, so you can get away with something like:

*FvwmButtons-Panel: (1x1 Icon 'l33t_BRO_firefox.png'    \
        Action(Mouse 1) 'exec exec firefox'             \
)

Which should give us a one-button panel with a launcher for firefox. Test it by pasting into the FVWM console. If it works, add it into the config, and add the module command to the start function. Then choose restart from them menu and make sure it works.

AddToFunc StartFunction
+ I Module FvwmButtons FvwmButtons-Panel

Now then: Iā€™m getting fed up of having to launch my terms from the command line all the time. So itā€™s time for a terminal launcher. My aterm invocation gets a bit complicated, so letā€™s bundle it all up in a FVWM function:

DestroyFunc InvokeAterm
AddToFunc InvokeAterm
+ I Exec exec aterm -tr -fg cyan -fn 10x20 -trsb -sl 1000 -ls -sh 45

And then we can write

*FvwmButtons-Panel: (1x1 Icon 'l33t_TER_term.png'       \
        Action(Mouse 1) 'Function InvokeAterm'                   \
)

Is it time for a screenshot yet? The wallpaper is is Purple Mila by drunken houscat taken from deviantart.com - with a bit of extra black added to fit my screen and a little rescaling. The icons are from the official gentoo icon set, plus a few home grown adaptations.

Looking at the result, the title and border on the panel is a bit irritating. Using the desktop, Iā€™m quickly reminded that it only appears on one desktop, and that it can get covered over by other windows. Letā€™s fix that:

style "FvwmButtons-Panel"       \
        NoTitle,                \
        BorderWidth 0,          \
        handlewidth 0,          \
        sticky,                 \
        StaysOnTop               

One more thing I want to do before I move on is a logout button. And, since Iā€™m also going to be restarting FVWM a lot while I get this config right, letā€™s make it so a left mouse click quits, but a right mouse click resarts the WM.

*FvwmButtons-Panel: (1x1 Icon 'l33t-logout.png'         \
        Action(Mouse 1) 'quit',                         \
        Action(Mouse 3) 'restart'                               \
)

That works well enough, except that we have the icons forming a square
. We can fix this by specifiying either rows or columns equal to one. I have a lot more width than height,
so Iā€™m going to specify columns.

*FvwmButtons-Panel: Columns 1    

All of which leaves us with something like this: screenshot.

Still to be done: window decorations, menus and colorsets.
[edit - fixed a typo]

Continuing with my config-from-scratch posts I was meaning to get onto window decors next. However there are a few things annoying me about the current setup. So Iā€™m going to follow the principle of fix-what-annoys-you, and scratch my itches first.

Take the auto-raise module. The number that you feed it is the number of miliseconds delay before the winindow under the cursor gets raised. 200ms is a fifth of a second, and way too frisky for me and my mouse pad, and I keep losing little windows under bigger ones. You can send a window to the back of the stack by double-clicking on the title bar (default behaviour, it seems) but itā€™s still a pain. I tried setting it to 750 which at 3/4 of a second was a little sluggish, and compromised at 500 in the end.

Next is that quit button. The right click to restart feature is proving useful, but Iā€™ve twice now accidentally left-clicked on the button (with a synaptics mousepad - itā€™s going to happen :frowning:). So I need some sort of ā€œare you sureā€ box. For the time being Iā€™ll use the FvwmForm-QuitVerify dialog that comes as standard. Weā€™ll see about sorting something out with a bit more zing later.

*Klix: (1x1 Icon 'l33t-logout.png' \ Action(Mouse 1) 'Module FvwmForm FvwmForm-QuitVerify', \ Action(Mouse 3) 'restart' \ )
The other thing thatā€™s been driving me nuts is navigation. The default desk uses a 3x3 page grid and Iā€™ve been traversing this by just running of the edges of the desktop. thatā€™s OK for a while, but Iā€™ve been missing my pager. Most of my desktops use 4 2x2 desks. So just for a change, I fancy a 3x3 single desk setup, wit the pager swallowed into the panel.

*FvwmButtons-Panel: (Swallow "FvwmPager" "FvwmPager 0 0")

That by itself gives us a pretty ugly looking pager. Letā€™s add some pager configs:

#
# Pager
#
*FvwmPager: Font "none"
*FvwmPager: Back "none"

I had been going to match the FvwmButtons background color, but somewhere along the line I mistyped and turned the color off completely. The result is a rather pleasing abstract of grey rectangles on a black background, which goes nicely with the solid back background. So I think Iā€™ll leave that and see how I get on with it.

Along the way I got annoyed with all the windows piling up in the top left hand corner of the screen and added

#
# global styles here
#
Style "*" MinOverlapPlacement

And I also got tired of having to pick the FVWM console off the menu, and in any event, I like my buttons to have multiple actions. So I set up the terminal button to generate a console on a right click. To lauch the console I wrote another quick func:

DestroyFunc InvokeConsole
AddToFunc InvokeConsole
+ I Module FvwmConsole -terminal aterm -tr +sb -fg red -sh 40 -geometry 180x12+0-1

So thatā€™s a console using a transparent red aterm. I got the geometry settings by dragging and resizing the window to my liking and then using FvwmIdent to get the settings. Of course, I had to invoke FvwmIdent from the console window itself, but thatā€™s not yet irritating enough to be fixed.

What is irritating, speaking of resizing windows, is those great thick borders. Something else for our global style section:

Style "*" BorderWidth 2, HandleWidth 2  # default window borders

And while Iā€™m at it, the other thing Iā€™m really missing is a close button. As it turns out, FVWM gives you some preset buttons by default. Itā€™s just that you canā€™t see them because thereā€™s no action bound to the button.

Type this into a console window:

Mouse 1 1 N Close
Mouse 1 2 N Close
Mouse 1 3 N Close
Mouse 1 4 N Close
Mouse 1 5 N Close
Mouse 1 6 N Close
Mouse 1 7 N Close
Mouse 1 8 N Close
Mouse 1 9 N Close
Mouse 1 10 N Close

Suddenly, you have loads of buttons! Admittedly, a lot of them look the same, and theyā€™re not particularly exciting, they will do for now. Letā€™s try just

Mouse 1 1 N Close        
Mouse 1 4 N Iconify
Mouse 1 2 N Maximize

This is starting to look like something I might be happy using, and the code clocks in at just 85 lines so far.

Of course thereā€™s a bit more work to do yet.

Last time we set up some titlebar icons, including one to iconify a window. Unfortunately, there is no obvious way to de-iconify them. In fact, since the first few icons are created behind the panel, we canā€™t even see them! The solution here is some sort of a task bar. I like to use FvwmIconMan for this. Try this in the console:

Module FvwmIconMan FvwmIconMan-TaskBar

None too promising that. Not only does it build the list downwards rather than across, but clicking on an entry does an inconify/deiconify by default. Maybe I spend to much time on Microsoft kit, but the behaviour I expect is to deiconify the window if necessary, bring it to the front and give it the input focus. Thereā€™s a builtin fuction that does that called EWMHActivateWindowFunc. Weā€™ll bind that to the left mouse click. This line tells FVWM that the Action to take if Mouse button 1 is clicked on the icon is to send the command FuncFvwmDeiconifyFocusAndRaise to the corresponding window.

*FvwmIconMan-TaskBar: Action Mouse 1 N sendcommand EWMHActivateWindowFunc

We can test that by clicking on the list entries. the trouble with that is that it only lists windows on the current desktop. Iā€™ve got a firefox window running on the page below this current one, and Iā€™d expect that to show up in the list. The solution is the Resolution option, which allow you to restrict the list to the current page, screen, desk, or to make it global. Since we only have one desk, Iā€™ll say desk.

*FvwmIconMan-TaskBar: Resolution Desk

Now we can see windows from apps on other pages, and clicking on them does indeed take us there, de-iconifying them if need be. It also reminds me that weā€™ll need to make it sticky at some point. We can still toggle a windows iconfication status with a right mouse click which is also nice.

The next thing I want to do is make the list run across rather than down. The ManagerGeometry option is a little arcane, but set it to 1x1 and the list will grow across and not down:

*FvwmIconMan-TaskBar: ManagerGeometry 1x1

That gives us the desired orientation, but itā€™s too small. Thereā€™s also a ButtonGeometry option which, somewhat counter-intuitively, allows us to specify the geometry of the IconMan window overall. After a bit of messing around, dragging, resizing and calling FvwmIdent, I settled on the following:

FvwmIconMan-TaskBar: ButtonGeometry 1190x10+--0

And having got that, itā€™s time to get rid of the title bar and make it sticky. In fact, while weā€™re at it:

Style   FvwmIconMan-TaskBar     NoTitle,        \
                                BorderWidth 0,  \
                                HandleWidth 0,  \
                                WindowListSkip, \
                                StaysOnTop,     \
                                Sticky           
Style   FvwmButtons-Panel       WindowListSkip

The only unfamiliar option there should be the WinListSkip one - which stops WinLists and IconMans from registering the IconMan itself. we donā€™t really want the panel showing registering, either.

The functionality of the taskbar is more or less there, but the cosmetics are bothering me. I donā€™t like that indented look to the entries, and the application names are taking up too much space. I also donā€™t like the default sort-by-name option since nothing is ever where I expect it to be

*FvwmIconMan-TaskBar: Format "%t"       # just the window title
*FvwmIconMan-TaskBar: PlainButton up    # bye bye indentations
*FvwmIconMan-TaskBar: Sort none         # no sorting, please

Thatā€™s looking much better. However the colors are starting to bother me. The Panel is a different shade of grey from the icon manager, which is different to the window title barsā€¦ I found myself wondering why FVWM didnā€™t have some mechanism for co-ordinating all itā€™s bits and modulesā€¦ and then I realised that it did. Itā€™s time to define some colorsets.

There are four basic colours to a colorset. In general, forground is the colour that any text will be written in, background is what you would expect, and highlight and shade are used to draw the bevel around 3D effect buttons. I like the away the panel is being rendered, so Iā€™ll standardise on that. I can get the hex triples for the colours in question using the Gimpā€™s
color picker on one of the screenshots:

Colorset 0      Foreground      black,          \
                Background      rgb:90/80/90,   \
                Hilight         rgb:c5/b9/c5,   \
                Shade           rgb:46/41/46

Weā€™ll need a second colorset for focus things. We could change the background colour, (which is the default) or the foreground color - which would change the color of the text in the windows. Or we could do both.

Colorset 1      Foreground      purple,   \
                Background      black,          \
                Hilight         rgb:c5/c5/b9,   \
                Shade           rgb:46/46/41

Now we need to add some lines to the apply these colorsets. To apply them to windows we use the style command:

Style "*" Colorset 0
Style "*" HilightColorset 1

For FvwmButtons, the command is:

*FvwmButtons-Panel: Colorset 0
*FvwmButtons-Panel: ActiveColorset 1

The second colorset in this case has the result of highlighting the button under the mouse pointer at any given time. I havenā€™t yet decided if I think this is cool, or really really annoying. Oh well, I can always turn it off again :slight_smile:

For the TaskBar, do this:

*FvwmIconMan-TaskBar: Colorset 0
*FvwmIconMan-TaskBar: FocusColorset 1

And weā€™re just about there.

One more thing I have in mind. Two things always strike when me building a desktop like this - how responsive FVWM is before I add a million applets and translucnet menus and all that, and just how much sheer space there is before all the clutter gets added. Itā€™d be nice to retain some of that space this time.

So I thought Iā€™d maybe put the titlebar back on the pager.

style "FvwmButtons-Pager"       Title

and then turn the buttons off.

style "FvwmButtons-Pager"       NoButton 1,             \
        NoButton 2,             \
        NoButton 4

Now you can shade the panel by double clicking it - effectively withdrawing it into the task bar. Iā€™ll change the panel alias to ā€œClikClikā€ because it suggest what you have to do to withdraw it. This isnā€™t quite so cute as auto-hiding, but then auto-hiding is more (IMHO) trouble than itā€™s worth for edge scrolling desk layouts.

Two final things. First of all I keep missing the taskbar because I hit the edge
of the screen and the page hits. This will slow it down a little

EdgeResistance 300 5

The second thing is to set the base EWMH struts so windows donā€™t obscure the taskbar. The command takes four arguments, each representing a pixel offset from the left, right, top and bottom of the screen that should be reserved. We want the top 18 pixels of the screen only. Thus:

EWMHBaseStruts 0 0 18 0

This doesnā€™t stop windows placing under the dock, but we can shade that to get it out of the way, so thatā€™s all right.

This, it turns out doesnā€™t play nicely with the MinOverlapPlacement style defined earlier so we need to turn that off. We only need to do it for the taskbar though

style FvwmIconMan-TaskBar TileCascadePlacement

Our config currently stands at 182 lines, and looks like this. Next time, I think itā€™s about time I looked at defining some menus, and possibly some cool panel/pager tricks as well.

Before I start on menus, Iā€™ve a couple of pager-related itches that need scratching. The big probem is that the window with the focus gets highlighted in black. Not terribly useful against a black background. Just as bad: it hightlights the current page in the same colour as it uses for passive windows. So now that weā€™ve got some colorsets defined, this would be a good time to address the issue.

The trouble is that there are five colorset options for the pager, and its not always clear what aspect of the colorset affects what element in each case. So I tried an experiment: Add into your config file a line like this:

Colorset 10 fg red, bg blue, hi gold, sh green

Then apply the colorset to one of the FvwmPager options. Choose one from this lot:

*FvwmPager: Colorset desk colorset
*FvwmPager: BalloonColorset desk colorset
*FvwmPager: HilightColorset desk colorset 
*FvwmPager: WindowColorsets colorset activecolorset 

Now reload the FVWM session to see what gets coloured how. Which sounds fine in priciple. In practice I had everything figured out and working one night, then I went to bed and the next morning I hadnā€™t saved the config, nor could I reproduce it. After some work, I managed to get the active window hightlighted in purple, certainly. The problem is that the inactive ones are now blackā€¦ Oh well, Iā€™ll get back to that one later. Here are a few other tweaks that worked rather better

First of all letā€™s have some names for the colorsets

SetEnv  PagerCSet               10
SetEnv  PagerBalloonCSet        11
SetEnv  PagerHiliteCSet         12
SetEnv  PagerWindowCSet         13

Then some colorsets using those values. The last two seem to have no effect whatsoever, although I expected the WindowColorset option to give me the colored windows I anticipated. The pixmap setting in the first colorset uses an image for the background. in this case Iā€™ve gimped up a clipped scaled version of the wallpaper (save FVWM time and memory if we do it in advance).

Colorset $[cset_pager]          fg purple,              \
                                pixmap mila84x84.png,   \
                                hi red,                 \
                                sh gold
Colorset $[cset_pager_b]        fg purple,              \
                                bg black,               \
                                hi rgb:c5/b9/c5,        \
                                sh rgb:46/41/46
Colorset $[cset_pager_h]        fg red, bg blue, hi gold, sh green
Colorset $[cset_pager_w]        fg red, bg blue, hi gold, sh green

I also tried reversing the hightlight and focus colorset to make purple-on-black the dominant colorscheme, since it fits with the wallpaper. I had to drop the intensity of the purple a bit, since it got a bit overwhelming on big title bars.

Colorset $[cset_norm]   Foreground      purple3,                \
                        Background      black,          \
                        Hilight         rgb:c5/b9/c5,   \
                        Shade           rgb:46/41/46
Colorset $[cset_focus]  Foreground      black,          \
                        Background      purple3,        \
                        Hilight         rgb:c5/c5/b9,   \
                        Shade           rgb:46/46/41

It may be a bit too StarTrek:TNG for some peopleā€™s tastes. If so, you know how to change it ;)

Lastly, Iā€™ve added a couple of options to the pager config. The comments should be self explanatory

Echo ### Pager Begin
DestroyModuleConfig FvwmPager: *

*FvwmPager: Colorset * $[PagerCSet]                     # background
*FvwmPager: BalloonColorset * $[PagerBalloonCSet]       # tool tips
*FvwmPager: HilightColorset * $2[PagerHiliteCSet]       # no effect?
*FvwmPager: HilightColorset * $2[PagerWindowCSet]       # no effect?

*FvwmPager: Font "none"         # no in-window labels
*FvwmPager: SloppyFocus         # focus window under mouse pointer
*FvwmPager: Balloons Pager      # tool-tip popups with the window title
*FvwmPager: NoSeparators        # turn off the lines separating desks
*FvwmPager: NoDeskHilight       # stop the current desk being blotted out

Echo ### Pager End

This is the net result of all that tweaking.

On to menus! Iā€™ve put off doing menus so far, because when you start a bare metal FVWM session the menu is the only way you have of starting a terminal or quitting the session. Mess that up and youā€™re in trouble. However, now that the panel is more or less stable, itā€™s time I bit the bullet.

Letā€™s start by getting the menu colors in sync with the rest of the desktop.

Colorset $[cset_menu]   Foreground      purple,         \
                        Background      black,          \
                        Hilight         rgb:c5/c5/b9,   \
                        Shade           rgb:46/46/41
MenuStyle * MenuColorset $[cset_menu]

Yep, I defined a new colorset for the menus, for no better reason that the toned-down purple shade looked a little bland. All this one does is restore the full intensity purple shade.

Itā€™s still a little uninspiring though. What we need is a good font. Get a list of fonts by starting a bash shell and typing

fc-list | less

Then paste a couple of funcs into your FvwmConsole

DestroyFunc fontz
AddToFunc fontz
+ I Style * Font 'xft:$0'
+ I MenuStyle * Font 'xft:$0'

DestroyFunc fontzN
AddToFunc fontzN
+ I Style * Font 'xft:$0:size=$1'
+ I MenuStyle * Font 'xft:$0:size=$1'  

Now you can try out fonts quickly and easily from the FvwmConsole Window, by passing lines from the fc-list output to these functions.

fontz "SF New Republic:style=Italic"            # set menu and titles - default size
fontzN "SF New Republic:style=Italic" 20        # same but in 20 point type

I picked a font called ā€œOberonā€. Itā€™s clearly readable at 12 points, Handles both cases and numbers, and it fits with the emerging style of the desktop.

To add the style into the config we need something like this:

Style "*" Font "xft:Oberon:style=Regular:size=12"           # titles
MenuStyle "*" Font "xft:Oberon:style=Regular:size=12"   # menus
#
# and in the IconMan definitions
# 
*FvwmIconMan-TaskBar: Font 'xft:Oberon:style=Regular'

Letā€™s have a quick screenshot.

The menu you get by clicking on the root window is called MenuFvwmRoot. To change it, destroy the old config and then add new entries, like so:

DestroyMenu MenuFvwmRoot
AddToMenu MenuFvwmRoot 'welcome to $[HOSTNAME]' Title
+ 'Shell'       InvokeAterm
+ 'Web'         Exec exec firefox
+ 'Tools'       Popup ToolsMenu
+ 'FVWM'        Popup FvwmMenu
+ 'Quit'        Popup QuitMenu

You can bind keyboard shortcuts by sticking an & in front of the letter you want to use.

DestroyMenu MenuFvwmRoot
AddToMenu MenuFvwmRoot 'welcome to $[HOSTNAME]' Title
+ '&Shell'      InvokeAterm
+ '&Web'        Exec exec firefox
+ '&Tools'      Popup ToolsMenu
+ '&FVWM'       Popup FvwmMenu
+ '&Quit'       Popup QuitMenu

Submenus as defined in the same way. Applications are a very individual thing, so add the stuff you use here.

DestroyMenu ToolsMenu
AddToMenu ToolsMenu 'Tool Box' Title
+ 'The &Gimp'   Exec exec gimp-2.0
+ 'XMMS'        Exec exec xmms
+ 'OOo'         Exec exec ooffice
+ '' Nop
+ '&Doom III' InvokeDoom3
+ '&Fallout 2' Exec exec fallout2
+ '&Alpha Centauri' Exec exec smacpack
+ '&Deus Ex' Exec exec xdeus

The ā€œNopā€ line apprears as a separator in the menu. Useful for separating the important stuff from minor distractions like The Gimp and OpenOffice.org ;)
If you want to add mini-icons (or grat big ones for that matter) add them to the menu text bracketted by percent signs. This is where the syntax starts to get weird and intimidating.

DestroyMenu MenuFvwmRoot
AddToMenu MenuFvwmRoot 'welcome to $[HOSTNAME]' Title
+ '&Shell%mini-purple-term.png%'     InvokeAterm                          
+ '&Web%mini-web.png%'                 Exec exec firefox
+ '&Tools%mini-tools-purple.png%'     Popup ToolsMenu   
+ '&FVWM%mini-fvwm-purple.png%'   Popup FvwmMenu   
+ '&Quit%mini-quit-purple.png%'        Popup QuitMenu

And hereā€™s the result. The most time consuming part was making the icons in the gimp. So Iā€™ll stop doing that or Iā€™ll never get finished :)

Some FVMW window commands can be usefully accessed from the menu.

DestroyMenu FvwmMenu
AddToMenu FvwmMenu 'FVWM' Title
+ '&Identify' Module FvwmIdent
+ '&Move' Move
+ '&Resize' Resize
+ 'R&aise' Raise
+ '&Lower' Lower
+ '(De)&Iconify' Iconify
+ '(Un)&Stick' Stick
+ '&Maximize' Maximize
+ '' Nop     
+ '&Close' Close
+ '&Delete' Delete
+ '&Destroy' Destroy

This also makes a useful menu to attach to a window toolbar or icon. This invokes the menu when you middle-click on a title bar.

Mouse 2 T N Menu FvwmMenu

The quit menu wants a quit and restat option. You can also restart using other WMs should you so deisre. Every now and again I find it useful to restart a session in afterstep or WindowMaker.

DestroyMenu QuitMenu
AddToMenu QuitMenu 'Quit Or Restart?' Title
+ '&Restart' Restart
+ 'Restart in &Afterstep' Restart afterstep
+ 'Restart in &WindowMaker' Restart wmaker
+ '' Nop
+ '&Quit' Quit

Lastly, just for the hell of it, try setting the menu colorset to the one used by the pager.

MenuStyle * MenuColorset $[cset_pager]

Itā€™s pretty cool, but I donā€™t think I want millaā€™s face everywhere I look, pretty as she is. Notice the red and gold hightlight colors finally showed up :slight_smile:

Thatā€™s it for this session. Our config stands at 275 lines and looks like this. More to come.

[edit]

Sussed out the colour problem from the man page;

So the inactive windows are appearing as black squares because their titlebars are black. There are some annoying hard-codes in the pager module.

Letā€™s start with some itches in need scratching:
Icons: Iā€™ve not added any key or mouse bindings to icons yet. Clicking on them does nothing, and with the taskbar to restore an iconified window, the icon itself is just a waste of space.

Style * NoIcon

solves the problem.

XMMS appears with a titlebar and looks weird. Unintentionally so.

Style "xmms" NoTitle

Donā€™t use caps (ā€œXMMSā€) or it wonā€™t work. You canā€™t match on the window title, because XMMS will change that with each track it plays. You can match on the resource id though, but thatā€™s in lower case. QED.

Transient windows donā€™t have a titlebar. If things go wrong, thatā€™s often the only way to close them.

Style * "DecorateTransient"

Onto the busines of the day. The last post left us with a config thatā€™s pretty much usable, even if it needs a fewmore apps added to the toolbox. So today, I think I might play with a few less essential things.

Like for example making the panel titlebar control XMMS. The plan is to have two buttons. One of them is going to play/pause/stop depending on the mouse button used. The other will FF or REW the track with the middle mouse button unhiding the XMMS window so you can set playlists and the like. Iā€™ll also look at desiging some vector buttons to reflect the changed functionality.

First thing to do is emerge xmmsctrl. Then remove NoButton 1 and NoButton 2 from the Panel style settings. You can either reload FVWM or set the Button 1 and Button 2 styles in the console to see the changes. Note that Iā€™ve changed the name of the panel again to ā€œKlixā€ since ā€œKlikKlikā€ isnā€™t going to fit.

Style "Klix" Button 1, Button 2

Next weā€™ll define a function to handle most of the XMMS operations weā€™ll need.

DestroyFunc XMMS
AddToFunc XMMS
+ I exec exec xmmsctrl launch
+ I exec xmmsctrl main 0
+ I exec exec xmmsctrl $0 $1

Weā€™re going to lauch the player each time because it has no effect if an instance is already running, and if xmms crashes for any reason, pressing play will restart it. The second line will hides the main xmms window if it appears, and the third one sends the function parameters to XMMS. Weā€™ve allowed two params ($0 and $1) so we can set flags as well as issue commands.

In a window decor button number one is the leftmost button. Thatā€™s the one thatā€™s going to handle PLAY (mouse 1), PAUSE (mouse 3) or QUIT (mouse 2). The quit operation is in there because some of my games wonā€™t run right if XMMS grabs the soundcard.

Mouse (Klix) 1 1 N XMMS play    # mouse 1, window button 1
Mouse (Klix) 2 1 N XMMS quit    # mouse 2, window button 1
Mouse (Klix) 3 1 N XMMS pause   # mouse 3, window button 1

Window button 2 is the rightmost one. That is going select the NEXT track on button 1, the PREVIOUS track on button 3 or toggle the main XMMS window on button 2.

Mouse (Klix) 1 2 N XMMS next
Mouse (Klix) 2 2 N exec exec xmms_toggle
Mouse (Klix) 3 2 N XMMS previous

The xmms_toggle script is a little shell script I wrote rather than try to couldnā€™t figure out how to quote the if-then-else construct to work all on one line. It looks like this:

#! /bin/bash 

if xmmsctrl is_main
then
        xmmsctrl main 0
else
        xmmsctrl main 1
fi

Bascially, it checks to see if the xmms main window is displayed. If it is, the script hides it. If not, the window is unhidden.

And just so we donā€™t need to hunt throught 9 pages to find the unhidden window:

style "xmms" NoTitle, Sticky, StaysOnTop

OK. Our titlebar works, but the buttons are saying ā€œcloseā€ and ā€œmaximiseā€. Actually the ā€œcloseā€ button says ā€œmenuā€ to me, but Iā€™ll get to that later. For now, we want to change those buttons for the panel only. That means defining a new decor.

Like everything else in FVWM, decors are additive. This means we start by destroying the old one.

DestroyDecor PanelDecor

Now we can add button definitions - this is the scary looking part.

AddToDecor PanelDecor
+ ButtonStyle 1 9       25x25@4 25x75@1 75x75@0 75x25@0 25x25@1  \
                        35x25@4 35x75@1 65x50@0 35x25@1
+ ButtonStyle 2 12      10x50@1 35x25@1 35x40@1 65x40@1 65x25@1
                        90x50@1 65x75@0 65x60@0 35x60@0 35x75@0 10x50@0 10x50@1

The first argument to ButtonStyle is the titlebar button number. The next one tells it how many lines to expect in the definition to follow. All the arguments after that represent lines to draw on the icon. If you paste that into a console window, you may find you need to type ā€œrecaptureā€ before the changes show up.

For button one, I want something to remind me that the button does ā€œplay/pauseā€. Iā€™m going for a mixture of the standard tape deck play and pause buttons: a square with a triangle on top of it. What we need to do is work out where the points at each end of the lines are going to be. We specify these on an imaginary grid of 100x100 points.

The top left hand corner of the square Iā€™m going to place at 25 across and 25 down. We write that as ā€œ25x25@4ā€, where the ā€œ@4ā€ bit the color to use when drawing the line. Usually, for each point like this, FVWM will draw a line from the previous point to this one. In this case there is no previous point, so I donā€™t think FVWM will draw anything, but just to be sure, Iā€™ve chosen colour 4 which means ā€œdonā€™t traw anything - just moveā€.

The Next point we choose is 25,75@1. This draws a line from the last point (35,35) to the new one (25,25). We choose colour 1 for this, because thatā€™s specifies the hilight colour. This is going to be the left side of the square, and that should look as if light was falling up it if its going to match the other icons.

The Next three points complete the square, finishing back where we started out: 75x75@0 75x25@0 25x25@1. The @0 lines are being drawn in the shade color to make them look like theyā€™re in shadow and preserve the illusion three-dimensonality for the icons.

After that we use another move-only point to move the cursor inside the square, and from there we draw the triangle in the same way.

See? That wasnā€™t so bad after all :slight_smile:

For the second icon I used a double headed arrow. There was a nice one on the FVWM vectorbuttons page, so I pinched that. That was even easier :smiley:

The last thing to do use make the ā€œKlixā€ window use the new decor:

Style "Klix" UseDecor PanelDecor

Et, voila! Ok, the triangle is a little pixelated, but no more so than the ā€œproā€ version. I think I can live with that. Iā€™ve also got a slight problem with the player stated up un-hidden. Anyone know a reliable way to make XMMS start off hidden? Iā€™d like to know about ut.

One thing Iā€™ve been putting off until we talked about decors: Iā€™m not mad keen on the default buttons either. The close button is on the wrong side of the bar ffor me, and the icon itself makes me thing Iā€™m using Windows 3.1.1. I keep clicking it expecting a menu. It can be a nasty surprise when the window vanishes.

So, I think Iā€™ll have close icon on the right where I expect it, and on the left, I fancy a combined min/max button. I also think Iā€™ll make the close icon only operate on a double click (never thought Iā€™d feel nostalgic for Win 3.1.1!) with probably a menu there for a single click to stop me forgetting and thinking the config is broken.

Letā€™s define another decor:

DestroyDecor DefaultDecor
AddToDecor DefaultDecor
+ ButtonStyle 1 16      60x40@1 60x80@0 15x80@0 15x40@1 60x40@1 \
                        40x40@1 40x25@1 75x25@1 75x60@0 60x60@0 \
                        75x60@0 75x40@0 85x40@0 85x15@0 60x15@1 \
                        60x25@1
+ ButtonStyle 2 8       35x15@1 20x50@1 40x50@0 30x80@1 75x40@0 \
                        50x40@1 75x15@0 35x15@1

I snaged both of these from the FVWM page. Why re-invient the wheel? Thatā€™s assuming the current defacto industry standard isnā€™t triangular or something, obviously :wink:

Mouse 1 1 N Iconify                     # iconify on mouse 1
Mouse 3 1 N Maximize                    # max it on mouse 3
Mouse 1 2 N CloseOrMenu                 # Call a function on mouse 1

The reson for the function call is that the ā€œDā€ modifier doesnā€™t work for mouse actions in this context. But it does in functions so we pass the click to the function, and then the function decides what sort of click it was passed:

DestroyFunc CloseOrMenu
AddToFunc CloseOrMenu
+ C Menu FvwmMenu               # if single click, display menu
+ D Close                       # close on double click

Anyone why ever accidentally clicked on a window and lost several hours work knows where Iā€™m coming from with this one.

Style "*" UseDecor DefaultDecor

Make sure you add the system wide stuff before you do the app specific code. Otherwise the above UseDecor will blot out the custom one and youā€™ll wonder where your XMMS controls went. If you do this from the console line you may need to add NoButton 4 to the style command to shift the now superfluous button.

The config file stands at 334 lines and looks like this. Next installment, some more oddball pager tricks.

(( kudos to downpour here for explaining how FvwmScript works, and helping me solve a problem thatā€™d been bugging me no end. This was posted to a different thread on the gentoo forums. The format is a little different, but I canā€™t be bothered to fix it at the moā€™ā€¦ ))

The Objective: I want to have a ā€œsmartā€ button on my panel that can be cycled through a list of less commonly used apps with a right click. A left mouse click would launch the application as usual.

Design Considerations: I donā€™t want any daemonized scripts lurking around to drive this. Context should be purely a FVWM problem.

List Management: Given the above, I want a stateless script to give me back command strings or file names given a state number. This can be written in anything, but I choose Perl, simply because itā€™s so easy to factor out the data from the code. I called this ā€œfvwm_nextā€

#! /usr/bin/perl -w
use strict;

#
# Change this list to customise your app sequence:
# Format is:
#       command         icon-name
#       command         icon-name
#
# with no quotes or commas. Icons should be full path specified or 
# should be in FVWM's ImagePath. 'kay?
#
my @raw_apps = qw(
        gaim            l33t_IMS_gaim2.xpm 
        ooffice         l33t_OFF_openoffice.xpm 
        gimp-2.0        l33t_GRA_gimp.xpm
        rox             l33t_UNK_rox.xpm
        dia             l33t_UNK_dia.png 
);

#
# Shouldn't need to change beyond this point
#
use constant COMMAND    => 0;
use constant ICON       => 1;

#
# init func - turns the @raw_app array into an array of couplets
#
sub init
{
        my @temp = ();
        while(@raw_apps) {
                my $command     = shift @raw_apps;
                my $icon        = shift @raw_apps;

                push @temp, [ $command, $icon ];
        }
        @temp;
}

#
# Once a C coder, always a C coder...
#
# Takes an index into the @apps array and a command - "icon" and "command"
# are supported.
#
# Returns the icon or command for the index-th entry in the list, modulus
# the list size so you can run over safely
#
sub main
{
        my $index = shift;
        my $op = shift;
#
#       easy on the debug prints, since they're liable to be mistaken for data
#
        unless(defined $op) {
                print STDERR "index = $index\n";
                print STDERR "op = $op\n";
                die "usage: $0 index operation";
        }
#
#       get a paired list of command-icon entries
#
        my @apps = init();
#
#       truncate the index if need be
#
        $index %= @apps;
#
#       switch on the operation string
#
        switch: {
                local $_ = $op;
                /icon/ and do { printf "%s\n", $apps[$index][ICON]; exit; };
                /command/ and do{ printf "%s\n", $apps[$index][COMMAND]; exit;};
#
#               should show a skull icon (or similar) and if clicked,
#               display a configuration error message.
#
#               later maybe
#
                die "unknown operation: $_\n";
        };
}
 
main @ARGV;

FvwmScript: I want a script with a single widget, sized to fit in my panel. it needs to launch an app on a left click and bump the icon on a right click. And here we hit a problem, because FvwmScripts doesnā€™t allow you to catch right-click events. On the other hand, it does allow arbitary message strings to be sent from elsewhere in FVWM. So we can have FvwmButtons handle it.

FvwmButtons: To handle the right click problem we define a button like this:

*Klix: (Swallow "FvwmScript-MuitiButton" 'FvwmScript FvwmScript-MuitiButton 2' \
        Action(Mouse 3) 'SendToModule FvwmScript-MuitiButton SendString 1 1 bump'       \
)

That lets the left click pass on through to be handled normally, while the right click gets caught and passed on as ā€œbumpā€ message.

FvwmScript, Revisited: That sorted out, we can write the FvwmScript now. This is FvwmScript-MultiButton

WindowTitle {FvwmScript-MuitiButton}
WindowSize 85 85 # Taille
Font "xft:Bitstream Vera Sans:size=9"

Init
Begin
#
#       state is the number of the current app
#

        Set $state="0"
        Set $MainColorset=(GetScriptArgument 1)
        If $MainColorset <> {} Then
        Begin
                ChangeColorset 0 $MainColorset
                ChangeColorset 1 $MainColorset
        End
        Set $cmd={exec next_fvwm }$state{ icon }
        Set $tmp = (GetOutput $cmd 1 -1)
        ChangeIcon 1 $tmp
End

#
# I left this in so the button would slowly cycle through the icons
# and generally look cool. Tastes may differ in this respect.
#
# Every five seconds the icon will cycle.
#
PeriodicTasks
Begin
        If (RemainderOfDiv (GetTime) 5)==0 Then
        Begin
                Set $cmd={expr 1 + }$state
                Set $state = (GetOutput $cmd 1 -1) 
                Set $cmd={exec next_fvwm }$state{ icon }
                Set $tmp = (GetOutput $cmd 1 -1)
                ChangeIcon 1 $tmp
        End
End

#
# This is the definition for our one and only widget
# it has actions to perform on getting a mouse click,
# or on receiving a bump message. Actaully any message
# is a bump message atm.
#
Widget 1
        Property
        Position 0 0
        Size 85 85
        Type PushButton
        #Icon $tmp
        Flags NoReliefString Left
        Title {}
Main
        Case message of
        SingleClic :
        Begin
                Set $cmd={exec next_fvwm }$state{ command }
                Set $tmp = (GetOutput $cmd 1 -1)
                Do{ Exec exec }$tmp
        End

        1 :
        Begin
                Set $cmd={expr 1 + }$state
                Set $state = (GetOutput $cmd 1 -1) 
                Set $cmd={exec next_fvwm }$state{ icon }
                Set $tmp = (GetOutput $cmd 1 -1)
                ChangeIcon 1 $tmp
        End
End

Put em all together and amaze your friends :wink:

This could also be used (as indeed I plan to use it) for a rotating system monitor button one that displays mail waiting, cpu load, etc. And that also does it intelligently skipping mail notifications if no mail is waiting, for instance.

Next post, more on fonts, shadows, transparency and an eye-candy replacement for that ugly QuitVerify form.
[edit - typo - probably an ongoing process in all these posts ]

The Oddball Panel Trick I mentioned wound up in as a post in dowmpourā€™s fvwm tips and tricks thread. This post talks about writing FvwmScript, illustrated by creating a replacememnt for FvwmForm-QuitVerify. If youā€™re fairly new to FVWM, youā€™re probably better off reading this one first, since I spend a bit more time explaining how FvwmScript works.

For any FvwmScript, the first section describes the properties of the window
weā€™re going to create. You can get away with something like this

WindowTitle {FvwmScript-NewQuitVerify}
WindowSize 400 200
Font "xft:Oberon:style=Regular" 
Colorset 2
WindowPosition 440 300
  • The first line sets the window title. The curly braces are string delimiters in FvwmScript.
  • WindowSize is straight forward. I picked 400 by 200 pixels as an initial estimate.
  • Font defines the font that will be used for text. I picked Oberon, in keeping with the design so far.
  • WindowPosition is in Pixels. Iā€™ve calculated this based on my screen size. There ought to be a way to calculate this on the fly. Meanwhile, Iā€™ll hardcode it.

Put the code above in a file called ā€œFvwmScript-NewQuitVerifyā€ in your .fvwm directory. The you can launch this from the console. Itā€™s not very exciting, mind.

Module FvwmScript FvwmScript-NewQuitVerify

As you can see, that gets us a plain black window. I wonā€™t bother with a screenshot.

So letā€™s add some widgets. I fancy a couple of warning triangles. I made some nice purple ones with the gimp. (Create a new 256x256 icon. Trace out an equilateral triangle using the path tool - use guides to keep 'em regular. Stroke the path; make a reasonable width and use rounded joins. Use the text tool to print an exclamation mark in the triangle. Shrink it to the desired size, clean it up,select all, paste as new and save. End of mini-howto ;))

Anyway, to get back on topic for a second, you add the icon to the window like this:

Widget 1
Property
        Size 50 50
        Position 20 20
        Type ItemDraw
        Icon purple-warning.png
End 

Widget 2
Property
        Size 50 50
        Position 330 20
        Type ItemDraw
        Icon purple-warning.png
End 

While weā€™re at it, letā€™s make it sticky and always on top. Weā€™ll turn off the title bar as well, eventually. For now we need it to close the window.

Add this to your config.

Style FvwmScript-NewQuitVerify Sticky, StaysOnTop

Itā€™d be a bit irritating to get logged out because you lost the logout box under a pile of aterms, after allā€¦:wink:

Run the script and you get a window, now improved with added triangles. Not bad, but some text might be useful.

Widget 3
Property
        Position 70 20
        Size 260 0
        Type ItemDraw
        Title {Termination Requested}
End 

That helps a bit. The position takesa bit of fiddling to get right. One thing that helps is knowing that text fields are centered by default. So if we have a 20 pixel border and a 50 pixel icon, then start the text field at 70 pixels. Similarly, if the box is 400 pixels wide then the space between the two icons is equal to

400 - (2 * (border_width + icon_width)

or

400 - (2 * (50 + 20) = 260

So, by starting the text field at 70 pixels across and making it 260 wide, we can rely upon FVWM to centre the text.

Iā€™ve left the text a bit high so thereā€™s room for a seconds-to-go coun down. before I get onto that though, letā€™s have some buttons

Widget 4
Property
        Size 50 30
        Position 20 160
        Type PushButton
        Title {No, Wait!}
Main
        Case message of
        SingleClic :
        Begin
                Quit
        End
End 

The Main section lets you detail event handlers for an item. In this case we want to catch left mouse clicks (you canā€™t do right or middle anyway) and the action we want to take is to Quit from the script. So thatā€™s pretty straightforward.

If weā€™d wanted to quit from FVWM, or otherwise send a command to the window manager, weā€™d do something like this:

Widget 5
Property
        Size 50 30
        Position 260 160
        Type PushButton
        Title {Just Do It!}
Main    
        Case message of
        SingleClic :
        Begin
                Do {Quit}
        End     
End             

Which is pretty much the same apart from the ā€œDo { fvwm-command }ā€ syntax that executes a FVWM command, rather than a FvwmScript command. So that Do {Quit} button will log you out if you click on it. Careful chaps, this window is loaded!

Next we need a counter. Iā€™m going provide a 20 second grace period. So first we need to initalise a variable. Put the following code after the header, but before the first widget:

Init
Begin
        Set $counter = 20
End

That sets a numeric variable to 20 at script startup time. Now let us deploy a widget to display the inexorable countdown process.

Widget 6
Property
        Position 70 45
        Size 260 0
        Type ItemDraw
        Title {Counting Down: 20}
End

Now we need the code to change the display. Happily FvwmScript assumes that youā€™ll be doing regular timed tasks like this. Add a "PeriodicTasks section after the end of the Init section:

PeriodicTasks
Begin
        Set $counter = (Add -1 $counter)
        Set $string = {Counting Down: }$counter
        ChangeTitle 6 $string
End

Try that now. I donā€™t know about you, but I find it processes a whole load of events, very fast, and whizzes down to about -35 and then settles down a second by second count. If that countdown was armed, Iā€™d be logged out before I knew what was happening. What I wound up doing was this:

Init
Begin
        Set $counter = 20
        Set $last = (GetTime)
End

PeriodicTasks
Begin
        Set $now = (GetTime)
        If $now > $last Then
        Begin
                Set $last = $now
                Set $counter = (Add -1 $counter)

                If $counter == 0 Then
                Begin   
                        Do {Quit}
                End     
                        
                Set $string = {Counting Down: }$counter
                ChangeTitle 6 $string
        End             
End                     

Essentially for each hit, weā€™re checking that at least one second has passed since the last one. The ChangeTitle command is what alters the text in the button. It takes a widget number and a string. So be careful if you add in new widgets.

I also did some googling for free sound effects and found a noise that gets my attention and hasnā€™t irritated me yet. Sounds in WM are a dubious proposition at best, but I feel theyā€™re warranted for a logout screen. This is something I want drawn to my attention. I added one when the box is displayed and the other before the two Do {Quit} commands.

I have to be a bit careful with the screenshots now, since this thing will log me out if I wait too long :wink: As you can see, weā€™re almost there. Just need to adjust the buttons and the lower edge of the box up a bit since I allowed a bit too much room. After some mucking about, I brought the buttons up by 80 pixels, and shrunk the box size accordingly.

Now one more thing to give it a bit more impact. Letā€™s draw a box around the lot. In fact letā€™s have two of them. I should turn off borders and handles as well, but you know how to do that.

Iā€™ve also been playing with fonts and gradients. The code is in the current config, but I think Iā€™m going to have to leave the details to another post. After that, I think weā€™re about done.

The config stands at 388 lines, and looks like this.

[edit - typos, always typos ]

Itā€™s been a couple of weeks since I last posted on this subject. In that time Iā€™ve tweaked a lot of stuff, and completely lost any chance of explaining what Iā€™m doing as Iā€™m doing it. So Iā€™m going to take a theme for this one and talk some more about colorsets.

Hereā€™s a new toy for you :slight_smile:

WindowTitle {FvwmScript-PreviewCset
WindowSize 400 400
Font "shadow=2:xft:Oberon:size=12"

Init
Begin
        Set $cset_no=(GetScriptArgument 1)
        ChangeColorset 1 $cset_no

        Set $cset_args=(GetScriptArgument 2)
        If $cset_args <> {} Then
        Begin
                Do {Colorset }$cset_no{ }$cset_args
                ChangeTitle 1 $cset_args
        End
        Else
        Begin
                Set $temp = {Colorset }$cset_no
                ChangeTitle 1 $temp
        End
End

Widget 1
Property
        Position 0 0
        Size 400 400
        Type PushButton
        Title {Visual Colorset Display}
Main
        Case message of 
        SingleClic :
        Begin
                Quit
        End
End 

Paste this into a file called FvwmScript-PreviewCset and stick it in your .fvwm directory. Itā€™s a visual colorset display tool. Call it like this

FvwmScript FvwmScript-PreviewCset 6

And youā€™ll get a big button that shows what colorset 6 looks like. (No screenshots in this one: Paste the FvwmScript lines into a console window and youā€™ll see what Iā€™m talking about far sooner).

Now then: you can use the script to define new colorsets as well: Pick a number that youā€™re not using; I chose 20.

FvwmScript FvwmScript-PreviewCset 20 "bg gold, fg red"

And colorset is set 20 to red-on-gold and the results displayed. Donā€™t forget he quotes.

One thing I learned playing with this is that colorset args are additive. Having once set an attribute of a colorset, it remains set unless explicitly changed throughout future colorset operations. Iā€™m not going to do screenshots for most of these.
So you can do

FvwmScript FvwmScript-PreviewCset 20 "bg blue"
FvwmScript FvwmScript-PreviewCset 20 "bg green"
FvwmScript FvwmScript-PreviewCset 20 "RootTransparent"
FvwmScript FvwmScript-PreviewCset 20 "Pixmap mila84x84.png"
FvwmScript FvwmScript-PreviewCset 20 "bg purple"

and the foreground will remain red. You might also notice that if you change colorset 20 for one window, you change it for them all.

I got started with this because I wanted to try a gradient on my titlebars. Normally I set my titles (and as much else as possible) RootTransparent, but I want to do things differently for this design, so gradients it is. The idea was to use a purple gradient shading into black from let to right so as to maximise the contrast with the purple mila wallpaper.

The simplest gradient definitions take a type specifier, a number to say how many intermediate colours to use, and two colours. They take up the background colour slot in a colorset like RootTransparent or Pixmap.

FvwmScript FvwmScript-PreviewCset 20 "HGradient 128 purple black"

If you want to go the other way, you have to reverse the order of the colours.

FvwmScript FvwmScript-PreviewCset 21 "HGradient 128 black purple "

Of course, there are more than just horizontal gradients. VGradients work top-to-bottom:

FvwmScript FvwmScript-PreviewCset 22 "VGradient 128 black purple "
FvwmScript FvwmScript-PreviewCset 23 "VGradient 128 purple black "

You can do diagonal ones. Bgrads go bottom-left-to-top-right; DGrads go top-left-to-bottom-right. Like this:

FvwmScript FvwmScript-PreviewCset 24 "BGradient 128 black purple "
FvwmScript FvwmScript-PreviewCset 25 "BGradient 128 purple black "
FvwmScript FvwmScript-PreviewCset 26 "DGradient 128 black purple "
FvwmScript FvwmScript-PreviewCset 27 "DGradient 128 purple black "

For the others: CGrads are circular, SGrads are square; RGrads are radial and radar-like while YGrads are similar with a yin-yang effect. You must be getting the hang of these by this stage, so Iā€™ll FFwd a bit.

FvwmScript FvwmScript-PreviewCset 28 "CGradient 128 black purple "
FvwmScript FvwmScript-PreviewCset 29 "CGradient 128 purple black "
FvwmScript FvwmScript-PreviewCset 30 "SGradient 128 black purple "
FvwmScript FvwmScript-PreviewCset 31 "SGradient 128 purple black "
FvwmScript FvwmScript-PreviewCset 32 "RGradient 128 black purple "
FvwmScript FvwmScript-PreviewCset 33 "RGradient 128 purple black "
FvwmScript FvwmScript-PreviewCset 34 "YGradient 128 black purple "
FvwmScript FvwmScript-PreviewCset 35 "YGradient 128 purple black "

Plenty to go on with there, isnā€™t there? And we havenā€™t even looked non-linear grads.

A non linear grad is like two or more separate grads, combined into one.

FvwmScript FvwmScript-PreviewCset 33 "HGradient 256 2 white 128 purple 128 black"

I donā€™t intend (as Iā€™m sure youā€™re delighted to learn) to go through all possible combinations here - there are way too many. But itā€™s worth playing with these things a bit and getting a feel for the possibilities. For instance, you can get a bilinear grad by going from black to purple to black. (You are allowed to use other colours).

FvwmScript FvwmScript-PreviewCset 36 "HGradient 256 2 black 128 purple 128 black"
FvwmScript FvwmScript-PreviewCset 37 "CGradient 256 2 black 128 purple 128 black"
FvwmScript FvwmScript-PreviewCset 38 "SGradient 256 2 black 128 purple 128 black"

Look at that somewhat lackluster RGrad in bilinear mode. Look at that shadow effect!

FvwmScript FvwmScript-PreviewCset 38 "RGradient 256 2 purple 128 black 128 purple "
FvwmScript FvwmScript-PreviewCset 38 "YGradient 256 2 purple 128 black 128 purple "
FvwmScript FvwmScript-PreviewCset 39 "YGradient 512 4 purple 1 black 1 purple 1 black 1 purple "

Notice that the number between the grads define the relative number of colours.

FvwmScript FvwmScript-PreviewCset 40 "YGradient 512 6 purple 1 black 1 purple 1 black 1 purple 1 black 1 purple "
FvwmScript FvwmScript-PreviewCset 40 "YGradient 512 6 white 1 purple 1 black 1 white 1 purple 1 black 1 white " 

Some of these things make me feel like I should be smoking controlled substances or something.

Lastly, non-linear grads, as the name implies, do not have to be evenly distributed:

FvwmScript FvwmScript-PreviewCset 38 "HGradient 256 2 purple 1 black 5 black "

OK. Youā€™re either keen, or youā€™ve vowed never to use a gradient as long as you live. Letā€™s move on.
Change the ā€œFontā€ line at the top of the script like this:

Font "shadow=2:xft:Oberon:size=12"

Change the font to something on your system, obviously. Now we can play with font shadows.

FvwmScript FvwmScript-PreviewCset 20 "HGradient 128 purple black, fg black, fgsh white"

Thatā€™s clearly visible all right. Try some other colours.

One that you might not have thought of:

FvwmScript FvwmScript-PreviewCset 20 "fgsh purple"

Despite the purple on purple effect, it adds just enough definition to show up the black text when the background fades, and never quite vanishes into the background at the other side. Useful for when your text starts fading out when your titles start vanishIng into the gradient.

Right. Thatā€™s more than enough of this. Iā€™m going to play a bit more catch up next time. I have some tricks with decors, key bindings, pagers, multiple desktops and, if I can make it work, a floating dock to hold some Afterstep/WindowMaker dockapps that donā€™t fit with the my design criteria, but which I find myself missing; monitors for battery level, email and network activity. That sort of thing

And if I ever get to then end of that lot, I think Iā€™ll call this configuration done.

I bet Nick you know this already, but for newcomers: Fvwm comes with a similar thing called FvwmScript-Colorset, which you can run and experiment with colors (and if you are using a configuration using colorsets, you can actually see then changes as you make them).

I hadnā€™t realised that. The script I used was just something I knocked up so I could see the effect of a few grads. I hadnā€™t realised there already was something to do the same job.

I really must get around to looking through all of those scripts sometime.

Last time I wanted a purple gradient for my titlebar. I talked about gradients but didnā€™t get around to setting the titlebar. Itā€™s not enough to set the window colorsets. This doesnā€™t work:

colorset $[cset_norm] BGradient 256 purple4 black 
colorset $[cset_focus] HGradient 256 purple black
Style "*" Colorset $[cset_norm]
Style "*" HilightColorset $[cset_focus]

What you Have to do is set them as part of the decor using the TitleStyle command.

AddToDecor DefaultDecor
+ TitleStyle Active HGradient 256 purple black
+ TitleStyle Inactive BGradient 256 2 purple4 50 black 50 black

This is ok, but I get problems with my text disappearing as the background color changes. I can fix that with a drop shadow.

DefaultFont "Shadow=2 nw:xft:Oberon:style=Regular" 

I discovered the DefaultFont command the other day. It saves hunting all through your config file for font commands. It took a bit of messing about to get the colours right for the drop shadow. Eventually I settled on this:

Colorset $[cset_norm]   fg purple4, bg purple4, hi rgb:c5/b9/c5, sh rgb:46/41/46, fgsh black
Colorset $[cset_focus]  fg purple, bg purple, hi rgb:c5/c5/b9, sh rgb:46/46/41, fgsh black

The result of all this fiddling looks like this:

Not bad, if I say so myself. The drop shadow, because I cast it to the north east, works against the relief borders of the titlebars, giving the text an indented look which quite appeals to me.

With gradiated titlebars, the solid purple highlights for the pager and taskbar suddenly look clumsy. I set out to apply the same colorsets to them and made a discovery: if you set a colorset for FvwmButtons or IconMan it gets applied to all the buttons. So if I open a console and type

colorset 40 VGradient 128  black purple
*Klix: Colorset 40
KillModule Klix
KillModule FvwmButtons
Module FvwmButtons Klix

then I get

instead of the having each button shaded individually. A Hgradient works better, but the highlight looks odd then. Eventually, I settled on leaving the buttons black with a diagonal grad for the selected button.

Now then: how many people noticed that my two main colorsets now use a nice purple-on-purple motif? ;) The thing is that, since decors override styles for window titles, that means I can color my windows however I like. And since the pager takes its window colours from the styles that colour the window titlebars, by specifying purple I get get rid of the black-on-black effect that plaugued my pager earlier. You can see what I mean in the buttons image above. So thatā€™s another job off the list.

And that brings by config, visually at least, up to date with what Iā€™m using on my machine at the moment. Before we leave the subject though, I thought Iā€™d take a crack at doing a pixmap based decor.
Dorothy Robinson has a page with loads of these things. Dorothyā€™s are elegant, tasteful, polished - nothing at all like mine is going to turn out.

First things first: we need an idea. I had this mental picture of an electric spark shooting across the titlebar, outlining the text, and continuing on to the end. So letā€™s start with the spark.

Out with the Gimp and create a new image, 40x20. I picked on 20 pixels deep because any less and I found the image tried to tile itself vertically. You may need to adjust the height based on titlebar size and font in your config. The width of 40 pixels is arbitary since we want it to tile horizontally.

On the blank image, create 4 layers and fill the bottom one with black. Then use the path tool to draw a zig-zag lightning path across the image. Stroke the path three times. On the second from bottom image use a fuzzy purple airbrush. Next layer up and stroke with 3 pixel black. On the top image stroke with 1 pixel purple. You may need to restroke the airbrush layer, or fiddle with th opacity a little, With a bit of luck youā€™ll get something like this:

Next, since Iā€™m by no means convinced Iā€™ll be keeping the results of this experiment. I set up a file in $HOME/.fvwm called test_decor

SetEnv decor_dir $[HOME]/.fvwm/decors

DestroyDecor TestDecor
AddToDecor TestDecor
+ TitleStyle Multipixmap Main $[decor_dir]/electric-lightning.png

Style TestTerm UseDecor TestDecor
recapture

Then type

read test_decor

into a console and start an term with title ā€œTestTermā€

xterm -T TestTerm

You should get a title bar like this

The image interferes with the text, and weā€™ve reverted to the standard FVWM icons, but weā€™re moving in the right direction. Letā€™s blank off the titlebar behind the text:

SetEnv decor_dir $[HOME]/.fvwm/decors

DestroyDecor TestDecor
AddToDecor TestDecor
+ TitleStyle Multipixmap                                \
        Main $[decor_dir]/electric-lightning.png        \
        UnderText Solid black

Style TestTerm UseDecor TestDecor
recapture                       # need this to force redisplay

Now we get

which looks OK as it is. Still, I promised myself to go the full distance on this, so letā€™s do the bit where the text meets the lightning.

For this I set out to create a semi-circle al a-spark with prickly electrical effects. What I got looked more like the end of some compressed air subterranean bullet train. Since thatā€™s how my creativity sometimes works, I decided to go with that and spiced it up with a some colored lights


Flip it horizontally and you get one for the other end. Then change the title style part of test_decor:

+ TitleStyle Multipixmap                                                \
        Main $[decor_dir]/electric-lightning.png,                       \
        RightOfText $[decor_dir]/electric-rightend_f.png,               \
        LeftOfText $[decor_dir]/electric-leftend_f.png,                 \
        UnderText Solid black

As I said earlier, weā€™re back to the FVWM default icons. Since we already did the vector button thing, Iā€™ll gimp up a couple of icons. I thought to have one of them as a source and the other as a sink - as if the spart was jumping from one to the other. The sink one wound up looking a bit like a plasma ball, so I added some plasma from the gimp filters->render->clouds tool and turned the opacity tigt down. We add them using ButtonStyle commands similar to TitleStyle.

AddToDecor TestDecor
+ ButtonStyle 1 Pixmap $[decor_dir]/electric-ball_f.png
+ ButtonStyle 2 Pixmap $[decor_dir]/electric-plasma_f.png

Which gives us something like this

All of a sudden the bevel on the title bar and icons looks out of place. We can fix that:

AddToDecor TestDecor
+ BorderStyle -- HiddenHandles NoInset
+ TitleStyle -- Flat

While Iā€™m at it, Iā€™ll add a roof and a floor to the title capsule. These are basically just two purple lines. I added a couple of bumps on the top and a faint glow just inside the walls. I also turned off the window border.

All of a sudden, thatā€™s looking rather good, I think.

I tried adding

+ TitleStyle LeftJustified

to shunt the title capsule over to the side, but decided against because I lost the mad scientist ā€œcaught between the elctrodesā€ look of the thing.

So thatā€™s almost done. Now I just need some way to tell the focus window from the rest. I decided to cut the power on the inactive windows: no spark, the lights go out on the R2D2 heads, and the plasma balls go dark. Similarly, I thought Iā€™d light up the cabin for the focus window.

We use the keywords ā€œActiveā€ and ā€œInactiveā€ to make a TitleStyle or ButtonStyle apply to just one state or another. So we copy the relevant lines, copy and edit the pixmaps, and the final config looks like this:

DestroyDecor TestDecor
AddToDecor TestDecor
+ TitleStyle Active Multipixmap                                         \
        Main $[decor_dir]/electric-lightning.png,                       \
        RightOfText $[decor_dir]/electric-rightend_f.png,               \
        LeftOfText $[decor_dir]/electric-leftend_f.png,                 \
        UnderText $[decor_dir]/electric-text_f.png
+ TitleStyle InActive Multipixmap                                       \
        Main Solid black,                                               \
        RightOfText             $[decor_dir]/electric-rightend_u.png,   \
        LeftOfText              $[decor_dir]/electric-leftend_u.png,    \
        UnderText               $[decor_dir]/electric-text_u.png
+ ButtonStyle 1 Active          Pixmap $[decor_dir]/electric-ball_f.png
+ ButtonStyle 1 InActive        Pixmap $[decor_dir]/electric-ball_u.png
+ ButtonStyle 2 Active          Pixmap $[decor_dir]/electric-plasma_f.png
+ ButtonStyle 2 InActive        Pixmap $[decor_dir]/electric-plasma_u.png
+ ButtonStyle All Active (-- flat) Inactive (-- flat)
+ BorderStyle -- HiddenHandles NoInset
+ TitleStyle -- Flat

Style TestTerm UseDecor TestDecor, BorderWidth 0, HandleWidth 0

Colorset $[cset_norm] fg gray60, fgsh purple4
Colorset $[cset_focus] fg black, fgsh purple


Which is all very well, but a little busy for my tastes. I think Iā€™ll be sticking with the grads.

Right. Thatā€™s done for this session. Next I think key bindings, and desktops.

The desktop currently looks like this:


Hope you like the new wallpaper :wink:

[edit - fixed some images, some typos, etc]

It looks OK, not really my colour preference, but to each their own. It might again just be me, but your screenshots probably donā€™t do your wonderful tweaking justice ā€“ everything seems so dark.

ā€“ Thomas Adam

Thatā€™s probably my terms. I shade them toward black by 40% or so to help visibility for the text when editing. I can still see the background if I look for it, but I can also ignore it to concentrate on my editing. Of course my preference for dark desktops wonā€™t help either.

The purple is purely because that was the predominant colour in the wallpaper I used at the start of this exercise. I grabbed the first one I liked from deviantart, and then chose colour to match that. Now if I want to change wallpaper, I need something with a lot of purple for everything else to match :smiley:

[edit]

I uploaded a new final screenshot with fully transparent terms. Itā€™s still a basically dark desktop, but at least Iā€™m not fading any more than I have to now :slight_smile:

Just wanna say.

GREAT :smiley:

Is there coming more of this?

Not very soon I donā€™t think: http://fvwm.lair.be/viewtopic.php?t=475

That said, life goes on and itā€™s about time did a bit more FVWMing. The trouble is that most of the bits I was going to use for the next instalment seem to have been spread around posts on other subjects. The key binding and desktop management all ended up in the new default desktop project, and most of the rest in the modules from scratch posts and the module release posts.

I might have a shot at pulling the bits together for one more post. Apart from that though, itā€™s finished. I set out to write an example desktop and document the process. I did it, the desktop is finished. Iā€™m still using it, rather to my surprise.

Itā€™s tempting to repeat the process, with a view to doing things differently. maybe something a bit lighter. The main constraint is time. H still have a house to finish off and a job and a PhD, so Iā€™ll have to see how things go.

I have come upon this seemingly most-highly-useful thread almost two years after it was initiated, and I suspect that the starting FVWM default then is not what it is today, with version 2.5.19. I am beginning to work with it, from ā€œscratchā€ ā€“ as was intended ā€“ and some things in the current default appear to me a bit different from what is in the thread. (For the purposes of this response I donā€™t think I need to go into any precise detail.) I am wondering only whether any possible differences between the earlier and current defaults are substantive enough as to render aspects of this thread unviable. Has anyone had any recent experiences in this regard?

Itā€™ll be fine.

ā€“ Thomas Adam