Going fast with DWM

If there was any justice in this world, there would be two cars parked in my driveway. One would be a 1977 Ferrari 308 GTS. The other would be a midnight blue BMW M3 convertible with all the amenities. I'd want the leather seats and power everything. When I'm in the BMW, I don't want to have to roll the windows down; I want to push a button and have a leprechaun come out and roll them down for me. I want to point the car in the general direction of where I want to go and have it drive me there. That's right, sometimes a guy just wants to be pampered.

Then there are those times when I just want to go fast, fast enough that I wouldn't have time to roll the window down and the leprechaun would be too afraid to unbuckle his seatbelt. In the Ferrari, I'm sure I'd feel every pebble in the road and I'd spend most of my weekends working on the car trying to coax out every last bit of horsepower. When I'm driving, I want to have to think about if I should down-shift from 3rd to 2nd, or maybe even down to 1st. And I want to know the car inside and out.

Well, if you're not geeking out over all this car talk, you're probably wondering what it has to do with Linux. In my day-to-day work, I use the K Desktop Environment (KDE). You could think of KDE as being like the BMW I mentioned earlier. As a user, you practically never have to get under the hood. And it seems that there is a button or a dialog box to perform just about any function or configuration change that you could imagine. If you don't know the name of the program you want to run, there's usually an icon or menu item that you can click on. Like the BMW, KDE isn't known for being fast or lightweight, but it is very comfortable.

Weighing in at a mere 2140 lines of C code, the Dynamic Window Manager, (DWM) certainly qualifies as lightweight. There aren't any menus, and no icons. You can't use a dialog box to change the screen colors, either. You literally have to get under the hood to make configuration changes, which we'll talk about shortly. Most of the time, you won't even use the mouse. Once you've learned how to “drive” DWM, you can really go fast in it.

Likewise, installing DWM couldn't be easier. Simply download the tarball from dwm.suckless.org and extract the contents. Then run make in the resulting directory. The result is a single executable, dwm. If you then run make install, make will install a man page and install the dwm executable in /usr/local. For testing, I simply ran dwm from my home directory.

I have to admit that my first impression of DWM was less than stellar. After I killed the KDE environment I was running and launched DWM I was almost immediately confronted by a simple gray screen with some numbers across the top. Without a menu, I was a little disoriented. So I decided to go back and read the fine manual.

After reading the manual and the tutorial on DWM's website, I discovered that would bring up an x-terminal. Finally, something I could relate to! As I started more x-terminals, DWM pushed them onto a stack along the right-hand side of the screen. With just a few quick keystrokes, I was able to flip through the “stacked” windows and bring them up to the top. After a couple of minutes, I could see that it would be very easy to train my fingers to navigate between several windows without ever picking up the mouse.

DWM lays out program windows according to one of two modes, tiled, floating, and monocle. The user can switch between these modes with , , and , respectively. Tiled mode is the default and behaves as I described earlier. In floating mode, windows may be dragged around the screen with the mouse and behave much like they do in other windowing environments. In monocle mode, the main window takes up the entire screen and can't be manipulated. To me, this seems like a very simple way to setup a kiosk machine. Simply put DWM in monocle mode and remove the key sequences to put it in a different mode.

Windows in DWM are organized by assigning one or more tags to them. Then the user can chose which tags to display in each virtual screen. This mechanism is actually more flexible than what I enjoy with KDE, since it allows a given window to appear in any number of virtual screens. I'm not completely comfortable with this mechanism, but I think I'll like it once I am.

When I first read that configuration changes to DWM were made by modifying the source and recompiling, I couldn't believe what I was reading, but it's not nearly as bad as it sounds. The source code is contained in two files: dwm.c, which you shouldn't have to modify, and config.h which is where you make your changes. By changing config.h you can change the color scheme, tag names, magic keyboard and mouse assignments, and more. The config.h file is only 100 lines of fairly well commented code, so let's take a quick look.

Starting on line 5, we have appearance settings. For example, we can set the color of the window border by modifying this statement:

static const char normbordercolor[] = "#cccccc";

We can even change the number of pixels used to frame the windows, which defaults to 1, and where the status bar appears.

We can predefine the names of the tags we want to use to organize our windows on line 16. By default, the tag names are simply the numbers 1 through 9.

static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };

We could redefine these to be “email”, “reference”, “work”, “play”, or whatever makes sense to us.

The next section of the config.h file is one that I think could use a few more comments. This is the rules section. The default looks like this:

static const Rule rules[] = {
        /* class      instance    title       tags mask     isfloating   monitor */
        { "Gimp",     NULL,       NULL,       0,            True,        -1 },
        { "Firefox",  NULL,       NULL,       1 << 8,       False,       -1 },

From this, I'm gleaning that DWM can handle different applications differently, but the documentation is a bit lacking here.

Next, we see some layout configuration options, but I'm going to skip ahead to the keyboard and mouse command sections, from which, I've pulled out a few highlights.

/* commands */ 
static const char *termcmd[]  = { "uxterm", NULL };                                                                                                             

Here we see that the developers have described what's involved in launching the uxterm program. There are other commands defined, and the user is certainly able to expand this list as they wish. These definitions are use in the next section, where we assign functions to keystrokes.

In this section, we can determine what happens when we press various key combinations. The MODKEY constant has been defined elsewhere to be the Alt key. Take a look:

static Key keys[] = {
/* modifier            key          function     argument*/      
{ MODKEY|ShiftMask,    XK_Return,   spawn,       {.v = termcmd } },                                                                                        
{ MODKEY,              XK_t,        setlayout,   {.v =&layouts[0]} },
{ MODKEY,              XK_f,        setlayout,   {.v = &layouts[1]} },
{ MODKEY,              XK_m,        setlayout,   {.v = &layouts[2]} },

The first entry simply says that when the user presses the key sequence, DWM should spawn an x-terminal. From here, it's pretty easy to see how one might define a hot-key sequence to launch our favorite web browser. Finally, I've shown how the window layout (tiled, floating, and monocle) mode key sequences are defined. If we wanted to create a kiosk machine, we'd simply remove the other options at this point, for example.

The mouse sequences are defined similarly.

There is a surprising amount of configuration to be found in DWM's config.h file. But going back to the automobile analogy, I just wanted to pop the hood and show you where the spark plugs are and how to check the oil.

I think that in the end, if you want a full-featured windows manager with all the amenities, DWM probably isn't for you. On the other hand, if you want something light and fast, and like to tinker, I would definitely check out DWM.

Load Disqus comments