You are currently reading post #48. Go to the main index.

"Using the new Devil’s Pie s-expression configuration"

1. Overview

Devil’s Pie is a nice utility which can apply various properties on the fly to your desktop windows. Until version 0.13, it used an XML config file. After, it switched to s-expressions, and seriously lacked documentation. This is an attempt to clear the mist.

Many thanks to Ross Burton, the creator, for Devil’s Pie itself, and because he was glad to help me.

I won’t insist on the old XML configuration, because that’s all gone now. 0.13 was a complete rewrite.

2. Introduction to the X desktop

For those readers who are not familiar with the quirks of the X desktop, here’s a short introduction.

2.1. The X server

The graphical desktop which people use on operating systems such as Linux or BSD is based on a master application called “X Window”, or “X server”. By itself, the application doesn’t do much: it simply makes it possible for other applications to use the graphics card in your computer.

We gotta have certain things for a desktop to be usable. At the very least we need a desktop background and windows.

2.2. Workspaces aka virtual desktops

X differs from other graphical desktops (such as Microsoft Windows) in that it natively provides one more thing: workspaces, aka “virtual desktops”. This means that instead of having one single desktop, you can have as many as you’d like. I have 5, for instance.

Each workspace has a number (1-5) and it can hold completely different applications. I can switch between them at will, and I can move windows among them. It can be quite useful once you get used to the concept: you can use one workspace for browser windows, one for terminal windows, one for the image editor and browser, one for the music player, and so on.

2.3. The window manager

The essential stuff, like the background and windows, are handled by another special application running on top of the X server, which is called a window manager.

A window manager creates, decorates and manages windows. As graphical applicatons start, they ask the manager for a window, and it provides one according to their specifications. The application runs inside the window, and the manager will take care of stuff such as moving the window, switching between windows, minimizing and maximizing, and so on. It will talk to the application inside the window at all times, so the window is in sync with the application.

Here’s a nice collection of windows managers.

2.4. Window properties

At any given moment, a window will have a lot of properties.

Some of them are obvious: position, size, title, what kind of buttons it has active.

Some of them are less obvious, but easy to understand once you think about it: maximized, minimized, focused.

Some of them are also easy to understand, but are specific to X and you may not have seen them before: shaded (the window keeps only its title bar and hides the rest), pinned aka sticky (appears on all workspaces at once), undecorated (only shows the central part of the window, and hides all the borders and bars and buttons), always on top/bottom (will stay like this in spite of which window has focus).

And then there are some of them which are never obvious, even though they are very important and often used. These are special window modes, which are used internally by the window manager. You won’t have to bother with them, since changing these states is not allowed for the user, only the application decides what they should be, internally, and the window manager obeys. If you must have an example, here it is: modal windows, such as the “open file” dialog; such a window is special in several ways — it is groupped with the “main” window of the application, but while it is open you can’t focus the main window, and closing it won’t close the application, only the file window.

3. How Devil’s Pie works

Devil’s Pie belongs to a category of applications called “window matching utilities”. Their job is to run in the background, match windows based on certain properties, and apply certain actions to them.

Naturally, you need to: start devilspie (the application) when X starts, and to tell it where to take all the configuration from (match codes and actions).

3.1. Configuration files

It’s important to note that, since version 0.13, Devil’s Pie needs several config files. The reason is that each file can only hold one (1) window matching definition. (This is expected to change in the future.)

So the trick is to create a central directory, such as ~/.devilspie, and put all the definitions there, each in its own file. You can give them intuitive names.

By default, Devil’s Pie will look for ~/.devilspie and load all files ending with the extension .ds.

Note: This is quite different from how pre-0.13 version used to work. Before 0.13, there was only one central config file (~/.devilspierc), which contained XML. There are now several configuration files, containing one s-expression each. See below for an introduction to s-expressions.

3.2. Starting when X starts

Most often, you can add devilspie to your ~/.xinitrc or ~/.Xsession file. Here’s how the line should look:

