Everything in it’s Right Place 3: Setting dedicated workspaces with devil’s pie

This is the third post in a series on achieving an orderly desktop environment in GNOME 3, using no add-ons, only old school hacks. See also the first and the second post in the series.

Dedicated workspaces is a term – possibly – of my own invention. Possibly not. The basic idea was outlined in the first post: “Certain windows belong on certain workspaces”. With multiple workspaces you easily get windows randomly strewn across the workspaces. A browser there, a file manager here, a text editor over there. Because I am pretty goddamn anal this kind of thing bugs me. For my peace of mind as well as for windows being easy to find I need them to be in their proper place. So I devise some sort of order that groups the various types of windows into themes and hierarchies. I tend to group windows into categories like browsers, editors, viewers etc. but the exact nature of my chosen order is not the subject here. The point is that each window has one and just one workspace where it should spawn and where it should stay. It may have that workspace to itself (more easily accomplished with a grid of workspaces) or it may share it with other, similar windows. The technique is the same and utilises just one tool, devil’s pie.

Devil’s pie (or “devilspie” as packages and the binary knows it) let’s you script various rules for windows in EWMH compliant window managers, including GNOME’s mutter. Here we’ll only use it for a tiny subset of it’s possible uses. We want it to identiy when a specific window spawns and apply some rules to it. devilspie should be run on desktop environment startup but for writing and debugging rules you will want to run it on the command line with the debug option:

[~] devilspie --debug

This will not do anything by itself since you have not written any rules for it to apply. The rules are contained in “*.ds” files in the “.devilspie”  directory of your home folder, with each .ds file identifying a different window or set of windows.

Here’s my viewers.ds file as an example:

(if
        (or
                (is (window_class) "Evince")
                (is (window_class) "Mirage")
        )
    (begin
        (set_workspace 6)
        (maximize)
    )
)

The code is reasonably transparent. If either of the the two conditions is satisfied the begin block should be executed. ‘Begin’ marks the end of the conditional block and the beginning of the set of actions to apply to windows that satisfy the conditions. Supposing we only wanted the code to apply to a single case, we would reduce to:

(if
        (is (window_class) "Mirage")
    (begin
        (set_workspace 6)
        (maximize)
    )
)

or if we wanted both conditions fulfilled we would change the ‘or’ in the first block to ‘and’. You get the gist of it. For a more comprehensive syntax guide, see foosel’s documentation page.

So what is happening here? devilspie identifies some windows and applies some rules to them. The windows being targeted are those of the window_class “Mirage” which are simply windows of the image viewer application Mirage. What rules are applied? Simple. Mirage windows are set to spawn on workspace 6 and Mirage windows should start maximised. [Sidenote: Devilspie counts workspaces from 1, unlike say wmctrl which starts at 0 and workspaces have just one number to identify them regardless of how they are presented and laid out, e.g. grid or column.] Note the words ‘spawn’ and ‘start’ in the previous sentence. devilspie rules are applied when the window is created by the window manager. In the first block the same rules were being applied to Evince, the standard GNOME PDF reader, making workspace 6 the hub for all viewers-as-opposed-to-editors.

You can experiment with various actions yourself if you want to do more than just put windows in their place and maximise them.

The question remains: How do we identify the window, we want to target. Is it always just (is (window_class) “application_name“)? Often but not always. The easiest way to id a window is simply to open the application whose windows you want to manipulate. That done, kill(all) devilspie if you’ve got it running in the background and start it on the commandline with the debug parameter. The program will first show you all the rule files it’s importing and then list all of the currently open windows as well as tell you what if anything it’s doing to them. Let’s have a look at my current list:

Window Title: 'Home'; Application Name: 'nautilus'; Class: 'Nautilus'; Geometry: 1920x1173+0+27
Changing workspace to 2
Window Title: 'MediaFox'; Application Name: 'Firefox'; Class: 'Firefox'; Geometry: 1920x1173+0+27
Window Title: 'local_screen'; Application Name: 'Xfce Terminal'; Class: 'Xfce4-terminal'; Geometry: 1920x1173+0+27
Changing workspace to 3
Removed decorations
Maximising
Window Title: 'MadsFox'; Application Name: 'Firefox'; Class: 'Firefox'; Geometry: 1920x1173+0+27

Let’s focus on the first two lines. The first line identifies the window as having the title ‘Home’. The title is what’s usually written across the center of the top window bar of the window. The window belongs to the application named ‘nautilus’ and is of the class ‘Nautilus’. I’m not sure when if ever programs distinguish between being of a certain application and of a certain class. I tend to stick with identifying windows by class as I have an experience/sense that that is more exact. But it matters very little. Finally is the ‘geometry’ of the window which is size and placement. The nautilus window is 1920 pixels wide and 1173 pixels high. It starts horisontally on the very first (left-most) pixel and vertically on the 28th pixel (since we start count at zero). Since it is maximised on a 1920×1200 resolution screen this means that the first 27 pixels are taken up by GNOME’s black shell bar (the one with the time on). The second line tells you that devilspie has moved the window to the second workspace.

Let’s check my nautilus.ds file to see if this is as it should be:

(if
        (is (window_class) "Nautilus")
    (begin
        (set_workspace 2)
    )
)

It is. How fortunate.

As you can see from the example all you need to do to get the id on a window is to run devilspie in debug mode and then copy-paste the correct window’s class name into a code block like the one above.

And that’s all you need to get dedicated workspaces. Yes, there is an extension that does more or less the same thing. It may even work once you update GNOME. But devilspie has been around and working since 2002. I think that is a much better guarantee. And once you understand how devilspie works you have got yourself a multi-purpose power tool rather than a single purpose can opener.

 

Featured image in public domain by Boereck.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.