Logo Computer scientist,
engineer, and educator

Underneath the Linux desktop

← 2. The X server 4. Desktops and panels →

3. The window manager

The window manager has no privileged status in the X system — it's just an application like any other. There's absolutely nothing to stop other applications fighting the window manager and making its job difficult. At the same time, there's nothing to stop the window manager taking a dislike to a particular application, and always positioning its windows half-way off screen, just to be awkward. In practice, neither applications nor window managers survive very long in the wild if they behave this way.

Window manager history and development

One of the earliest window managers is an application called twm, which is still provided in most modern Linux distributions. The X server, and twm, make a perfectly workable user environment, albeit one that looks pretty clunky by modern standards. If you go back to the virtual X server from the previous example, and have some applications running on screen, you can start twm (or any other window manager) just by doing
twm -display :3
and you should see the windows sudddenly grow decorations. There's a couple of interesting things to note about this. First, the windows are in broadly the same place on screen with, or without, the window manager. A competent window mananger will try not to disturb things more than it has to, but will adjust window positions to accomodate the frame and decorations if necessary. It isn't obvious to the end user, but some fairly complicated stuff goes on behind the scenes to make this happen as it does. Second, if you kill the window manager, the original application windows should remain where they are. This illustrates the independence of the applications from the window manager.

The effect if running xsetroot and then twm on the X server, with client applications still in place. Note that the xclock window has been displaced from its previous position to accommodate the frame

A somewhat more sophisticated window manager was the Motif Window Manager (mwm). This application was based on the proprietary Motif window toolkit, and was never particular significant in the Linux world. However, mwm was essentially the first modern window manager, and it is established a number of conventions that eventually became de-facto standards. For example, even now an application that wants to be displayed full-screen, for example, will use a Motif way of requesting this, and any window manager that does not respect Motif conventions will be lacking some functionality.

Like it or not, many of our ideas about how a graphical user interface should work were crystallized in the 1990s by Microsoft Windows, although Microsoft probably did not originate all these ideas. Until Windows became so dominant, different Unix window managers had radically different approaches to how the user interface ought to behave. For example, it's now almost ubiquitous that to change input focus with a mouse requires the focused window to be at the top of the window stack. But there's no necessary reason why that should be so — there's nothing to stop you typing text into a partly obscured window, for example. But Microsoft Windows standardized the focus-on-top model and also the click-to-focus model, and these have become almost universal in Linux desktops as well. The first 'Windows-like' X window manager was probably Fvwm, which even gave rise to a Windows lookalike called Fvmw95. For good or ill, Linux window manager development has tended to follow the Microsoft approach since the mid-90s, to the extent that the user interfaces are now almost keystroke-compatible. Of course this is good for encouraging Windows users to feel more comfortable with Linux (they're never going to be entirely comfortable, of course), but much of the earlier diversity has been lost. There was a time when everybody with a C compiler wrote a window manager — I've written several myself — and at least a hundred are still available in the open source domain. But a handful of window managers now completely dominate the Linux desktop, and they all look and feel like Microsoft Windows.

Still, non-Microsoft-like window managers do still have a following. There are tiling window managers like xmonad, which strive to keep the whole screen area used at all times without user intervention. They are single-pane window managers like Matchbox which are potentially very effective on small-screen devices. There are minimalist window managers that try to do without captions and decorations, making more screen available for applications. And so on. If there's anything Linux geeks like more than rubbishing Microsoft, it's rubbishing other people's window managers.

Window manager standards and interoperability

The present sitaution is that there are quite a few different, decent window managers available for Linux. In principle, they should all be interoperable with all applications and other desktop components. In practice, they aren't, at least not entirely.

The reason they aren't is that, in reality, the various components of a desktop environment tend to be developed and tested side by side. This wouldn't matter so much if the behaviour of X components was very thoroughly standardised, but it isn't, despite what some enthusiasts would have us believe. There are various standards-like documents such as ICCCM and EWMH (of which, more later) but there two problems here. First, developers do not necessarily implement all the requirements of these documents and, second, even when they do (or try to do) implement everything, there is some ambiguity in the documents.

For all that, given the diversity of the developers and the vagueness of the specifications, there is a fair amount of workable interoperation to be had between different software components — if you understand how they work and are prepared to spend a bit of time tweaking.

Managed and unmanaged windows

It has never been practicable, or even desirable, for the window manager to manage every window known to the X server. For example, menus and buttons may be implemented as individual X windows, but these probably don't need to be managed. An application can set the override redirect flag on its windows, and thereby tell the window manager, and the X server, that these windows are to be left entirely under the application's control. It is possible, in theory, for the application to set the override redirect flag on its main window, and the window manager will generally respect this. But it does make the task of window management difficult, and this isn't recommended. However, transients like splash screens and tooltips might usefully be excluded from window manager influence.

