title | tags |
---|---|
Status Bars in XMonad |
haskell, xmonad |
One of the trickiest things for a new user of XMonad is adding a statusbar. This is mainly because xmonad's statusbar support is so transparent and extensible, that any documentation for setting it up could be completely different from any other. Do you want a dynamicLog? A customLog? xmobar? dzen? One bar? Two?
Here I'll outline my method. Two separate dzen2 bars aligned to look like one bar across the top of your screen. The left fed by an xmonad dynamicLogWithPP to show workspaces (with coloring and urgencyHooks), the current layout and the current window title. The right fed by conky to show music, system stats and of course the time.
Full desktop:
And with an urgencyHook
notification (Workspace turns a different
color):
To achieve this, we set up a dynamicLog
in xmonad.hs
and adjust our
main
function to output to this bar and also spawn our right bar as
fed by conky.
Your imports and main function will look like this:
import XMonad.Util.Run
import XMonad.Hooks.DynamicLog
import XMonad.Hooks.ManageDocks
import XMonad.Hooks.UrgencyHook
main = do
-- spawn our left and right bars. in my case, I use two monitors,
-- I want one bar on each, and my version of dzen supports the -xs
-- argument for specifying on which screen to appear. if your
-- situation is different in some way, use -w and -x to give your
-- bars appriate width and x offsets for your needs.
d <- spawnPipe "dzen2 -p -xs 1 -ta l -e 'onstart=lower'"
spawn $ "conky -c ~/.xmonad/data/conky/dzen | " ++
"dzen2 -p -xs 2 ta -r -e 'onstart=lower'"
xmonad $ withUrgencyHook NoUrgencyHook $ defaultConfig
{ ...
, logHook = myLogHook d
-- having these call out to external functions makes it easier
-- to add the "no overlap" stuff later on. if you don't have
-- myLayoutHook or myManageHook, you can continue to use the
-- xmonad defaults by declaring them like so:
--
-- > myManageHook = manageHook defaultConfig
-- > myLayoutHook = layoutHook defaultConfig
--
, manageHook = myManageHook
, layoutHook = myLayoutHook
}
Don't worry about the things we haven't defined yet, I'll get to those. Also, the conky config file which I use can be found in my xmonad repo.
Your logHook
will setup the output of workspaces, layouts, and titles
to the left dzen
. You can customize the formatting, padding,
shortening, etc.
Here's a commented version of myLogHook
which, hopefully, is
illustrative enough to not warrant further explanation.
--
-- Loghook
--
-- note: some of these colors may differ from what's in the
-- screenshot, it changes daily
--
myLogHook h = dynamicLogWithPP $ defaultPP
-- display current workspace as darkgrey on light grey (opposite of
-- default colors)
{ ppCurrent = dzenColor "#303030" "#909090" . pad
-- display other workspaces which contain windows as a brighter grey
, ppHidden = dzenColor "#909090" "" . pad
-- display other workspaces with no windows as a normal grey
, ppHiddenNoWindows = dzenColor "#606060" "" . pad
-- display the current layout as a brighter grey
, ppLayout = dzenColor "#909090" "" . pad
-- if a window on a hidden workspace needs my attention, color it so
, ppUrgent = dzenColor "#ff0000" "" . pad . dzenStrip
-- shorten if it goes over 100 characters
, ppTitle = shorten 100
-- no separator between workspaces
, ppWsSep = ""
-- put a few spaces between each object
, ppSep = " "
-- output to the handle we were given as an argument
, ppOutput = hPutStrLn h
}
The last thing you should do is add two little things to make sure you leave a gap for the new statusbar:
-- add avoidStruts to your layoutHook like so
myLayoutHook = avoidStruts $ {- whatever you had before... -}
-- add manageDocks to your managehook like so
myManageHook = manageDocks <+> {- whatever you had before ... -}
Happy haskelling!