Adding a dzen2 Statusbar to xmonad

Using the xmonad tiling window manger and looking for a way to keep track of your workspaces, the time, and more? This guide shows how you can set up dzen2 as a statusbar with state information from xmonad.

dzen2 is a general purpose statusbar; it can display anything you like from standard in and integrates easily with xmonad or your own scripts. dzen2 is even capable of displaying icons and advanced text formatting.

If you’re not familiar with xmonad and configuring it, see my post on getting started with xmonad on Ubuntu.

dzen2 with dynamicLogDzen

Install dzen2

Install dzen2 from the package dzen2 (click the link to install), or by running the command below in your terminal:

sudo apt-get install dzen2

Configure xmonad

My xmonad configuration file is based off this template from the xmonad wiki. I’ll show the required changes to this configuration, and hopefully explain well enough what’s going on that you’ll also be able to make the correct changes to a custom configuration.

xmonad’s behavior needs to change in two ways: layouts need to not cover up the dzen2 statusbar and status information needs to be printed to standard out.

These two new imports are required (add them after any existing imports):

import XMonad.Hooks.DynamicLog
import XMonad.Hooks.ManageDocks

Your layouts need to be changed to add the avoidStruts modifier. This will cause the layouts to make room for any statusbars like dzen2. If you’re using the template file, you’ll need to change this line:

myLayout = tiled ||| Mirror tiled ||| Full

I chose to have four layouts: the three default ones with avoidStruts, and an additional full layout without it. This way I can hide the statusbar for fullscreen applications if I want. Here’s the line for this configuration:

myLayout = avoidStruts (tiled ||| Mirror tiled ||| Full) ||| Full

Lastly, a logging hook needs to be added. In the template, no logging takes place:

myLogHook = return ()

dynamicLogDzen will print workspace, layout, and window title information formatted nicely for dzen2. (Use dynamicLog to get the same thing minus the formatting.) In the template, replace the line above with this one to enable dynamicLogDzen.

myLogHook = dynamicLogDzen

Starting dzen2 and xmonad

xmonad and dzen2 need to be started when you log in so that xmonad’s logging is redirected to dzen2 to be displayed. This is easy to do with a pipe.

Create a small shell script that starts xmonad and pipes its output to dzen2:

xmonad | dzen2

Don’t forget to add the execute permission to the script:

chmod +x

This is the script that will be run when you log in. You can also add any other applications you want started with your session to this file.

GDM uses a desktop launcher to run xmonad. This launcher needs to be modified to run your script instead. Open the /usr/share/xsessions/xmonad.desktop launcher in an editor (this will require root privileges). Change the file’s Exec= line to point to your script instead of xmonad.

That should be it! Log in using the xmonad session, and dzen2 should be running at the top of the screen displaying your active workspaces, the current layout, and the title of the focused window.

Advanced statusbars

If you’re comfortable with Haskell programming, you can customize the information that xmonad passes to dzen2 right from your xmonad configuration file.

Another option is to use multiple dzen2 statusbars positioned to look like a single bar. The extra instances can have a shell or python script supplying information like the time, unread email, and weather.

Right now I’m working on a python script that takes xmonad’s status, adds the time and date, formats everything, and passes it on to dzen2. It uses a command like this: xmonad | ./ | dzen2.

Have a look at the statusbars in some of these xmonad setups to see what’s possible.

Archived Comments

Manuel Galisteo

Nice. I think these xmonad articles are very useful. Thanks a lot.


why not use this:


You should not change /usr/share/xsessions/xmonad.desktop to run your own startup script. If another user wants to use xmonad, he will try to run your xmonad-script. Better use .Xsession. :-)


Not in scope: `dynamicLogDzen’

the syntax has changed a bit,

logHook = dynamicLogWithPP dzenPP

as found on :

Respond via email