\chapter{Overview} \sloppy {\GWM} like any other window manager is in charge of all that is {\bf exterior} to other application windows on the display. It performs its task by {\bf 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. \section{GWM Window OBjects: the wobs} {\GWM} is built upon the notion of a {\bf wob}, which, not unlike an X {\sl Widget\/} is an object composed of: \begin{description} \item[an X11 window] used to display the wob on the screen (output) \item[a {\WOOL} finite state machine] used to trigger {\bf WOOL} functions in response to X11 events sent to the wob (input) \end{description} Wobs are not directly created with {\WOOL} constructors, they are {\bf 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: \begin{description} \item[Window] An X11 application, such as XTERM(1) or XCLOCK(1) usually opens one or more windows directly on the screen (in fact the {\em root window\/}). We will call these windows, which are not created by {\GWM}, {\bf client windows}. {\GWM} will ``decorate'' these client windows by {\em reparenting\/} them, i.e. by creating a {\bf Window} wob and making the client window a son of this newly created window. A window is a wob made by creating a new toplevel X window, reparenting the client window as its child, and framing it with four (optional) {\em bars}, children of the new toplevel window. Note that the inside of a window wob is thus never visible, since it is entirely covered by the bars and the client window. \item[Bar] The only extensible wob, it has a width and an extensible length. It is a line (vertical or horizontal) of bars or {\em plugs\/} centered on the axis of the bar with optional stretchable space between them. Horizontal bars contains vertical bars and vertical bars contains horizontal bars. \item[Plug] The simplest of all wobs, its contents is just a graphic which is displayed in their X window. It acts thus like some kind of button. Current graphics are text and pixmaps. \item[Menu] A bar of bars (horizontal menus consist of a horizontal bar of vertical bars, vertical menus are a vertical bar of horizontal ones). Menus are the only ``stand-alone'' wobs, their windows are directly created by {\GWM} on the screen. They can be used to implement pop-up, pull-down or fixed menus, control panels, message windows and icon boxes. \end{description} \subsubsection{Other GWM objects} Other gwm objects are just X objects (fonts, pixel colors \ldots) that are referenced by their X id, and are accessed via encapsulating {\WOOL} types, such as Numbers or Pixmaps. \section{WOOL objects} {\WOOL} is a lisp interpreter of a special kind, since it has some important design differences from ``real'' lisps: \begin{description} \item[incremental garbage collection] {\WOOL} has a {\sl reference-count\/} driven memory management scheme. This means that the load of memory management is evenly distributed on all phases of computing, thus avoiding the dreadful garbage collection pauses. But, since reference count memory management doesn't work with circular lists, no {\WOOL} function allows the user to do physical replacements on lists\footnote{In fact, some do, but are flagged as ``for experts only'' in the documentation}. \item[no real lists, but arrays] {\WOOL} lists are internally stored as arrays, speeding up list scanning. We do not really need the generality of the chained cells model, since we do not want to have circular lists. \item[monovalued atoms] In classical lisp dialects, you can give a variable and a function the same name without conflict. In {\WOOL}, an atom can only have one value. \item[internally typed objects] All of the {\WOOL} interpreter is written in an object oriented way. This is not visible to the user, since we do not offer a way to define user types, but it greatly improves the modularity of the code, and allows us to provide generic functions, such as the \verb"+" function operating on numbers, lists, or strings. \end{description} {\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: \begin{description} \item[atoms] associates any {\WOOL} object to any other via a hash table. Only one wool object can be referenced, which implies that a \verb"(setq foo1)" assignment will remove any function definition made by \verb"(defun foo ...)". There is {\bf no} limit on the length of atom names. Atom names can be composed of any printable ASCII character except {\tt " ' ( )}, and cannot begin by a digit. \item[active values] are predefined atoms that can be used as atoms or functions. If \verb"foo" is an active value, then \verb"foo" and \verb"(foo)" give the same result, and the calls \verb"(setq foo obj)" and \verb"(foo obj)" have the same effect. Active values are just like other atoms, but setting and evaluating them trigger specific functions to allow for greater expressive power. For instance, just setting a wob's \verb"borderwidth" will actually resize the corresponding X window's border, and declaring a local value for it by a \verb"(with (wob-borderwidth 3) ...)" will actually change the borderwidth of the current wob on the screen during the execution of the \verb"with" body, and then revert to the previous value. \item[numeric variables] are atoms that can only store integer values. Like active values, they can be used as variables or functions. Setting them to \verb"()" or \verb"t" equivalent to setting them to \verb"0" or \verb"1". \item[namespaces] are sets of variable names that have a different value for each state of the namespace. For instance, the most useful namespace is the \verb"screen." one, having one state for each screen. So each name in this namespace, such as \verb"white", can hold a screen-dependent value that will always eval to the correct value relative to the screen. \item[integers] are 32-bit signed integer values. \item[strings] are 8-bit strings of characters, with no size limit. \item[functions] may evaluate or not their arguments and have a fixed or variable parity. \item[fsms] the finite state machines. They are {\WOOL} objects shared by wobs and respond to both X events and {\WOOL}-made events, the so-called ``user'' events. \item[wobs descriptors: plug, bar, menu, client] are used by {\GWM} to build its wobs. \item[X objects: pixmaps, cursors, events, labels] allow X resources to be shared via the {\WOOL} memory management. \item[internal objects] used to improve efficiency (These include collections and quoted expressions). \end{description} \section{Operation} When you start {\GWM}, it: \begin{itemize} \item connects to the display it must manage to initialize its X11 structures \item 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: \begin{description} \item[describe-window] which will be called by {\GWM} to know how to decorate any client window and must return a list of two window descriptors, one for the window itself, and one for the associated icon; \item[describe-screen] which will be called by {\GWM} for each managed screen and must return a window descriptor; \end{description} \item looks to see if it is the only window manager running; if not, it aborts. \item decorates the managed screens by calling the user-defined {\tt describe-screen} function for each one, with the \verb"screen" active value being set to the current screen. \item decorates all already mapped client windows, by calling {\tt describe-window} with the current client window being set to each window. \item executes the (user-defined) opening function for each screen. \item enters {\GWM} main loop, which consists in: \begin{itemize} \item waiting for an X event \item examining the received event, and if it is for an existing wob, sends it to the {\em fsm\/} of this wob, else if it is a new window which is being mapped for the first time, decorates it (by calling {\tt describe-window}) \end{itemize} When an event is sent to a {\em 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. \end{itemize} \section{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: {\exemplefont\begin{verbatim} (plug-make '(label-make window-name)) \end{verbatim}} which creates a plug whose text is fetched as the name of the window on each realization, you do not have to explicitly \verb"eval" a quoted expression. \section{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: \desc{pixmaps}{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. \section{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 {\bf GWM\_EXECUTE} \label{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 {\tt gwmsend} in the contrib/gwmsend directory in the distribution to send commands to {\GWM}. It takes its first argument and puts in the {\bf GWM\_EXECUTE} property on the root window. It can thus be used like: \begin{verbatim} gwmsend '(? "Hello there\n")' \end{verbatim} A better way is to use the \verb|-I| option to make {\GWM} read its standard input for commands. a recommended use is to run not \verb|gwm| directly but a command like: \begin{verbatim} xterm -title gwm -e fep gwm -IP \end{verbatim} \verb|fep| is a pseudo-tty driver which gives its argument line editing and history capabilities, like \verb|ile| or the GNU library \verb|readline|. \section{Using {\tt gwmchat} as a shell to GWM} If you want to communicate with {\GWM} more interactively, via {\WOOL}, you can use the program {\tt gwmchat} (in the contrib/gwmchat directory). Start {\tt 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 {\tt .xinitrc} or {\tt .xsession} or correspondingly, where you normally would start {\GWM}, you may instead have something like: \begin{verbatim} xterm -e gwmchat \end{verbatim} \begin{verbatim} xterm -geometry =80x16-1-1 -e gwmchat -f vtwm \end{verbatim} {\tt gwmchat} can be compiled to use the {\tt readline} package. This is strongly recommended if it is available and if {\tt 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). % Obsolete formulation %\section{Sending commands with {\tt gwmsend} } %If you rather want to send commands to {\GWM} one at a time, or to an %already running {\GWM}, you could use the program {\tt gwmsend}. It takes %a {\WOOL} command as argument and sends it to {\GWM}: %\begin{verbatim} % gwmsend '(? "Hello there\n")' %\end{verbatim} \section{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 {\bf GWM\_RUNNING} property on the root window {\bf and} the hidden window itself. Thus, if this window exists, and has the {\bf GWM\_RUNNING} property set, you can be sure that the screen is managed by {\GWM}.