Work area

An important concept in window management is the 'work area'. This is the area of the display which is available to the desktop and applications, and excludes any area taken up by persistent desktop utilities such as panels (docks). Any window, but most commonly a panel, can request that the window manager reserve an area at the edge of the screen for its personal use. Such an area is called a strut. The work area is, essentially, that part of the screen left over after reserving all the struts.

Strut support is an area of the X system that seems to be particularly vaguely described. This is a particular problem for partial struts, which are reserved areas that do not run the whole length or width of the screen. Consequently, the handling of struts is one area that causes particular problems when using desktop components that weren't developed and tested side-by-side.

For example, it isn't clear how the window manager should handle resizeable taskbars and panels. Should the workarea by adjusted when the tasknbar is resized? And should the size of the struct indicate the maximum, or minimum, size of the taskbar? It's worth pointing out that some window managers are very ideosyncratic in their handling of struts and work areas, and consequently work only with a very few other components.

The window manager work area may be implemented as an X window in its own right, which has certain advantages for programmers (see below), but it need not be — it could be nothing more than a virtual construct in the window manager's memory. If it is implemented as a window, then it will obscure the root window, which is one of the reasons utilities like xsetroot don't appear to work on modern systems.

Reparenting window managers

Nearly all modern window managers are reparenting. What this means is that that the window manager reassigns the parent window of each window it manages, to a window that it owns. A typical approach is for the window manager to create a new decocrator X window for each managed window, and put the managed window inside the decorator. The problem with this approach is that, if the window manager crashes, it will probably take all the other application windows with it.

In principle, the window manager could set its decorators to be children of the root window, and then set the application windows to be children of the decorators. In practice, it is nearly always more convenient for the window manager to create the work area window to be a child of the root window, and for the work area then to become the parent of the decorators. This allows the window manager more easily to separate windows that the user can resize from windows that are static, such as desktops and panels.

How the window manager communciates with other clients

Applications communicate with the window manager by means of window properties — either set by themselves for the window manager to read, or set on their windows by the window manager, for other desktop components to read. An important category of properties is window manager hints. These hints are used by the application to tell the window manager how the application would like its windows displayed and managed. In theory a window manager can ignore these hints completely, and do what it likes. In practice, users expect some degree of predictability in the behaviour of their desktops.

For example, an application will set a property called WM_NORMAL_HINTS to specify its windows' maximum and minimum sizes, and resize increments. This propery is so important that even the lowest-level X programming libraries have specific functions to read and write it. The window manager can ignore WM_NORMAL_HINTS, but only at the expense of deeply irritated users. Other properties control other aspects of window management, such as whether the application would like its window centred, and whether a particular window is a transient. A transient window is one that is short-lived, is subordinate to another window, and generally has a highly specific function. A tranient window is called a 'dialog' in the Microsoft Windows world, and that terminology has become widespread in X programming as well. However, unlike in Windows, an X window manager is not obliged to treat a transient in a particular way. In practice, it usually will by, for example, ensuring that transient is always on top of its owner in the stacking order.

The complexity of window managers and other desktop components has increased outside the scope of any of the original X standards, however. There is now a whole new set of window properties dedicated entirely to the interaction between desktop components. These properties are defined by the EWMH (extended window manager hints) document, and usually have names beginning with _NET_WM. One of the most signicant of these properties is _NET_WM_WINDOW_TYPE. In the days when Motif was the height of X technology, there were really only two 'kinds' of windows: ordinary windows that could be operated by the user, and icons. A window was either one or the other. These days, there are dozens of other kinds of window: panels, taskbars, desktops, tooltips, splash screen, dialogs, etc. If the window manager knows that a window is intended to have one of these purposes, then it can be managed in a helpful way.

For example, a window that is intended to work as a taskbar — that is, to provide a way for the user to get access to other applications — probably should be kept visible on screen. If you can't even find the taskbar, then it's not going to serve its primary purpose. Similarly, a dialog window probably should not be decorated the same way as an ordinary window — very often it doesn't make much sense to minimize (iconize) such a window, for example, and the window manager won't provide user controls to do this.

The window manager is entirely at liberty to ignore _NET_WM_WINDOW_TYPE property, and sometimes must. For example, there is nothing in the EWMH document to dictate what should happen if two different applications register themselves as a desktop. There are specific window messages intended to apply to the desktop window, and they don't really make much sense if there is more than one. The Metacity window manager, for example, will respect the request of any window to be a desktop to the extent that it will not decorate the window, or provide any method for the user to move or size it. But only the first such window created wil be treated as the desktop, and respond to 'show desktop' messages.

Window properties example

