Nepherte (dot) be

Clickable workspaces in XMonad with dzen2

While XMonad can be controlled entirely by the keyboard, it can still be a useful feature to change your workspace with a mouse click. I’ve been looking for this for quite some time and finally figured out how to get clickable workspaces in XMonad with dzen2.

You’ll need 3 things:

  • xmonad
  • dzen2 >= rev. 267
  • xdotool

Here are the things you’ll need to put in your xmonad.hs config:

import Data.List
 
-- Define amount and names of clickable workspaces.
myWorkspaces    = clickable . (map dzenEscape) $ nWorkspaces 0 ["main","web","chat","media","graph","browse","dev","mail"]
    where nWorkspaces n [] = map show [1 .. n]
          nWorkspaces n l  = init l ++ map show [length l .. n] ++ [last l]
          clickable l      = [ "^ca(1,xdotool key ctrl+F" ++ show (n) ++ ")" ++ ws ++ "^ca()" | (i,ws) <- zip [1..] l, let n = i ]

These lines will wrap every workspace name with ^ca, a click action available in dzen2 >= rev. 267. Xdotool is a small application that simulates pressed keys. You can alter the names of the workspaces to your likings. You do, however, have to change the key in the xdotool command to the key you use in XMonad to switch to a specific workspace. In my case, keys <ctrl>+F1 to <ctrl>+F8 are used to switch to workspaces 1 to 8.

Throughout your xmonad.hs you will need to replace all direct references to workspace names because now your first workspace for example, is named ^ca(1,xdotool key ctrl+F1)main^ca(). One way to do this is to use the following references instead:

-- Workspace variables
mainWs      = (myWorkspaces !! 0)
webWs       = (myWorkspaces !! 1)
chatWs      = (myWorkspaces !! 2)
mediaWs     = (myWorkspaces !! 3)
graphWs     = (myWorkspaces !! 4)
browseWs    = (myWorkspaces !! 5)
devWs       = (myWorkspaces !! 6)
mailWs      = (myWorkspaces !! 7)

Remember to use a dzen2 panel, as this click action is a dzen2 specific thing. Also don’t forget that if you have an urgent hook in your dzen2 pretty printer, you’ll have to rewrap the workspace with ^ca. You can find my entire confg file here

2 Comments

    Rather than changing all of the workspace names like that (not for this reason but something similar), I prefer to map something like your clickable function over all the workspace names before passing it to the PP value you use to interact with the status bar; this way my workspace names aren’t as ugly ;-)

  • Could you perhaps provide some sample code? I’m not quite sure I’m following, but it does make sense to not statically define workspace variables like that, I agree. It’s just a quick hack.

Leave a Reply