Background
A fundamental design decision for the X Window system was to permit an arbitrary user-level program to manage the various application windows. This open architecture permits great flexibility in the way windows look and behave.
Window Managers
X Window managers are complex applications. They are responsible for decorating top-level application windows (such as drawing labeled title bars with buttons), permitting resizing and moving windows, "iconifying," tiling, cascading windows, and much more. Many Xlib library functions wrapping the X protocol are specific to the special needs of window managers. Because our goal is to do interesting research beyond that of modern window managers, we used an existing popular window manager—FVWM2—as our starting point. (See http://www.plig.org/xwinman/ for links to other window managers.)
When I began the SCWM project with Maciej Stachowiak in 1997, FVWM2 was arguably the most used window manager in the X Window community. It supports flexible configuration capabilities via a per-user .FVWM2rc file that is loaded once when FVWM2 starts. In order to tweak a parameter, end users edit their .FVWM2rc files using an ordinary text editor, save the changes, and then restart the window manager to activate the change. The FVWM2 configuration language supports a very restricted form of functional abstraction, but it lacks loops and conditionals.
Despite these shortcomings, FVWM2 provides adequate control over the look of windows, and it has evolved over the years to meet complex specifications (such as the Interclient Communication Conventions Manual, or ICCCM) and deal with the innumerable quirks of applications. By basing SCWM on FVWM2, we leveraged those capabilities and ensured that SCWM was at least as well-behaved as FVWM2. Our fundamental change to FVWM2 was to replace its ad-hoc configuration language with Guile/Scheme.
Guile
Guile is the GNU Ubiquitous Intelligent Language for Extension. The GNU project designed it specifically for use as an embedded interpreter. Scheme is a very simple, elegant dialect of the long-popular Lisp programming language. This dialect is easy to learn, and it provides exceptionally powerful abstraction capabilities such as higher-order functions, lexically scoped closures, and a hygienic macro system. Guile extends beyond the standard Scheme language with its module system and numerous wrappers for system libraries (such as POSIX file operations). The implementation of Guile is based on Aubrey Jaffer's SCM Scheme interpreter. Guile is highly efficient and remains under constant development. At the time of this writing, the most recent stable version is Guile 1.3.4.
Constraints
The third important component of SCWM is the Cassowary constraint-solving engine. Window managers are responsible for arranging the various top-level windows on a single shared display. This is essentially a two-dimensional layout problem, and similar problems have benefited from the application of a technology called constraints.
A constraint is simply a mathematical description of a relationship between two objects. It is often a relationship that we desire to hold true. For example, Netscape's Find dialog box often pops up in an undesirable location, therefore hiding the content on the page that you intend to search. A simple constraint that addresses this problem is for the northeast corner of the Find dialog box to stay at the same onscreen location as the northeast corner of the main Netscape browser window. Mathematically, we can write:
NFind.ne.x = NBrowser.ne.x AND NFind.ne.y = NBrowser.ne.y
In this pair of equations, we use NFind and NBrowser to refer to the Netscape Find and Browser windows, respectively. The .ne.x simply refers to the X coordinate of the northeast corner of a window. Similarly, .ne.y refers to the Y coordinate of that corner. Thus, the equations constrain the northeast corners of the two windows to exactly the same location—both the X and Y coordinates must match. Solving this "system" of constraints involves picking actual values for each of the variables in order to maintain the relationship. There are infinitely many solutions to these constraints, one of which is shown here:
NFind.ne.x = 600 NBrowser.ne.x = 600 NFind.ne.y = 250 NBrowser.ne.y = 250
Constraints can involve anything that can be expressed precisely, but in order for them to be solvable, we must restrict how much expressiveness we permit in the constraints we consider. In the above constraints, each of the values being related is simply an integer screen coordinate. Also notice that we are interested in the conjunction of two simpler constraints: that the X coordinates are the same, and that the Y coordinates are the same. As it turns out, conjunctions of equality constraints are especially easy to solve programmatically.
The primary benefit of automatic constraint-solving is that it permits a declarative specification of behavior that we desire. We can simply express what relationships we wish to hold without detailing how those relationships should be maintained. In our Netscape windows example, we can simply list a conjunction of two constraints and leave to the constraint solver the task of continually assigning values to the variables. SCWM does exactly this by embedding the Cassowary Constraint Solving Toolkit. Cassowary implements a sophisticated constraint-solving algorithm that can handle systems of arbitrary linear equalities and inequalities. Our example constraints fall well within the capabilities of Cassowary.
With SCWM, if we add our example constraints to the system and then move the Netscape browser window around the screen, the Find dialog box also moves, keeping its northeast corner coincident with the browser's northeast corner. In contrast, an ordinary window manager would have to do so "imperatively" (or "procedurally") in order to achieve this behavior—for example, by having a snippet of code run whenever the Browser window is moved, and a different snippet of code run whenever the Find dialog box is moved. Each of those code fragments would just move the other window to the appropriate location. Although the procedural approach is tenable for very simple constraints, such as equalities, more sophisticated constraint techniques become necessary when dealing with greater numbers of relationships or more complex relationships, such as inequalities (for example, I want the Find window to stay to the right of my Browser window).
Because you probably do not want to write mathematical equations and inequalities for your window manager in order to lay out your windows, SCWM provides a graphical user interface for specifying a large class of relationships that its Cassowary constraint solver can handle. See the section "User Interface for Constraints" for more information.