It might be instructive at this stage to look at some specific examples of how window properties are used. If you've followed the examples up to now you might have the twm window manager running. If so, have a look at the properties set on the root window, by doing:
$ xprop -display :3 -root
(remember to substitute the display number you used when you started Xvnc).

You'll find the output will be pretty sparse, because the ancient twm does not support the modern de-facto standards for interoperability. So it's time to start a more modern window manager. Anything developed in the last five years or so should do. If you use, or have acceess to Gnome, you probably have the metacity window manager, which is a good one to use for this example. You'll also find that xclock is not a particularly helpful utility to experiment with here, for exactly the same reason. So in what follows I'm using the gnome-calculator application. Anything reasonably modern that creates a window should work fine.

$ killall twm
$ metacity -display :3 &
$ gnome-calculator --display :3 &
Assuming it starts up correctly (and your window decorations reappear), try queying the root window again. You should get reams of output, which I won't reproduce here except for the essentials.

_NET_WORKAREA(CARDINAL) = 0, 0, 1024, 768, 0, 0, 1024, 
  768, 0, 0, 1024, 768, 0, 0, 1024, 768
This property has been set by the window manager on the root window to tell other desktop components how large its work area is. Because the work area can occupy any rectangular part of the screen, the coordinates of all four corners must be given. The window manager will update this property if it has reason to resize its own work area. Note that in this example there are no other desktop components in use, so the size of the work area (1024x768) is the same as the size of the screen (the Xvnc virtual screen, that is).

_NET_ACTIVE_WINDOW(WINDOW): window id # 0x200007
The window manager sets this property to indicate the window that currently has input focus, if any. This ID, 0x20000e, corresponds to the gnome-calculator window we started earlier (more on its own properties later). Pagers and task managers will read this property to determine which application is currently active, so that this information can be reflected in their own displays.
_NET_CLIENT_LIST(WINDOW): window id # 0x200007, 0x60000e
This is the window manager's list of windows that it is currently managing. In this case there are two: 0x200007 is gnome_calculator and 0x60000e is xclock. There's no way to determine this information from the root window — we need to query the individual windows (more later).
_NET_NUMBER_OF_DESKTOPS(CARDINAL) = 4
_NET_CURRENT_DESKTOP(CARDINAL) = 0
_NET_DESKTOP_GEOMETRY(CARDINAL) = 1024, 768
_NET_DESKTOP_VIEWPORT(CARDINAL) = 0, 0
These properties are used to communicate virtual desktop (paging) information. The window manager is saying that it currently supports four virtual desktops of which the first (0) is currently active. The virtual desktop size if 1024x768 and the displayable desktop is positioned at 0,0 in the virtual desktop. In this case, the virtual desktop is the same size as the displayable desktop. In practice, desktop viewports (the ability to select a specific part of a larger desktop) are rarely used much these days as screen resolution has improved so much in the last ten years. But paging — the ability to maintain several desktops — is still very important. Typically the window manager will manage paging by setting the off-screen windows to have coordinates outside the range the X server can display.
_NET_SUPPORTED(ATOM) = _NET_WM_NAME, _NET_CLOSE_WINDOW, _NET_WM_STATE, 
  _NET_WM_STATE_SHADED, _NET_WM_STATE_MAXIMIZED_HORZ, .... 
A list, usually a very long list, of all the extended protocols that the window manager supports.

So much for the Window manager, but what about the applications? Let's have a look at the window whose ID is 0x200007 in the above output.

% xprop -id 0x200007 -display :1
Again, the output will be extensive, and I'll only highlight the most significant parts here.
_NET_WM_STATE(ATOM) = WM_STATE(WM_STATE): window state: Normal
The window manager sets this property on a window to indicate how it is currently displayed: normal, maximized, modal, etc. In this case the state is 'normal', the meaning of which should be pretty obvious.
_NET_WM_ALLOWED_ACTIONS(ATOM) = _NET_WM_ACTION_MOVE, _NET_WM_ACTION_RESIZE, ..._
A list of all the actions that the window manager is prepared to take on the current window. Typically a window will be prepared to move, resize, and change the stacking order of normal windows. But it may not wish to hide or restack a window that has asked to be displayed in a modal state, or resize a window that has asked to have a fixed size. This property is typically read by taskbars and similar interface management utilities.
_NET_WM_WINDOW_TYPE(ATOM) = _NET_WM_WINDOW_TYPE_NORMAL
This property is set by the application on its own window(s), to tell the window manager how it would like to be managed. The use of this property allows an intermediate position between the extremes of full management (the window manager does whatever it likes) and override-redirect (the window manager does nothing). The type of this window is 'normal', which typically means that the window manager will allow the user to move and resize it freely, and give it no special treatment. But this property could also be set to indicate that the window is a desktop, or a dialog, or a panel, in which case it would be treated differently by the window manager.

