Basic fvwm Configuration
This article is primarily intended for, and dedicated to, all the novices and newcomers who have joined the worldwide community of Linux users. Welcome aboard! This article will attempt to introduce you to one of the most versatile and popular X-Windows managers: fvwm (which, I've been told, originally stood for “Frugal Virtual Window Manager”). Its well-deserved popularity is based, among other things, on its relatively parsimonious memory consumption, an extensively customizable 3 Motif-ish appearance, a virtual desktop, and the ability to extend functionality through the use of modules.
Before we begin, let me state a couple of presuppositions:
1. You've installed X-Windows and the fvwm window manager and have them working, and
2. You're willing to tinker a bit.
If this is you, keep reading!
First, some background: the concept of a window manager is, in essence, a rather simple one. X-Windows itself oversees certain rudimentary tasks such as managing the display hardware (monitor, keyboard, and mouse), handling mouse and keyboard events, and creating the windows which appear on the display. Just exactly how windows appear and behave is left up to the window manager. Window managers, such as fvwm, control how you interact with programs by providing decorative window frames, window controls, menus, virtual desktops, and so forth. Change to a different window manager and you can create a completely different look and feel even though the programs which run under them are identical.
fvwm was developed by Robert Nation as a derivative of one of the original MIT window managers, twm (the Tabbed Window Manager, which started life as Tom's Window Manager in honor of its author, Tom LaStrange). fvwm is currently maintained by Chuck Hines. The latest official release is fvwm-1.24r, although a beta version—pre2.0pl40 (as of mid-December 1995)--is currently available as well. These can be found at: ftp://sunsite.unc.edu/pub/Linux/X11/window-managers/ ftp://ftp.hpc.uh.edu/pub/fvwm/ ftp://ftp.x.org/contrib/
In addition, there are a number of excellent WWW pages dedicated to fvwm which provide a wealth of information, screen shots, and sample .fvwmrc configuration files. These include:
T.J. Kelly's The fvwm Home Page: www.cs.hmc.edu/~tkelly/docs/proj/fvwm.html
Todd Postma's fvwm Info: http://xenon.chem.uidaho.edu/~fvwm/
Jens Frank's fvwm Documentation: namu19.gwdg.de/fvwm/fvwm.html
Erik Kahler's fvwm Home Page: mars.superlink.net/user/ekahler/fvwm.html
At this point it's probably worth mentioning that if you're serious about customizing fvwm, it's a good idea to get the sources even if you don't intend to compile your own version. Why? Some Linux distributions do not include full documentation for every program. Getting the sources for fvwm ensures that you'll have the complete documentation, including manual pages for the various fvwm modules. Also, if you do choose to compile fvwm yourself, you can determine which features you wish to include.
Some of the basics we'll try to cover include:
1. Managing configuration files
2. Starting programs at load up
3. Adding items to the fvwm popup menus
4. Color customization
Keep in mind that the information presented here is intended to be used as a primer. I'd recommend skimming through the manual pages for fvwm in addition to reading this article. The definitive source of information is the manual page and documentation that comes with the program source distribution.
The first thing that you'll need to know about fvwm is where the configuration file is found. When fvwm starts, it first looks for .fvwmrc in your home directory. For example, if your username is johndoe, fvwm looks for the file /home/johndoe/.fvwmrc. If this file is absent it then looks for the system-wide configuration file /usr/lib/X11/fvwm/system.fvwmrc. If neither of these files are present, it simply exits.
One of the first things you'll want to do is make a copy of the default system-wide configuration file and put it in your home directory:
$ cp /usr/lib/X11/fvwm/system.fvwmrc ~/.fvwmrc
Be sure to copy this to ~/.fvwmrc and not ~/system.fvwmrc. Creating a copy of the file in your home directory is a good idea for a couple reasons:
1. If your .fvwmrc file gets corrupted, fvwm will fall back to using the system-wide configuration file.
2. If ~/.fvwmrc inadvertently gets deleted, you can use the system.fvwmrc file to re-create it.
3. On a multi-user system, it allows each user to customize her/his own .fvwmrc file.
The other issue to think about at the outset is sequential customizations. Chances are, over the course of several weeks or months, you'll make numerous small and large changes to the config file as you get fvwm customized to work the way you want it. What happens when you accidently overwrite or delete system.fvwmrc or your .fvwmrc? Serious bummer.
Managing system configuration files is important for anyone who is running, and likely administering, his own Linux system. It is wise to have a well-thought-out plan for how changes are implemented and changes tracked. Never do what you cannot undo. fvwm uses a single configuration file, making this a fairly simple task. Here are a few suggestions.
Before making any changes in a default configuration file, make a backup of it and give it a distinctive suffix, such as .dist. For example, before you edit the system.fvwmrc file for the first time, you'd make a copy of it by:
# cp system.fvwmrc system.fvwmrc.dist
The .dist suffix alerts you to the fact that this is an original file from the distribution. To further safeguard it, you should copy this to a directory owned by root (the superuser) and set the permissions on that directory to read and execute only, except for root. To do this, you could, for example, make a directory in your /etc or /usr/local directory called backups/ and then copy all default config files to this directory.
To do this, log in as root and enter:
# mkdir /etc/backups # chmod 755 /etc/backups
Setting the directory permissions, as root, to 755 allows root full read, write, and execute permissions, while preventing write permissions for everyone else. With read and execute permissions, users may change to the directory and do a file listing but cannot (since they don't have write permission to that directory) delete a file.
After you've created a backup directory and set the appropriate permissions you should, as root, make backup copies of important configuration files with the .dist suffix. You can also set the permissions for each file to read-only by:
# chmod 744 /etc/backups/system.fvwmrc.dist
This limits permissions on the file to read only for all users except root. Making backups of default configuration files is helpful only if it actually works. Obviously, you'll want to make a backup copy of a working configuration file. This, however, still doesn't address the question of what to do about keeping track of each of your changes. Here are a few suggestions.
1. After you have modified a configuration file, and ensured that it works correctly, make a copy of it and number each file consecutively such as:
fvwmrc.01 fvwmrc.02 fvwmrc.03 ...
Comments can be added by starting a line with the # (hash) character and should probably include the date and what modifications were made. If space is a problem, you can compress all the files you are not currently using.
2. Use RCS, the “Revision Control System”, to keep track of your changes. Before you make any changes to the file, run the RCS check-in program:
$ ci -l .fvwmrc
It will ask you for a description of the file; type:
fvwm configuration file .
The . on a line by itself finishes the description.
Then, every time you make a change to the file, run the same command. It will ask you for a description of the change you just made; type something like:
Added Calculator, xjed, and Emacs to the "Application" pop-up menu. .
so that you can find this change later.
RCS keeps track of all the changes you have made to .fvwmrc in a file called “.fvwmrc,v”. Instead of storing a complete copy of each new version of the file, it stores only the changes you have made, plus the latest version of the file.
How do you find the change later? The command line
$ rlog .fvwmrc | less
will give you a history of all the changes you have made. Each change has a revision number, starting at 1.1.
If you want to compare the current copy of the file with the version you previously checked in, use this command:
$ rcsdiff -u .fvwmrc | less
You can retrieve any version of the file you want (overwriting the current version) with
$ co -rrevision .fvwmrc
If you want more information on how to use RCS, it is available with:
$ man rcsintro
which provides a good overview of the concepts and commands you'll need to know. [Linux Journal also published an overview of RCS in issue 10, page 36—ED]
Using the RCS system is only slightly more complex a method of version control than simply making copies of every modified file. However, the basics are easily mastered and can be used for any file—programming project, article, term paper, etc.—that is undergoing sequential revision.
Now that you've copied the .fvwmrc file to your home directory and decided how you'll track your changes to it, you're ready to start tinkering! One of the first things you might be interested in is automatically launching programs when fvwm starts. You may want to start an xterm or two, a clock or calendar, xbiff (to warn you when mail arrives), and so forth. fvwm allows you to define an InitFunction within .fvwmrc that handles program launching at initialization. Before discussing this, however, we need to briefly mention xinit.
xinit is the program responsible for starting the X Window System and, like fvwm, it uses an .xinitrc file. A user may create a personalized copy of this file in her or his home directory as ~/.xinitrc, or simply use the system wide default located in /usr/lib/X11/xinit/xinitrc. To see how xinit launches programs at startup, let's look at the default xinitrc file that came with Slackware 2.2.0:
# start some nice programs xsetroot -solid SteelBlue & fvwm
In this simple example, xsetroot sets the color of the root window to SteelBlue. Once it is done, fvwm is started. A slightly more complicated example is given in the manual page for xinit:
xrdb -load $HOME/.Xresources xsetroot -solid gray & xclock -g 50x50-0+0 -bw 0 & xload -g 50x50-50+0 -bw 0 & xterm -g 80x24+0+0 & xterm -g 80x24+0-0 & twm
In this example, several programs are launched before twm is started. The important thing to point out is that the stanzas which launch programs, such as xclock and the xterm, need to end with an ampersand (&) so as to have them running in the background. It is also important that the window manager be started last and that it runs in the foreground (i.e., do not add an ampersand at the end of the line).
fvwm provides a similar method for launching programs at startup using the InitFunction. To see how, let's look at a sample entry in .fvwmrc:
Function "InitFunction" # Module "I" FvwmBanner # Get the fvwm GoodStuff button bar running Module "I" GoodStuff # Module "I" FvwmPager 0 3 # Then, the analog clock - Swallowed by GoodStuff Exec "I" exec xclock -g 140x160-145+138 & Wait "I" xclock # Start xmailbox - swallowed by GoodStuff Exec "I" exec xmailbox & Wait "I" xmailbox # Fire up xload - also swallowed by GoodStuff Exec "I" exec xload -geometry 80x80+100+100 & Wait "I" xload # Now, start up xcalendar Exec "I" exec xcalendar -g 345x382+793+372 & Wait "I" xcalendar # Finally, fire up a full screen xterm Exec "I" exec xterm -sb -j -ls -g 84x48+4+4 & Wait "I" xterm EndFunction
Since it's easiest to explain by example, let's see what you'd need to do to add a second xterm to the startup. To begin with, InitFunction generally uses two-line stanzas for launching programs, and these take the form:
Exec "I" exec program_name -options & Wait "I" program_title
For example, the stanzas which start xcalendar look like:
# Now, start up xcalendar Exec "I" exec xcalendar -g 345x382+793+372 & Wait "I" xcalendar
Lines which begin with the hash (#) character are treated as comments and ignored by fvwm. The first line begins with the reserved word Exec and has four arguments:
1. An "I" (in double quotes).
2. The word exec.
3. The command used to start the program.
4. Any command line options followed by an ampersand (&).
The next line begins with the word Wait which causes an fvwm function to pause while a window with the name given on the command line is drawn to the display. In this case, the InitFunction pauses while a window with the title xcalendar is drawn to the display. Once the window has been drawn, fvwm continues.
Be aware that this is a bit of a fib, but a useful one for the moment. The Wait function is primarily used when programs are launched on more than one desktop—something we won't touch on for the moment. Assuming you use a single desktop, as in this present example, the Wait stanza may be safely omitted.
Going back to our assignment to start another xterm, we could launch a second xterm by adding the following:
Exec "I" exec xterm & Wait "I" xterm
which would be sufficient to get a second xterm going.
If you added this entry and started fvwm, you'd find that when fvwm got to the point in the initialization process where the second xterm was started, it would draw the outline of the xterm window and wait for you to position it before proceeding. That's not very convenient if you have to do this every time fvwm starts. The way around this is to add a command line option specifying the xterm's geometry, which allows you to control where to place the window from the command line.
A geometry entry for an application might look something like this:
If this looks a bit cryptic, don't worry, it's actually pretty simple. Converting this statement into plain English yields:
“The application window is 420 pixels wide by 320 pixels high, with its left border 5 pixels from the display's left edge and its top border 20 pixels from the display's top edge.”
Pretty simple, eh? There are actually only a couple of rules to keep in mind when specifying a window's geometry. First, dimensions are generally in terms of pixels, although there are times, notably with xterms and some text editors, in which the width and height dimensions will be in terms of characters. You'll notice in the example .xinitrc file above that the width and height dimensions for the xterm were given as 80x24, or 80 characters wide by 24 columns high. If you bear in mind that your entire display screen is probably 640x480 or 800x600 or 1024x768 pixels, depending on your resolution, you can get a feel for how much of the screen is taken up by an application window that is, say, 400x300 pixels.
The second set of numbers specify the horizontal (x-offset) and vertical (y-offset) distances from the edge of the display screen. Again, this is pretty straightforward: think of the screen in terms of graphing paper in which the upper left hand corner is 0,0 and the values increase as you move from left to right and from top to bottom.
If your screen were 640x480 pixels, your top left corner would be considered 0,0; the bottom left corner would be 0,480 (remember that the vertical position increases as you move from top to bottom); the top right corner would be 640,0; and the bottom right corner would be 640,480. The other thing to keep in mind is that horizontal and vertical positions are generally (but not always, as we'll see in a minute) specified in terms of the left and top sides of the application window.
For example, suppose that you wanted to put an xterm window in the upper left hand side of the screen. You decide that you want it 10 pixels from the left hand side of the display and 50 pixels from the top. You also want the window to be 400 pixels wide by 320 pixels high. Simple enough. You'd use the following geometry option to accomplish this:
Notice the general form this takes:
Using a plus + sign before the pixel value indicates the position of the window with respect to its left hand or top edges. However, using a minus - sign specifies the opposite meaning: the horizontal position is the distance in pixels between the application window's right hand side and the right side of the display, and the vertical position is the distance in pixels between the application window's bottom edge and the bottom edge of the display.
If this seems a bit confusing try playing with it a bit. Start up fvwm and in an xterm enter the following commands:
xterm -g +5+5 & xterm -g -5-5 & xterm -g -5+5 & xterm -g +5-5 &
Try these out and see where the xterm gets put. Note that you can generally abbreviate -geometry to a simple -g.
We've wandered a bit from our discussion about launching programs at startup. In practical terms, figuring out the correct geometry for all of the applications you want to have started is pretty easy. The first step is to get pencil and paper ready because you'll want to jot some notes.
Customizing the start-up desktop usually begins by starting all of the applications that you want present when fvwm begins. Try out various command line options to get the look and feel that you want. Reading a program's manual page often helps you determine what options are available at run time. Once you get an application running, you can generally resize it by clicking the mouse on one of the “L” shaped window corners and dragging it to a larger or smaller size. Clicking and dragging on the titlebar or side borders lets you position the window.
Once you have everything started, positioned, and sized the way you want it, jot down each application and the command line options, if any, that you used. To get each window's geometry, we'll use a great little program called xwininfo.
Start it from an xterm by entering:
at the command prompt. Notice that you don't use an ampersand for this command. Your mouse cursor will change to a cross-hair and the following instructions will be displayed:
xwininfo: Please select the window about which you would like information by clicking the mouse in that window.
Clicking on an application window produces the output like the following:
xwininfo: Window id: 0x2c00007 "ez ~/fvwm_LJ.ez*" Absolute upper-left X: 92 Absolute upper-left Y: 28 Relative upper-left X: 0 Relative upper-left Y: 0 Width: 528 Height: 724 Depth: 8 Visual Class: PseudoColor Border width: 0 Class: InputOutput Colormap: 0x21 (installed) Bit Gravity State: ForgetGravity Window Gravity State: NorthWestGravity Backing Store State: WhenMapped Save Under State: no Map State: IsViewable Override Redirect State: no Corners: +92+28 -532+28 -532-148 +92-148 -geometry 528x724+85+0
In this instance, I clicked on the EZ editor's window, which produced a veritable cornucopia of information. Specifically, the geometry setting that you were looking for is in the last line. Do this for all the applications that you want started, and your work is pretty much done. Find the section in .fvwmrc that defines the InitFunction, add or modify the entries so as to start the applications that you want—don't forget to put that ampersand at the end of each Exec line!—and you should be all set. Once you've gotten things the way you want them, don't forget to make a backup of your newly modified .fvwmrc file.
One more thing before we leave the subject of launching programs at start up. fvwm comes with a number of modules, which are separate programs which must be spawned by fvwm—you can't start these from a command line. There are a number of modules which can generally be found in the /usr/lib/X11/fvwm directory. A couple of the more common modules to launch at start up include FvwmBanner, which places a decorative banner across the root window; FvwmPager, which serves as a virtual desktop manager when you have multiple desktops going; and the GoodStuff button bar. The entry in InitFunction to start an fvwm module is a bit different than a regular application in that it is simpler:
Module "I" GoodStuff Module "I" fvwmPager 0 3
You'll notice that there's no Exec or Wait statement needed. Simply use the reserved word Module, followed by "I" and then the name of the module to launch with any options.
That wasn't too bad, was it? This should give you the basics that let you customize your startup desktop. Next month, I'll cover launching programs once fvwm has started—and more!
John Fisk (firstname.lastname@example.org) After three years as a General Surgery resident and Research Fellow at the Vanderbilt University Medical Center, he decided to “hang up the stethoscope” and pursue a career in Medical Information Management. He's currently a full-time student at the Middle Tennessee State University and hopes to complete a graduate degree in Computer Science before entering a Medical Informatics Fellowship. In his dwindling free time he and his wife Faith enjoy hiking and camping in Tennessee's beautiful Great Smoky Mountains. An avid Linux fan since his first Slackware 2.0.0 installation a year and a half ago.