GWM Manual Contents


GWM like any other window manager is in charge of all that is exterior to other application windows on the display. It performs its task by decorating the existing windows on the screen with its own windows. The appearance and behavior of these windows are described by the user through programs written in the lisp-like WOOL language, which are interpreted by the built-in WOOL interpreter of GWM.

The GWM Window manager is composed of 2 modules: the window manager itself, GWM, and the lisp interpreter WOOL. The role of the garbage-collected WOOL objects is to build shared descriptors that will be used by GWM to build its (non-shared and non-garbage-collected) objects.

GWM was designed in 1988 and was developed on 68020 unix stations with 4K of main memory, and thus tradeoffs in its design has been made to make it as efficient as current C window managers, often at the expense of ease of customization. But the power is there under the hood if you need it.

My main research interest was on window management metaphors, but the design and development of the platform flexible enough to implement my views as WOOL profiles has taken me too much time, and I did not find time to implement the rooms-like metaphors I wanted to try. But I, and some others, still use only GWM as it provides features yet unseen in any other WMs to date.

GWM Window OBjects: the wobs

GWM is built upon the notion of a wob, which, not unlike an X Widget is an object composed of:

Wobs are not directly created with WOOL constructors, they are described, and GWM uses this description to physically create the wobs when it needs to, when decorating a new client window for instance.

Like any X11 window, the user can choose the width, color(s), and tiling pixmap of the border of the wob (which is considered to be in the wob for input purposes). There are four kinds of wobs:

Other GWM objects

Other gwm objects are just X objects (fonts, pixel colors ...) that are referenced by their X id, and are accessed via encapsulating WOOL types, such as Numbers or Pixmaps.

WOOL objects

WOOL is a lisp interpreter of a special kind, since it has some important design differences from ``real'' lisps:

WOOL alas lacks lots of features from real lisps, for the sake of small footprint. But the WOOL code accounts for about 50k of the total text size of 150k of GWM.

The different WOOL objects are:


When you start GWM, it:

  1. connects to the display it must manage to initialize its X11 structures

  2. reads and interprets the user's WOOL profile (searched for in a user-defined path, see usage). This profile must define at least two WOOL functions:

  3. looks to see if it is the only window manager running; if not, it aborts.

  4. decorates the managed screens by calling the user-defined describe-screen function for each one, with the screen active value being set to the current screen.

  5. decorates all already mapped client windows, by calling describe-window with the current client window being set to each window.

  6. executes the (user-defined) opening function for each screen.

  7. enters GWM main loop, which consists in:

    1. waiting for an X event

    2. examining the received event, and if it is for an existing wob, sends it to the fsm of this wob, else if it is a new window which is being mapped for the first time, decorates it (by calling describe-window)

    When an event is sent to a fsm, it is matched against the transitions in the current state of the fsm, and as soon as one matches, the corresponding WOOL expression is evaluated, and the fsm changes state if necessary. If no transition is waiting for the event, it is discarded.

Lazy evaluation

For sub-wobs of wobs, i.e., bars of a window, plugs of a bar, bars of a menu, and menu of any wob, lazy evaluation is performed. That is, on the realization of the wob the field is re-evaluated if the result is not of the expected type. This allows for constructs such as:

        (plug-make '(label-make window-name))

which creates a plug whose text is fetched as the name of the window on each realization, you do not have to explicitly eval a quoted expression.

Screen-dependent objects

An invocation of GWM can manage all screens attached to a display (there is one keyboard and mouse per display), but in X, screens are very distinct worlds. If you create a pixmap or a color on a screen, you cannot use it on another one. The list of objects created on one screen that cannot be used on another is:

Objects made by

colors color-make
pixmaps pixmap-make, label-make, active-label-make
cursor cursor-make
menus menu-make

And of course, all the wobs and windows are screen-specific.

Sending commands to GWM

Any program can make GWM execute any WOOL code by putting the WOOL code to execute as an ASCII string in the GWM_EXECUTE property on any root window or client window of the screens managed by GWM, which will parse and evaluate the given string with the current window being the one on which the property was set.

This feature is built in, so that it will work regardless of the profile used.

You can also use the program gwmsend in the contrib/gwmsend directory in the distribution to send commands to GWM. It takes its first argument and puts in the GWM_EXECUTE property on the root window. It can thus be used like:

    gwmsend '(? "Hello there\n")'

A better way is to use the -I option to make GWM read its standard input for commands. a recommended use is to run not gwm directly but a command like:

    xterm -title gwm -e fep gwm -IP

fep is a pseudo-tty driver which gives its argument line editing and history capabilities, like ile or the GNU library readline.

Using gwmchat as a shell to GWM

If you want to communicate with GWM more interactively, via WOOL, you can use the program gwmchat (in the contrib/gwmchat directory). Start gwmchat in any terminal window, with the same flags as you would have given GWM. It forks off GWM and then waits for commands to send it. Output from GWM goes to the same terminal window.

In your .xinitrc or .xsession or correspondingly, where you normally would start GWM, you may instead have something like:

    xterm -e gwmchat
    xterm -geometry =80x16-1-1 -e gwmchat -f vtwm

gwmchat can be compiled to use the readline package. This is strongly recommended if it is available and if gwmchat is to be used in other ways than from inside Emacs, since otherwise it will have no command line editing mechanisms whatsoever (other than erasing backwards).

Checking that GWM is running

On each screen it manages, GWM will maintain a hidden window whose X Id will be given as a 32-bit Id in the GWM_RUNNING property on the root window and the hidden window itself. Thus, if this window exists, and has the GWM_RUNNING property set, you can be sure that the screen is managed by GWM.

Christophe Tronche,