It's interesting and slightly shocking to developers who are used to the Microsoft Windows platform that the primary parts of the desktop environment have absolutely no special status, and are just ordinary windows. Their specific role comes about purely because the window manager agrees to respect an application's request for a window to be treated in a different way.

WM_NORMAL_HINTS(WM_SIZE_HINTS):
                program specified location: 0, 0
                program specified minimum size: 292 by 329
                window gravity: NorthWest
Note that this is not one of the extended properties, but a traditional X property with a long history. It is set by the application on its window(s) to tell the window manager how it would like to be positioned and sized. In this case the application has set a minimum size but no maximum size. The window manager will try to prevent the user making the window smaller than the minimum size. If the application asks for the minimum and maximum sizes to be equal, the window manager will typically respond by drawing the window border differently, to make it clear that the window can not be resized. The location in this example is (0,0) and yet you'll notice that the window is almost certainly not at (0,0) on the screen. This is an example of the window manager being free to ignore client hints. In this case, as this is a 'normal' window, the user almost certainly wants to have the window manager position the window in a helpful place, not in the top-left corner. Had the window been a tooltip or a desktop, for example, the window manager would almost certainly have respected the position request.
WM_NAME(STRING) = "Calculator"
_NET_WM_NAME(UTF8_STRING) = 0x43, 0x61, 0x6c, 0x63, 0x75, 0x6c, 
  0x61, 0x74, 0x6f , 0x72
X predates the widespread use of Unicode, so the traditional property WM_NAME is set by the application to give its name in ASCII characters. The extended property _NET_WM_NAME gives the Unicode equivalent. The window manager and other desktop components will use this name in window frames and menus, and will usually take the Unicode version if it has been set.
WM_CLIENT_MACHINE(STRING) = "tommy"
_NET_WM_PID(CARDINAL) = 5220
The hostname of the computer running the application, and the process ID of the application on that host. If the application indicates that it is willing to take part in the 'ping' protocol, by which the window manager can determine if it is responding to events, then the window manager is allowed to kill the unix process if the application appears to be hung. This is one area of the X system where it does actually matter what the network organization is: the window manager will not be able to kill a process which is not hosted on the same machine as itself. It's hard to imagine a practical situation, however, where the window manager and the applications it manages are not on the same host.

Compositing

Compositing is the process of building up an image from a number of independent layers. In the X system, compositing means arranging for windows to draw their contents into off-screen buffers, so that they can be recombined in more elegant and useful ways. In the traditional X server model, drawing to a screen window that is obscured by another window has absolutely no effect on the server. The data written by the application is lost. Consequently, visual effects like transparency have been very difficult to achieve in X.

With compositing, each window draws its output to a separate buffer. The buffers are then combined, applying whatever transparency, shadowing, etc., is required. This process is carried out as a collaboration between the X server and a compositing manager. The compositing process can be accelerated by the video adapter if the X video driver supports it. As well as simple overlaying of window contents, the compositing manager is free to distort the window output however it sees fit. This is what makes it possible to produce the notorious 'wobbly windows' and exploding dialog boxes the Linux users like to show off.

Compositing is typically done by the window manager, although it's perfectly possible to get basic effects such as transparency using a stand-alone compositing manager, such as xcompmgr. Nearly all modern window maangers have some degree of compositing support.

Modularizing the window manager

In the early days of X, the window manager was the X desktop. All desktop operations other than the applications themselves were carried out by the window manager — popping up menus, launching applications, managing iconified windows, etc. As time went by, it became expedient to split these roles out into separate applications — desktops, panels, launchers, etc. But more recently window managers have expanded in complexity, particularly with the increase in support for compositing. As a result, a recent development has been to split window management itself into separate processes. For example, the basic management of the windows — their size and position, for example — is in principle independent from the user interface needed to effect this management. So increasingly we are seeing window managers delegate the user interface to any independent window decorator. The decorator draws the window frame and user interface elements, and may make use of various theme engines, allowing applications and window managers to share a user interface look-and-feel. This has traditionally been a bugbear of the X desktop: the menus and buttons drawn by the window manager have typically been independent of those drawn by applications, leading to a visual inconsistency. One solution to this problem is to use the same graphical toolkit to implement the window manager as applications typically use: GTK, Qt, etc. The problem here is that such toolkits are intended for developing applications, not infrastructure, and subverting them for use this way tends to be very ugly. There are also problems with resource (typically memory) usage, although these are probably less important these days.

The use of stand-alone window decorators goes some way to addressing these problems, and makes it possible, in principle to make quite radical changes in look-and-feel without changing the basic window management logic.

← 2. The X server 4. Desktops and panels →

Copyright © 1994-2013 Kevin Boone. Updated Jul 30 2010