Download as pdf or txt
Download as pdf or txt
You are on page 1of 13

How X Window Managers Work, And How To Write One (Par... https://seasonofcode.com/posts/how-x-window-managers-wo...

How X Window Managers Work, And How To


Write One (Part I) (https://seasonofcode.com
/posts/how-x-window-managers-work-and-
how-to-write-one-part-i.html)
By Chuan Ji | Apr 10, 2014 |
Tags: Featured (https://seasonofcode.com/tag/featured.html), Window Manager (https://seasonofcode.com/tag/window-
manager.html)
|
Comments (2) (https://seasonofcode.com/posts/how-x-window-managers-work-and-how-to-write-one-part-
i.html#disqus_thread)

Series Contents

Part I: Basic Concepts (/posts/how-x-window-managers-work-and-how-to-write-one-part-i.html)

Part II: Introduction, Setup & Teardown, Initialization, Event Loop (/posts/how-x-window-
managers-work-and-how-to-write-one-part-ii.html)

Part III: Interaction with Application Windows (/posts/how-x-window-managers-work-and-


how-to-write-one-part-iii.html)

Window managers are one of the core components of the modern Linux/BSD desktop. It is not an
exaggeration to say that they dene to a large degree our day-to-day user experience, as they are
responsible for deciding how individual windows look, move around, react to input, and organize
themselves. Hence, almost 30 years since the rst X window manager (http://en.wikipedia.org
/wiki/Ultrix_Window_Manager), we still argue over the merits of dierent window managers, and new
window managers continue to reinvent how we interact with our digital world.

In this series of posts, I hope to demystify how window managers work, and how you might go about
writing one yourself.

I will be quoting quite heavily from the seminal Xlib Programming Manual (3rd Ed, 1994)
(http://www.amazon.com/Programming-Manual-Version-Denitive-Guides/dp/1565920023) by Adrian
Nye and published by OReilly. Despite its age, it remains amazingly relevant and is the best available
introductory text to the internals of X, which has not changed over the past two decades as much as
youd think. Since you could buy the book plus shipping for less than the price of a cup of coee, I
strongly recommend it to anyone interested in learning more about X. In addition, its chapter 16 also
covers the basics of window management.

The Role of an X Window Manager


2011-2017 Chuan Ji

1 of 13 10/04/17 15:39
How X Window Managers Work, And How To Write One (Par... https://seasonofcode.com/posts/how-x-window-managers-wo...

Lets start with an examination of the role of the window manager in a modern Linux/BSD desktop
environment.

The Rights of X Window Managers


Unlike other windowing systems such as Microsoft Windows or Mac OS X, X does not dictate a window
manager or how a window manager should behave. This decision is to thank for the wild diversity of X
window managers we see today.

X is somewhat unusual in that it does not mandate a particular type of window manager.
Its developers have tried to make X itself as free of window management or user interface
policy as possible.

Xlib Programming Manual 1.2.3

In fact, it does not even require a window manager to be present at all:

Unlike citizens, the window manager has rights but not responsibilities. Programs must be
prepared to cooperate with any type of window manager or with none at all [].

Xlib Programming Manual 1.2.3

This is in stark contrast to the integrative approach of other GUI systems. On Mac OS X and Unity
(https://unity.ubuntu.com/), for example, an application could not possibly function without the window
manager, as the latter is responsible for rendering a part of the applications interface (e.g., menus).

The Responsibilities of X Window Managers


As you probably already know, X operates in a server-client model. An X server controls one or more
physical display devices as well as input devices (mouse, keyboard, etc.). An application that wants to
interact with these devices assumes the role of an X client. An X server and its clients may run on the
same computer, in which case they communicate via domain sockets (http://en.wikipedia.org
/wiki/Unix_domain_socket), or on dierent computers, in which case they communicate through TCP/IP.

A window manager is a regular X client. It doesnt have any superuser privileges or keys to kernel
backdoors; it is a normal user process that is allowed by the X server to call a set of special APIs. X
ensures that no more than one window manager is running at any given point by denying a client access
to these APIs if another client currently has access. The rst client to attempt to access these APIs always
succeeds.

A window manager communicates with the windows it manages through two X mechanisms: properties
and events. We will discuss these in detail in later sections, but the takeaway is that the communication
happens through the X server, not directly between the window manager and other applications.

This is illustrated by the following diagram:

2 of 13 10/04/17 15:39
How X Window Managers Work, And How To Write One (Par... https://seasonofcode.com/posts/how-x-window-managers-wo...

How an X Window Manager Manages Windows


Lets now dive into the details of how a window manager does its job.

The Window Hierarchy


When we think about modern GUIs, we usually use the term widgets or controls to refer to UI elements
such as buttons, scrollbars, or text boxes, and the term windows to refer to a container for such widgets
that has its own name and can be independently moved around, closed, resized, etc..

X, however, was designed to be as low-level as possible. The fundamental UI model that X provides, upon
which UI frameworks such as GTK+ (http://www.gtk.org/) and Qt (http://qt-project.org) are built, is that of
an hierarchy of rectangles. In X terminology, all top level windows and all UI elements within are windows.
In other words, a window, is any rectangular area that is an unit of user interaction and/or graphic
display.

Windows are organized into a tree hierarchy. At the root of the hierarchy is the root window, a virtual,
invisible window that has the same size as the screen, and is always present. Top level windows are direct
children of the root window. UI elements within a top level window are descendants of that window.

3 of 13 10/04/17 15:39
How X Window Managers Work, And How To Write One (Par... https://seasonofcode.com/posts/how-x-window-managers-wo...

For example, consider the dialog box above from the Xfce (http://www.xfce.org/) desktop environment.
The entire dialog is an X window. All UI elements in the dialog box - the magnifying glass icon, the text
box, the green down arrow, the Close and Launch buttons, and the icons inside those buttons - are also X
_window_s.

The whole dialog window is a child of the root window. The magnifying glass icon, the text box, and the
Close and Launch buttons are children of the dialog window. The green down arrow is a child of the text
box window, and the icons in the Close and Launch buttons are children of those buttons respectively.

An important thing to note about X windows is that a child window is clipped to the boundaries of its
parent:

A child may be positioned partially or completely outside its parent window, but output to
the child is displayed and input received only in the area where the child overlaps with the
parent.

Xlib Programming Manual 2.2.2

For example, if we increase the width of the text box in the dialog above by 2x without changing the size
of the dialog box, the portion of the text box that extends outside of the dialog box will become invisible,
and clicking on it will not send an event to the text box.

A window manager manages top level windows - that is, direct children of the root window.

Substructure Redirection
In the absence of a window manager, when an application wants to do something with a window - move
it, resize it, show/hide it, etc. - its request is directly processed by the X server, and thats the end of that.
A window manager, however, needs to intercept these requests. For example, a window manager may
need to know that a new top level window has been created and displayed, in order to draw window
decorations (e.g. minimize / maximize / close buttons) around it. It may also need to know that an
existing top level window has been resized, in order to redraw the window decorations to reect the
change.

The mechanism that allows a window manager to intercept such requests is called substructure
redirection.

This is how substructure redirection works. Suppose we have a window W. If a program M registers for
substructure redirection on W, a matching request to modify any direct child window of W will not be
executed by the X server. Instead, the X server redirects this request to the program M, which can do

4 of 13 10/04/17 15:39
How X Window Managers Work, And How To Write One (Par... https://seasonofcode.com/posts/how-x-window-managers-wo...

whatever it wants with the request, including denying the request outright or granting the request with
modications. More formally,

The structure, as the term is used here, is the location, size, stacking order, border width,
and mapping status of a window. The substructure is all these statistics about the children
of a particular window. This is the complete set of information about screen layout that
the window manager might need in order to implement its policy. Redirection means that
an event is sent to the client selecting redirection (usually the window manager), and the
original structurechanging request is not executed.

Xlib Programming Manual 16.2

Note that only direct children of a window W is aected by substructure redirection on W, not any
windows further down the hierarchy.

This gets interesting when we consider substructure redirection on the root window:

When the window manager selects SubstructureRedirectMask on the root window, an


attempt by any other client to change the conguration of any child of the root window
will fail. Instead an event describing the layout change request will be sent to the window
manager. The window manager then reads the event and determines whether to honor
the request, modify it, or deny it completely. If it decides to honor the request, it calls the
routine that the client called that triggered the event with the same arguments. If it
decides to modify the request, it calls the same routine but with modied arguments.

Xlib Programming Manual 16.2

In other words, a window manager must register for substructure redirection on the root window, which
causes all creation, destruction, reconguration etc. of top level windows - which are direct children of
the root window - to be routed to the window manager. This is the magic hook into the X server that
window managers rely on to do their job.

This relationship is shown in the following diagram:

5 of 13 10/04/17 15:39
How X Window Managers Work, And How To Write One (Par... https://seasonofcode.com/posts/how-x-window-managers-wo...

Finally, the X server only allows one running program to register for substructure redirection on any
given window at any given time. An attempt to register for substructure redirection on a window will fail if
another X client has already done the same on the same window, and has not unregistered,
disconnected from the X server, or crashed. Since all window managers must register for substructure
redirection on the root window, this latter acts as a locking mechanism that prevents two or more
window managers from running simultaneously on the same screen.

Reparenting
In the example dialog box above, we see a title bar with, for example, little buttons for minimizing,
maximizing, and closing the window. These UI elements are not created by the application, but by the
window manager, via a process known as reparenting or framing:

A window manager can decorate [top level] windows on the screen with titlebars and
place little boxes on the titlebar with which the window can be moved or resized. This is
only one possibility [].

To do this, the window manager creates a child of the root somewhat larger than the top
level window of the application. Then it calls XReparentWindow()
(http://manpages.ubuntu.com/manpages/en/man3/XReparentWindow.3.html), specifying
the top level window of the application as win and the new parent [window it just
created] as parent . win and all its descendants will then be descendants of parent .

Xlib Programming Manual 16.3

In other words, if we were to run an X application without a window manager present, the top level
window of the application would be a direct child of the root window. With a window manager running,
however, the top level window of the application may be reparented by the window manager; it becomes
a child of a frame window which is created by the window manager, and which is itself a direct child of
the root window. The window manager can add other UI elements inside this frame window alongside
the applications top level window as it sees t.

Therefore, Ive kind of lied to you several paragraphs ago: the dialog box shown earlier is really a child
window within a frame window created by Xfce (http://www.xfce.org)'s window manager, Xfwm, along
with other UI elements for window management:

6 of 13 10/04/17 15:39
How X Window Managers Work, And How To Write One (Par... https://seasonofcode.com/posts/how-x-window-managers-wo...

Reparenting is what allows dierent window managers to draw dierent window decorations, and
thereby achieve a consistent look-and-feel across windows. However, there are also window managers
that do not reparent at all: these are called non-reparenting window managers. There are two reasons
why a window manager would not want to reparent:

1. If a window manager does not draw window decorations around top level windows , it obviously
has no need to reparent them. Examples: xmonad (http://xmonad.org), dwm
(http://dwm.suckless.org).

2. Compositing window managers do not always need to reparent windows; we will discuss why
below. Example: Compiz (http://www.compiz.org/). This is not true for all compositing window
managers, however; for example, GNOMEs default window manager, Mutter (http://github.com
/GNOME/mutter/), is a reparenting comopositing window manager.

Lets now consider substructure redirection in the context of reparenting. When a top level window W is
rst shown (map'ped in X jargon), the window manager is notied because it has registered for
substructure redirection on the root window, and a top level window is a direct child of the root window.
It then creates a frame F and reparents W, so that W becomes a child of F, which itself is a child of the root
window. But since now W is no longer a direct child of the root window, the window manager will no
longer be able to intercept changes to W!

Therefore, a reparenting window manager must also subsequently register for substructure redirection
on each frame window it creates.

Compositing
Compositing window managers are a relatively new development. Compositing support in X was added
in late 2004, a full decade after the last edition of Xlib Programming Manual (http://www.amazon.com
/Programming-Manual-Version-Denitive-Guides/dp/1565920023). The rst compositing window

7 of 13 10/04/17 15:39
How X Window Managers Work, And How To Write One (Par... https://seasonofcode.com/posts/how-x-window-managers-wo...

managers, Xfwm (http://www.xfce.org) and Compiz (http://www.compiz.org/), launched in early 2005.

So, what exactly does a compositing window manager do?

In our discussion above on substructure redirection and reparenting, we saw how a window manager can
respond to various requests for a top level window - to display/hide it (map/unmap in X jargon), to resize
it, to move it, etc.. But we didnt talk about how to deal with whats inside the top level windows.

Indeed, from the perspective of the window manager, top level windows are black boxes; they each
manage their own descendant windows (UI elements), perhaps through a framework such as GTK+
(http://www.gtk.org) or Qt (http://qt-project.org/), and the window manager has no right to interfere
there. The application that creates a top level window is responsible for rendering and handling events
for any descendant windows (UI elements), and does so directly through X. This is shown in the rst
diagram above.

As the computing power of graphics hardware grew, so did peoples expectations from their window
managers. With hardware acceleration, it became possible to build much more computationally intensive
user interfaces, such as the (in)famous Desktop Cube in Compiz (http://www.compiz.org):

or the Shift Switcher:

8 of 13 10/04/17 15:39
How X Window Managers Work, And How To Write One (Par... https://seasonofcode.com/posts/how-x-window-managers-wo...

Lets take a moment to think about how we can implement an interface such as the Shift Switcher above.
When the user triggers this interface, we need to:

1. Render each top level window and all its descendant windows (UI elements) to an o-screen,
in-memory buer, instead of directly to the hardware.

2. Transform (rotate, contort, etc.) each buer according to our design.

3. Composite the transformed buers into a nal buer along with a background and any other
oating UI elements else we need to display.

4. Create an overlay window that covers the entire screen and hides all other windows.

5. Render the nal buer into the overlay window.

There are a number of challenges:

We must be able to retrieve the displayed contents of top level windows. However, as we described
earlier, top level windows render their contents directly through X, without going through the
window manager.

We need to update our interface in real time as the contents of the top level windows change.
However, top level windows do not notify window managers when their contents change, again
because they render their contents directly through X.

A top level window A may overlap with another top level window B below, which means a portion of
B isnt currently displayed. Our interface, however, must capture the full rendering of A and B,
regardless of overlapping regions.

All this complex compositing process is computationally intensive and requires hardware
acceleration to function adequately.

It is clear that none of this would be possible without some heavy cooperation from the X server. Enter
the Composite extension (http://cgit.freedesktop.org/xorg/proto/compositeproto

9 of 13 10/04/17 15:39
How X Window Managers Work, And How To Write One (Par... https://seasonofcode.com/posts/how-x-window-managers-wo...

/tree/compositeproto.txt):

Many user interface operations would benet from having pixel contents of window
hierarchies available without respect to sibling and antecedent clipping. In addition,
placing control over the composition of these pixel contents into a nal screen image in
an external application will enable a exible system for dynamic application content
presentation.

X Composite Extension

The Composite extension provides a mechanism to request the X server not to render a specic window
and its descendants directly to hardware, but to a special buer maintained by the X server, and do so
without the normal clipping and overlap computations. This buer can then be read and used by the
client that made the request.

Thats exactly what a compositing window manager does: it will ask X to render each top level window to
an o-screen, in-memory buer and composite the results into an overlay window itself. And it needs to
do this not just for fancy task switcher interfaces as in our example, but also to achieve eects like
translucency, animations, soft shadows, and the like.

This is illustrated in the following diagram:

10 of 13 10/04/17 15:39
How X Window Managers Work, And How To Write One (Par... https://seasonofcode.com/posts/how-x-window-managers-wo...

Lets end this section by considering whether a compositing window manager should reparent top level
windows.

Since a compositing window manager already knows the size and position of all top level windows, its
easy for it to just draw window decorations during compositing into the overlay window using graphics
operations (e.g. OpenGL), without ever creating an actual X frame window and reparenting. Some
compositing window managers do operate this way.

On the other hand, a window manager may need to support both a compositing and a non-compositing
mode, for compatibility with older or unsupported graphics hardware. In this case, it needs to implement
reparenting and frame windows for non-compositing mode anyway, so additionally implementing
drawing window decorations using graphics operations becomes redundant. This is why may other
compositing window managers still choose to reparent.

Ready For Some Code?


If youve read everything up to this point, youre probably holding back the urge to cry out "Enough talk -
show me some code!" I dont blame you.

In the next installment (/posts/how-x-window-managers-work-and-how-to-write-one-part-ii.html) in this

11 of 13 10/04/17 15:39
How X Window Managers Work, And How To Write One (Par... https://seasonofcode.com/posts/how-x-window-managers-wo...

series, I will walk you through a basic implementation of a reparenting, non-compositing window
manager. Impatient? Check out the code on GitHub (https://github.com/jichu4n/basic_wm)!

Next chapter: How X Window Managers Work, And How To Write One (Part II) (/posts/how-x-
window-managers-work-and-how-to-write-one-part-ii.html)

Series Contents

Part I: Basic Concepts (/posts/how-x-window-managers-work-and-how-to-write-one-part-i.html)

Part II: Introduction, Setup & Teardown, Initialization, Event Loop (/posts/how-x-window-
managers-work-and-how-to-write-one-part-ii.html)

Part III: Interaction with Application Windows (/posts/how-x-window-managers-work-and-


how-to-write-one-part-iii.html)

By Chuan Ji | Apr 10, 2014 |


Tags: Featured (https://seasonofcode.com/tag/featured.html), Window Manager (https://seasonofcode.com/tag/window-
manager.html)
|
Comments (2) (https://seasonofcode.com/posts/how-x-window-managers-work-and-how-to-write-one-part-
i.html#disqus_thread)
| Permalink (https://seasonofcode.com/posts/how-x-window-managers-work-and-how-to-write-one-part-i.html)

About the author


I am a software engineer by profession and a passionate technology geek
in my free time.

jichu4n (https://github.com/jichu4n) @jichu4n


(https://twitter.com/jichu4n) Chuan Ji (https://www.linkedin.com

(https://plus.google.com /in/chuanji) Chuan Ji (https://plus.google.com


/115396580584561637180) ji@chu4n.com
/115396580584561637180)
(mailto:ji@chu4n.com)

12 of 13 10/04/17 15:39
How X Window Managers Work, And How To Write One (Par... https://seasonofcode.com/posts/how-x-window-managers-wo...

2 Comments season of code


1 Login

Sort by Best
Recommend 2 Share

Join the discussion

Omar Moya 2 years ago


Hi Chuan Ji, amazing tutorial. Im learning a lot from this, but i have a question... in xcb, how should i
do the substructure redirect mask stuff to get my wm working not as an application but as a real and
only wm ?
Reply Share

Daxx10 2 years ago


Crystal clear writing, thank you.
Reply Share

ALSO ON SEASON OF CODE

Announcing AsciiDocLIVE Custom Domain E-mails With Postfix and


4 comments 3 years ago Gmail: The Missing Tutorial
Chuan Ji The site has been fixed - very 19 comments 2 years ago
sorry for the inconvenience. Mobi Cycle http://icarobichir.com.br/u...

How To Set Default Fonts and Font Aliases The Most Popular Fonts On The Web: A
on Linux Study
10 comments 3 years ago 1 comment 3 years ago
Lazza > Fonts like Times basically ignore Shannon Thanks, I was looking for just
that min-size preferenceThey don't. I think you these stats.
might be confused by the different x-height of

Subscribe d Add Disqus to your site Add Disqus Add Privacy

13 of 13 10/04/17 15:39

You might also like