devilspie ~/.devilspie/*.ds &

Or just the following, which is by default the equivalent of the above:

devilspie &

3.3. What it does

Devil’s Pie will load your config files and learn your preferences. Basically, you tell it what windows it should take care of, and what it should do with them.

It recognizes windows based on a limited range of characteristics. We’re talking about things such as their titles here. Sorry, it doesn’t do stuff like “take the window that is on workspace 3, near the top-left corner, and focused”. That’s too complicated. Besides, recognizing windows by name is plenty useful as it is.

Once it recognizes a window, it will do stuff to it. Here you have a lot more things to choose from. Almost all the things that can be done to a window can be applied via Devil’s Pie. It depends on you to imagine cool tricks to do.

3.4. Disabling a config file

You can either edit the file and add a semicolon (;) in front of the s-expression, or rename the file so it doesn’t end in .ds anymore, or move it to another directory.

4. S-Expressions

4.1. Introduction to s-expressions

Devil’s Pie now uses its config files to load s-expressions. Emacs users probably know what that is, but the rest of the world doesn’t. An s-expression is an expression written with a lot of round brackets, which makes a condition and decides what to do if it is met.

4.2. Basic s-expression example

Here’s an example:

(if (is (window_name) "XMMS") (set_workspace 2))

Such an expression is evaluated from the inside-most and left-most set of brackets, to the right and outside. They usually are formed like this:

(if (condition) (action))

Here’s the above example, explained:

  • window_name: this is one of four (4) window properties that Devil’s Pie can examine (we’ll see which later). It evaluates to a short text, such as “XMMS”, or “tvtime [10]: zoom zoom zoom”.
  • "XMMS": a text to match the window property against.
  • (is (window_name) "XMMS"): this is the main condition: it says that the application name should match the text exactly.
  • (set_workspace 2): the action that should be taken, if the condition is met. This one will send the matching windows to the 2nd workspace.

4.3. Logical operations

The logical operations are the methods which you use to compare window properties to your own texts. There’s three (3) of them currently:

  1. is: the text must be identical to the value of the property;
  2. contains: the text must be contained at least once inside the value of the property;
  3. matches: the text contains a regular expression which will be applied to the value of the property (see below for a very small explanation regarding regular expressions).

4.4. Matchers aka matching window properties

Matchers are window properties you can use to identify windows with. There’s currently four (4) of them:

  1. window_title: The title of the window, as displayed in the title bar. Example: XMMS - Cranberries - You and me (3:37).
  2. application_name: The internal window title, as known to the application itself. Most often and for simple applications it will be identical to the window title, but it may differ sometimes.
  3. window_class, window_role: More obscure properties which are used to mark windows from the same application together as the members of the same group.

You can use any of these to match against with the logical conditions above.

4.5. Actions

The following actions were extracted from the source code, from src/parser.c, so I can’t really offer solid help on their parameters or usage. Their names are self-explanatory in most cases and you can make educated guesses as to the number of parameters and how they should look.

debug,  print, geometry, fullscreen, focus, center,
maximize, maximize_vertically, maximize_horizontally,
minimize, shade, unshade, close, pin, unpin, set_workspace,
skip_pager, skip_tasklist, above, below, undecorate, wintype

You can look at the window documentation for the Blackbox window manager. It’s a modern manager, so its docs cover pretty much all the above window actions. It will help you understand them better.

4.6. Regular expressions

Since the values of the window properties can vary wildly sometimes, it can be very useful to have not only simple texts to match against them, but regular expressions.

Regular expressions are a complicated thing themselves and I’m afraid I’m not going to go into that. You can read up on them on the Web.

5. Tips and tricks

5.1. How to find out window properties

One way is to run devilspie in debug mode, either with the --debug option, or by loading a .ds file which contains this: (debug), or both.

Another way is to run the xprop utility from a terminal. It will transform the mouse pointer in a targeting cross. Click on a window to get all kinds of information about that window.

5.2. Syntax highlighting for the .ds files

If you use NEdit, you can syntax-highlight the .ds files by using the scheme.pats patterns. You can find them here.

6. Examples

  1. (debug)
    Make devilspie print window properties on the standard output. Very useful so you can see how it reacts and what properties values are.
  2. (if (is (application_name) "Xmms") (skip_tasklist skip_pager))
    Hide all XMMS windows except the main one from both pagers and tasklists. This includes Alt-Tab lists. It will make XMMS much easier to work with.
  3. (if (contains (window_name) "TightVNC") (undecorate maximize))
    Make TightVNC client windows maximize and lose decorations.
  4. (if (is (application_name) "gamix") (geometry "767x409+59+82"))                 
    Impose a certain geometry on gamix windows, who are ill-behaved and never remember their last position.
  5. (if (contains (window_name) "LGeneral") (undecorate fullscreen))                
    Make LGeneral behave more like a game by removing decorations and giving it the special fullscreen status.

FIXME: more example wanted! Especially ones that use more actions or combine several logical operators with (and) and (or).

7. Other tutorials

  • Foosel Wiki: contains lots of examples with the new config syntax