diff --git a/news.md b/news.md
--- a/news.md
+++ b/news.md
@@ -1,5 +1,32 @@
 % xmobar - Release notes
 
+## Version 0.20 (March 10, 2014)
+
+_New features_
+
+  - Mouse actions now support multiple buttons, by Marcin Mikołajczyk.
+  - Non supported monitors are ignored in configuration files (see
+    [issue #139]), by Adam Vogt.
+
+_Bug fixes_
+
+  - `Disk` monitor now ignores non-existent devices (Reto Hablützel).
+  - `Weather` is now non-blocking and doesn't use curl (Ben Boeckel).
+  - Fix for `Memory` monitor in 3.14 kernels (Ben Boeckel).
+  - Fix for infinite loops in `AutoMPD` ([issue #76], [issue #111]).
+  - More robust AC readings in `BatteryP`.
+  - Fix for `Top` monitor's readings for processes whose name contains
+    blanks.
+  - Fixes for geometry computation on multihead (Dmitry Malikov).
+  - Fixes for missing XDG configuration (Thiago Negri and James McCoy,
+    see [issue #133]).
+  - Compatibility with latest `directory` (1.2.0.2).
+
+[issue #76]: https://github.com/jaor/xmobar/issues/76
+[issue #111]: https://github.com/jaor/xmobar/issues/111
+[issue #133]: https://github.com/jaor/xmobar/issues/133
+[issue #139]: https://github.com/jaor/xmobar/issues/133
+
 ## Version 0.19 (October 27, 2013)
 
 As of this release, the old bug tracker at Google code is deprecated.
diff --git a/readme.md b/readme.md
--- a/readme.md
+++ b/readme.md
@@ -11,7 +11,7 @@
 features, like dynamic color management, icons, output templates, and
 extensibility through plugins.
 
-This page documents xmobar 0.19 (see [release notes]).
+This page documents xmobar 0.20 (see [release notes]).
 
 [This screenshot] shows xmobar running under [sawfish], with
 antialiased fonts. And [this one] is my desktop with [xmonad] and two
@@ -132,7 +132,7 @@
      Requires the [dbus] and [text] packages.
 
 `with_inotify`
-:    Support for inotify in modern linux kernels. This option is needed
+:    Support for inotify in modern Linux kernels. This option is needed
      for the MBox and Mail plugins to work. Requires the [hinotify]
      package.
 
@@ -197,7 +197,10 @@
 
 - `<icon=/path/to/icon.xbm/>` will insert the given bitmap.
 
-- `<action=command>` will execute given command.
+- ```<action=`command` button=12345>``` will execute given command when
+  clicked with specified buttons. If not specified, button is equal to 1
+  (left mouse button). Using old syntax (without backticks surrounding `command`)
+  will result in `button` attribute being ignored.
 
 Other configuration options:
 
@@ -256,7 +259,7 @@
 
 `allDesktops`
 :     When set to True (the default), xmobar will tell the window manager
-      explicitily to be shown in all desktops, by setting
+      explicitly to be shown in all desktops, by setting
       `_NET_WM_DESKTOP` to 0xffffffff.
 
 `overrideRedirect`
@@ -347,7 +350,7 @@
 controlled over dbus. All signals defined in [src/Signal.hs] as `data
 SignalType` can now be sent over dbus to xmobar.  Due to current
 limitations of the implementation only one process of xmobar can
-aquire the dbus. This is handled on a first-come-first-seved basis,
+acquire the dbus. This is handled on a first-come-first-served basis,
 meaning that the first process will get the dbus interface. Other
 processes will run without further problems, yet have no dbus
 interface.
@@ -461,9 +464,10 @@
 
 It's also possible to use action directives of the form:
 
-     <action=command>
+     <action=`command` button=12345>
 
-which will be executed when clicked on.
+which will be executed when clicked on with specified mouse buttons. This tag
+can be nested, allowing different commands to be run depending on button clicked.
 
 ## The `commands` Configuration Option
 
@@ -488,7 +492,7 @@
 
 This example will run "xclock" command when date is clicked:
 
-    template="<action=xclock>%date%</action>
+    template="<action=`xclock`>%date%</action>
 
 The only internal available command is `Com` (see below Executing
 External Commands). All other commands are provided by plugins. xmobar
@@ -514,7 +518,7 @@
 ### Default Monitor Arguments
 
 Monitors accept a common set of arguments, described in the first
-subsection below.  In additon, some monitors accept additional options
+subsection below.  In addition, some monitors accept additional options
 that are specific to them.  When specifying the list of arguments in
 your configuration, the common options come first, followed by "--",
 followed by any monitor-specific options.
@@ -646,15 +650,15 @@
 
 ### `Weather StationID Args RefreshRate`
 
-- Aliases to the Station ID: so `Weather "LIPB" []` can be used in template as `%LIPB%`
+- Aliases to the Station ID: so `Weather "LIPB" []` can be used in
+  template as `%LIPB%`
 - Args: default monitor arguments
 - Variables that can be used with the `-t`/`--template` argument:
 	    `station`, `stationState`, `year`, `month`, `day`, `hour`,
 	    `wind`, `visibility`, `skyCondition`, `tempC`, `tempF`,
 	    `dewPoint`, `rh`, `pressure`
 - Default template: `<station>: <tempC>C, rh <rh>% (<hour>)`
-- Requires `curl` in the `$PATH` to retrieve weather information from
-  `http://weather.noaa.gov`
+- Retrieves weather information from http://weather.noaa.gov.
 
 ### `Network Interface Args RefreshRate`
 
@@ -751,7 +755,7 @@
   - `-H`: high power threshold (default: -10)
   - `-l`: color to display power lower than the `-L` threshold
   - `-m`: color to display power lower than the `-H` threshold
-  - `-h`: color to display power highter than the `-H` threshold
+  - `-h`: color to display power higher than the `-H` threshold
   - `-p`: color to display positive power (battery charging)
   - `-f`: file in `/sys/class/power_supply` with AC info (default:
     "AC/online")
@@ -860,7 +864,7 @@
 - Variables that can be used with the `-t`/`--template` argument:
 	    `temp`
 - Default template: `<temp>C`
-- This plugin works only on sytems with devices having thermal zone.
+- This plugin works only on systems with devices having thermal zone.
   Check directories in `/sys/class/thermal` for possible values of the
   zone number (e.g., 0 corresponds to `thermal_zone0` in that
   directory).
@@ -878,7 +882,7 @@
 - Variables that can be used with the `-t`/`--template` argument:
 	    `temp`
 - Default template: `Thm: <temp>C`
-- This plugin works only on sytems with devices having thermal zone.
+- This plugin works only on systems with devices having thermal zone.
   Check directories in /proc/acpi/thermal_zone for possible values.
 - Example:
 
@@ -954,10 +958,10 @@
   The environment variables `MPD_HOST` and `MPD_PORT` are used to configure the
   mpd server to communicate with.
 - Variables that can be used with the `-t`/`--template` argument:
-             `bar`, `state`, `statei`, `volume`, `length`
+             `bar`, `state`, `statei`, `volume`, `length`,
              `lapsed`, `remaining`,
-             `plength` (playlist length), `ppos` (playlist position)
-             `name`, `artist`, `composer`, `performer`
+             `plength` (playlist length), `ppos` (playlist position),
+             `name`, `artist`, `composer`, `performer`,
              `album`, `title`, `track`, `file`, `genre`
 - Default template: `MPD: <state>`
 - Example (note that you need "--" to separate regular monitor options from
@@ -1001,7 +1005,7 @@
 - Args: list of maildirs in form
   `[("name1","path1"),...]`. Paths may start with a '~'
   to expand to the user's home directory.
-- This plugin requires inotify support in your linux kernel and the
+- This plugin requires inotify support in your Linux kernel and the
   [hinotify] package. To activate, pass `--flags="with_inotify"`
   during compilation.
 - Example:
@@ -1021,11 +1025,11 @@
    -d dir  --dir dir a string giving the base directory where mbox files with
                      a relative path live.
    -p prefix --prefix prefix  a string giving a prefix for the list
-                      of displayed mail coints
+                      of displayed mail counts
    -s suffix --suffix suffix  a string giving a suffix for the list
-                      of displayed mail coints
+                      of displayed mail counts
 - Paths may start with a '~' to expand to the user's home directory.
-- This plugin requires inotify support in your linux kernel and the
+- This plugin requires inotify support in your Linux kernel and the
   [hinotify] package. To activate, pass `--flags="with_inotify"`
   during compilation.
 - Example. The following command look for mails in `/var/mail/inbox`
@@ -1059,7 +1063,7 @@
     - `-C`: file with the current brightness (default:
        actual_brightness)
     - `-M`: file with the maximum brightness (default:
-       max_brigtness)
+       max_brightness)
 - Variables that can be used with the `-t`/`--template` argument:
 	    `hbar`, `percent`, `bar`
 - Default template: `<percent>`
@@ -1070,9 +1074,9 @@
 ### `Kbd Opts`
 
 - Registers to XKB/X11-Events and output the currently active keyboard layout.
-  Supports replacement of layoutnames.
+  Supports replacement of layout names.
 - Aliases to `kbd`
-- Opts is a list of tuple:
+- Opts is a list of tuples:
     -  first element of the tuple is the search string
     -  second element of the tuple is the corresponding replacement
 - Example:
@@ -1137,7 +1141,7 @@
 - Sample usage: send to xmobar's stdin the list of your workspaces enclosed by
   actions tags that switches the workspaces to be able to switch workspaces by
   clicking on xmobar:
-  `<action=xdotool key alt+1>ws1</action> <action=xdotool key alt+1>ws2</action>`
+  ```<action=`xdotool key alt+1`>ws1</action> <action=`xdotool key alt+1`>ws2</action>```
 
 <font size="+1">**`Date Format Alias RefreshRate`**</font>
 
@@ -1176,13 +1180,13 @@
   content is restored i.e. if there was already something from a
   previous pipe it will be put on display again, overwriting the
   current status.
-- A pipe with Timout of 0 will be displayed permanently, just like
+- A pipe with Timeout of 0 will be displayed permanently, just like
   `PipeReader`
 - The boolean option indicates whether new data for this pipe should
   make xmobar appear (unhide, reveal). In this case, the Timeout
   additionally specifies when the window should be hidden again. The
   output is restored in any case.
-- Use it for OSD like status bars e.g. for setting the volume or
+- Use it for OSD-like status bars e.g. for setting the volume or
   brightness:
 
         Run BufferedPipeReader "bpr"
@@ -1346,11 +1350,11 @@
 Cheplyaka, Patrick Chilton, John Goerzen, Reto Hablützel, Juraj
 Hercek, Tomas Janousek, Spencer Janssen, Jochen Keil, Lennart
 Kolmodin, Krzysztof Kosciuszkiewicz, Dmitry Kurochkin, Todd Lunter,
-Dmitry Malikov, David McLean, Thiago Negri, Edward O'Callaghan, Svein
-Ove, Martin Perner, Jens Petersen, Alexander Polakov, Petr Rockai,
-Peter Simons, Andrew Sackville-West, Alexander Solovyov, John Soros,
-Artem Tarasov, Sergei Trofimovich, Thomas Tuegel, Jan Vornberger,
-Daniel Wagner and Norbert Zeh.
+Dmitry Malikov, David McLean, Marcin Mikołajczyk, Thiago Negri, Edward
+O'Callaghan, Svein Ove, Martin Perner, Jens Petersen, Alexander
+Polakov, Petr Rockai, Peter Simons, Andrew Sackville-West, Alexander
+Solovyov, John Soros, Artem Tarasov, Sergei Trofimovich, Thomas
+Tuegel, Jan Vornberger, Daniel Wagner and Norbert Zeh.
 
 [jao]: http://jao.io
 [incorporates patches]: http://www.ohloh.net/p/xmobar/contributors
diff --git a/src/Actions.hs b/src/Actions.hs
--- a/src/Actions.hs
+++ b/src/Actions.hs
@@ -14,14 +14,21 @@
 
 import System.Process (system)
 import Control.Monad (void)
-import Text.Regex (subRegex, mkRegex)
+import Text.Regex (Regex, subRegex, mkRegex, matchRegex)
+import Graphics.X11.Types (Button)
 
-data Action = Spawn String
+data Action = Spawn [Button] String
                 deriving (Eq)
 
 runAction :: Action -> IO ()
-runAction (Spawn s) = void $ system (s ++ "&")
+runAction (Spawn _ s) = void $ system (s ++ "&")
 
 stripActions :: String -> String
-stripActions s = subRegex actionRegex s "[action=\1]\2[action]"
-  where actionRegex = mkRegex "<action=([^>])*>(.+)</action>"
+stripActions s = case matchRegex actionRegex s of
+  Nothing -> s
+  Just _  -> stripActions strippedOneLevel
+  where
+      strippedOneLevel = subRegex actionRegex s $ "[action=\\1\\2]\\3[/action]"
+
+actionRegex :: Regex
+actionRegex = mkRegex "<action=`?([^>`]*)`?( +button=[12345]+)?>(.+)</action>"
diff --git a/src/Bitmap.hs b/src/Bitmap.hs
--- a/src/Bitmap.hs
+++ b/src/Bitmap.hs
@@ -30,7 +30,7 @@
                      }
 
 updateCache :: Display -> Window -> Map FilePath Bitmap ->
-               [[(Widget, String, Maybe Action)]] -> IO (Map FilePath Bitmap)
+               [[(Widget, String, Maybe [Action])]] -> IO (Map FilePath Bitmap)
 updateCache dpy win cache ps = do
   let paths = map (\(Icon p, _, _) -> p) . concatMap (filter icons) $ ps
       icons (Icon _, _, _) = True
diff --git a/src/Config.hs b/src/Config.hs
--- a/src/Config.hs
+++ b/src/Config.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE CPP, TypeOperators #-}
+{-# LANGUAGE TypeOperators #-}
 
 -----------------------------------------------------------------------------
 -- |
@@ -37,14 +37,10 @@
 import Plugins.Kbd
 import Plugins.Locks
 
-#ifdef INOTIFY
 import Plugins.Mail
 import Plugins.MBox
-#endif
 
-#ifdef DATEZONE
 import Plugins.DateZone
-#endif
 
 -- $config
 -- Configuration data type and default configuration
@@ -135,11 +131,7 @@
 -- the plugin's type to the list of types (separated by ':*:') appearing in
 -- this function's type signature.
 runnableTypes :: Command :*: Monitors :*: Date :*: PipeReader :*: BufferedPipeReader :*: CommandReader :*: StdinReader :*: XMonadLog :*: EWMH :*: Kbd :*: Locks :*:
-#ifdef INOTIFY
                  Mail :*: MBox :*:
-#endif
-#ifdef DATEZONE
                  DateZone :*:
-#endif
                  ()
 runnableTypes = undefined
diff --git a/src/Main.hs b/src/Main.hs
--- a/src/Main.hs
+++ b/src/Main.hs
@@ -105,14 +105,16 @@
 -- | Read default configuration file or load the default config
 readDefaultConfig :: IO (Config,[String])
 readDefaultConfig = do
-  xdgconf <- getXdgConfigFile
-  x <- io $ fileExist xdgconf
+  xdgConfigFile <- getXdgConfigFile
+  xdgConfigFileExists <- io $ fileExist xdgConfigFile
   home <- io $ getEnv "HOME"
-  let path = home ++ "/.xmobarrc"
-  f <- io $ fileExist path
-  if x then readConfig path
-       else if f then readConfig path
-                 else return (defaultConfig,[])
+  let defaultConfigFile = home ++ "/.xmobarrc"
+  defaultConfigFileExists <- io $ fileExist defaultConfigFile
+  if xdgConfigFileExists
+    then readConfig xdgConfigFile
+    else if defaultConfigFileExists
+         then readConfig defaultConfigFile
+         else return (defaultConfig,[])
 
 data Opts = Help
           | Version
diff --git a/src/Parsers.hs b/src/Parsers.hs
--- a/src/Parsers.hs
+++ b/src/Parsers.hs
@@ -28,13 +28,14 @@
 import qualified Data.Map as Map
 import Text.ParserCombinators.Parsec
 import Text.ParserCombinators.Parsec.Perm
+import Graphics.X11.Types (Button)
 
 data Widget = Icon String | Text String
 
 type ColorString = String
 
 -- | Runs the string parser
-parseString :: Config -> String -> IO [(Widget, ColorString, Maybe Action)]
+parseString :: Config -> String -> IO [(Widget, ColorString, Maybe [Action])]
 parseString c s =
     case parse (stringParser (fgColor c) Nothing) "" s of
       Left  _ -> return [(Text $ "Could not parse string: " ++ s
@@ -43,14 +44,14 @@
       Right x -> return (concat x)
 
 -- | Gets the string and combines the needed parsers
-stringParser :: String -> Maybe Action
-                -> Parser [[(Widget, ColorString, Maybe Action)]]
+stringParser :: String -> Maybe [Action]
+                -> Parser [[(Widget, ColorString, Maybe [Action])]]
 stringParser c a = manyTill (textParser c a <|> try (iconParser c a) <|>
-                             try (actionParser c) <|> colorParser a) eof
+                             try (actionParser c a) <|> colorParser a) eof
 
 -- | Parses a maximal string without color markup.
-textParser :: String -> Maybe Action
-              -> Parser [(Widget, ColorString, Maybe Action)]
+textParser :: String -> Maybe [Action]
+              -> Parser [(Widget, ColorString, Maybe [Action])]
 textParser c a = do s <- many1 $
                           noneOf "<" <|>
                             try (notFollowedBy' (char '<')
@@ -61,7 +62,6 @@
                                    string "/fc>"))
                     return [(Text s, c, a)]
 
-
 -- | Wrapper for notFollowedBy that returns the result of the first parser.
 --   Also works around the issue that, at least in Parsec 3.0.0, notFollowedBy
 --   accepts only parsers with return type Char.
@@ -70,28 +70,38 @@
                         notFollowedBy $ try (e >> return '*')
                         return x
 
-iconParser :: String -> Maybe Action
-              -> Parser [(Widget, ColorString, Maybe Action)]
+iconParser :: String -> Maybe [Action]
+              -> Parser [(Widget, ColorString, Maybe [Action])]
 iconParser c a = do
   string "<icon="
   i <- manyTill (noneOf ">") (try (string "/>"))
   return [(Icon i, c, a)]
 
-actionParser :: String -> Parser [(Widget, ColorString, Maybe Action)]
-actionParser c = do
-  a <- between (string "<action=") (string ">") (many1 (noneOf ">"))
-  let a' = Just (Spawn a)
+actionParser :: String -> Maybe [Action] -> Parser [(Widget, ColorString, Maybe [Action])]
+actionParser c act = do
+  string "<action="
+  command <- choice [between (char '`') (char '`') (many1 (noneOf "`")),
+                   many1 (noneOf ">")]
+  buttons <- (char '>' >> return "1") <|> (space >> spaces >>
+    between (string "button=") (string ">") (many1 (oneOf "12345")))
+  let a = Spawn (toButtons buttons) command
+      a' = case act of
+        Nothing -> Just [a]
+        Just act' -> Just $ a : act'
   s <- manyTill (try (textParser c a') <|> try (iconParser c a') <|>
-                 try (colorParser a') <|> actionParser c)
+                 try (colorParser a') <|> actionParser c a')
                 (try $ string "</action>")
   return (concat s)
 
+toButtons :: String -> [Button]
+toButtons s = map (\x -> read [x]) s
+
 -- | Parsers a string wrapped in a color specification.
-colorParser :: Maybe Action -> Parser [(Widget, ColorString, Maybe Action)]
+colorParser :: Maybe [Action] -> Parser [(Widget, ColorString, Maybe [Action])]
 colorParser a = do
   c <- between (string "<fc=") (string ">") colors
   s <- manyTill (try (textParser c a) <|> try (iconParser c a) <|>
-                 try (colorParser a) <|> actionParser c) (try $ string "</fc>")
+                 try (colorParser a) <|> actionParser c a) (try $ string "</fc>")
   return (concat s)
 
 -- | Parses a color specification (hex or named)
diff --git a/src/Plugins/DateZone.hs b/src/Plugins/DateZone.hs
--- a/src/Plugins/DateZone.hs
+++ b/src/Plugins/DateZone.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE CPP #-}
 {-# LANGUAGE DoAndIfThenElse #-}
 -----------------------------------------------------------------------------
 -- |
@@ -23,30 +24,37 @@
 
 import Plugins
 
-import Localize
 
+#ifdef DATEZONE
 import Control.Concurrent.STM
 
+import System.IO.Unsafe
+
+import Localize
 import Data.Time.LocalTime
 import Data.Time.Format
 import Data.Time.LocalTime.TimeZone.Olson
 import Data.Time.LocalTime.TimeZone.Series
 
-import System.IO.Unsafe
 import System.Locale (TimeLocale)
+#else
+import System.IO
+import Plugins.Date
+#endif
 
 
 
-{-# NOINLINE localeLock #-}
--- ensures that only one plugin instance sets the locale
-localeLock :: TMVar Bool
-localeLock = unsafePerformIO (newTMVarIO False)
-
 data DateZone = DateZone String String String String Int
     deriving (Read, Show)
 
 instance Exec DateZone where
     alias (DateZone _ _ _ a _) = a
+#ifndef DATEZONE
+    start (DateZone f _ _ a r) cb = do
+      hPutStrLn stderr $ "Warning: DateZone plugin needs -fwith_datezone."++
+                  " Using Date plugin instead."
+      start (Date f a r) cb
+#else
     start (DateZone f l z _ r) cb = do
       lock <- atomically $ takeTMVar localeLock
       setupTimeLocale l
@@ -60,6 +68,11 @@
 
       where go func = func >>= cb >> tenthSeconds r >> go func
 
+{-# NOINLINE localeLock #-}
+-- ensures that only one plugin instance sets the locale
+localeLock :: TMVar Bool
+localeLock = unsafePerformIO (newTMVarIO False)
+
 date :: String -> TimeLocale -> IO String
 date format loc = getZonedTime >>= return . formatTime loc format
 
@@ -67,3 +80,4 @@
 dateZone format loc timeZone = getZonedTime >>= return . formatTime loc format . utcToLocalTime' timeZone . zonedTimeToUTC
 --   zonedTime <- getZonedTime
 --   return $ formatTime loc format $ utcToLocalTime' timeZone $ zonedTimeToUTC zonedTime
+#endif
diff --git a/src/Plugins/MBox.hs b/src/Plugins/MBox.hs
--- a/src/Plugins/MBox.hs
+++ b/src/Plugins/MBox.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE CPP #-}
 -----------------------------------------------------------------------------
 -- |
 -- Module      :  Plugins.MBox
@@ -16,6 +17,7 @@
 
 import Prelude
 import Plugins
+#ifdef INOTIFY
 import Plugins.Utils (changeLoop, expandHome)
 
 import Control.Monad (when)
@@ -57,6 +59,10 @@
     (o, _, []) -> return $ foldr id defaults o
     (_, _, errs) -> ioError . userError $ concat errs
 
+#else
+import System.IO
+#endif
+
 -- | A list of display names, paths to mbox files and display colours,
 -- followed by a list of options.
 data MBox = MBox [(String, FilePath, String)] [String] String
@@ -64,8 +70,12 @@
 
 instance Exec MBox where
   alias (MBox _ _ a) = a
+#ifndef INOTIFY
+  start _ _ = do
+    hPutStrLn stderr $ "Warning: xmobar is not compiled with -fwith_inotify" ++
+          " but the MBox plugin requires it"
+#else
   start (MBox boxes args _) cb = do
-
     opts <- parseOptions args
     let showAll = oAll opts
         prefix = oPrefix opts
@@ -109,3 +119,4 @@
   (p, _) <- atomically $ readTVar v
   n <- countMails p
   atomically $ writeTVar v (p, n)
+#endif
diff --git a/src/Plugins/Mail.hs b/src/Plugins/Mail.hs
--- a/src/Plugins/Mail.hs
+++ b/src/Plugins/Mail.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE CPP #-}
 -----------------------------------------------------------------------------
 -- |
 -- Module      :  Plugins.Mail
@@ -15,6 +16,7 @@
 module Plugins.Mail where
 
 import Plugins
+#ifdef INOTIFY
 import Plugins.Utils (expandHome, changeLoop)
 
 import Control.Monad
@@ -27,13 +29,22 @@
 import Data.List (isPrefixOf)
 import Data.Set (Set)
 import qualified Data.Set as S
+#else
+import System.IO
+#endif
 
+
 -- | A list of mail box names and paths to maildirs.
 data Mail = Mail [(String, FilePath)] String
     deriving (Read, Show)
 
 instance Exec Mail where
     alias (Mail _ a) = a
+#ifndef INOTIFY
+    start _ _ = do
+        hPutStrLn stderr $ "Warning: xmobar is not compiled with -fwith_inotify,"
+                        ++ " but the Mail plugin requires it."
+#else
     start (Mail ms _) cb = do
         vs <- mapM (const $ newTVarIO S.empty) ms
 
@@ -65,3 +76,4 @@
  where
     delete = S.delete (filePath e)
     create = S.insert (filePath e)
+#endif
diff --git a/src/Plugins/Monitors.hs b/src/Plugins/Monitors.hs
--- a/src/Plugins/Monitors.hs
+++ b/src/Plugins/Monitors.hs
@@ -19,7 +19,7 @@
 
 import Plugins
 
-import Plugins.Monitors.Common (runM)
+import Plugins.Monitors.Common (runM, runMD)
 import Plugins.Monitors.Weather
 import Plugins.Monitors.Net
 import Plugins.Monitors.Mem
@@ -40,7 +40,7 @@
 #endif
 #ifdef LIBMPD
 import Plugins.Monitors.MPD
-import Plugins.Monitors.Common (runMB)
+import Plugins.Monitors.Common (runMBD)
 #endif
 #ifdef ALSA
 import Plugins.Monitors.Volume
@@ -136,7 +136,7 @@
     start (MultiCpu a r) = startMultiCpu a r
     start (TopProc a r) = startTop a r
     start (TopMem a r) = runM a topMemConfig runTopMem r
-    start (Weather s a r) = runM (a ++ [s]) weatherConfig runWeather r
+    start (Weather s a r) = runMD (a ++ [s]) weatherConfig runWeather r weatherReady
     start (Thermal z a r) = runM (a ++ [z]) thermalConfig runThermal r
     start (ThermalZone z a r) =
       runM (a ++ [show z]) thermalZoneConfig runThermalZone r
@@ -155,8 +155,8 @@
     start (Wireless i a r) = runM (a ++ [i]) wirelessConfig runWireless r
 #endif
 #ifdef LIBMPD
-    start (MPD a r) = runM a mpdConfig runMPD r
-    start (AutoMPD a) = runMB a mpdConfig runMPD mpdWait
+    start (MPD a r) = runMD a mpdConfig runMPD r mpdReady
+    start (AutoMPD a) = runMBD a mpdConfig runMPD mpdWait mpdReady
 #endif
 #ifdef ALSA
     start (Volume m c a r) = runM a volumeConfig (runVolume m c) r
diff --git a/src/Plugins/Monitors/Batt.hs b/src/Plugins/Monitors/Batt.hs
--- a/src/Plugins/Monitors/Batt.hs
+++ b/src/Plugins/Monitors/Batt.hs
@@ -87,6 +87,7 @@
   , fNow :: String
   , fVoltage :: String
   , fCurrent :: String
+  , isCurrent :: Bool
   } | NoFiles
 
 data Battery = Battery
@@ -103,20 +104,21 @@
 batteryFiles bat =
   do is_charge <- exists "charge_now"
      is_energy <- if is_charge then return False else exists "energy_now"
-     is_current <- exists "current_now"
+     is_power <- exists "power_now"
      plain <- if is_charge then exists "charge_full" else exists "energy_full"
-     let cf = if is_current then "current_now" else "power_now"
+     let cf = if is_power then "power_now" else "current_now"
          sf = if plain then "" else "_design"
      return $ case (is_charge, is_energy) of
-       (True, _) -> files "charge" cf sf
-       (_, True) -> files "energy" cf sf
+       (True, _) -> files "charge" cf sf is_power
+       (_, True) -> files "energy" cf sf is_power
        _ -> NoFiles
   where prefix = sysDir </> bat
         exists = safeFileExist prefix
-        files ch cf sf = Files { fFull = prefix </> ch ++ "_full" ++ sf
-                               , fNow = prefix </> ch ++ "_now"
-                               , fCurrent = prefix </> cf
-                               , fVoltage = prefix </> "voltage_now" }
+        files ch cf sf ip = Files { fFull = prefix </> ch ++ "_full" ++ sf
+                                  , fNow = prefix </> ch ++ "_now"
+                                  , fCurrent = prefix </> cf
+                                  , fVoltage = prefix </> "voltage_now"
+                                  , isCurrent = not ip}
 
 haveAc :: FilePath -> IO Bool
 haveAc f =
@@ -129,9 +131,10 @@
     do a <- grab $ fFull files
        b <- grab $ fNow files
        d <- grab $ fCurrent files
-       return $ Battery (3600 * a / sc) -- wattseconds
-                        (3600 * b / sc) -- wattseconds
-                        (d / sc) -- watts
+       let sc' = if isCurrent files then sc / 10 else sc
+       return $ Battery (3600 * a / sc') -- wattseconds
+                        (3600 * b / sc') -- wattseconds
+                        (d / sc') -- watts
     where grab f = handle onError $ withFile f ReadMode (fmap read . hGetLine)
           onError = const (return (-1)) :: SomeException -> IO Float
 
diff --git a/src/Plugins/Monitors/Common.hs b/src/Plugins/Monitors/Common.hs
--- a/src/Plugins/Monitors/Common.hs
+++ b/src/Plugins/Monitors/Common.hs
@@ -23,7 +23,9 @@
                        , getConfigValue
                        , mkMConfig
                        , runM
+                       , runMD
                        , runMB
+                       , runMBD
                        , io
                        -- * Parsers
                        -- $parsers
@@ -178,11 +180,14 @@
     , Option "x" ["nastring"] (ReqArg NAString "N/A string") "String used when the monitor is not available"
     ]
 
-doArgs :: [String] -> ([String] -> Monitor String) -> Monitor String
-doArgs args action =
+doArgs :: [String] -> ([String] -> Monitor String) -> ([String] -> Monitor Bool) -> Monitor String
+doArgs args action detect =
     case getOpt Permute options args of
       (o, n, [])   -> do doConfigOptions o
-                         action n
+                         ready <- detect n
+                         if ready
+                            then action n
+                            else return "<Waiting...>"
       (_, _, errs) -> return (concat errs)
 
 doConfigOptions :: [Opts] -> Monitor ()
@@ -216,10 +221,18 @@
         -> (String -> IO ()) -> IO ()
 runM args conf action r = runMB args conf action (tenthSeconds r)
 
-runMB :: [String] -> IO MConfig -> ([String] -> Monitor String)
-         -> IO () -> (String -> IO ()) -> IO ()
-runMB args conf action wait cb = handle (cb . showException) loop
-  where ac = doArgs args action
+runMD :: [String] -> IO MConfig -> ([String] -> Monitor String) -> Int
+        -> ([String] -> Monitor Bool) -> (String -> IO ()) -> IO ()
+runMD args conf action r = runMBD args conf action (tenthSeconds r)
+
+runMB :: [String] -> IO MConfig -> ([String] -> Monitor String) -> IO ()
+        -> (String -> IO ()) -> IO ()
+runMB args conf action wait = runMBD args conf action wait (\_ -> return True)
+
+runMBD :: [String] -> IO MConfig -> ([String] -> Monitor String) -> IO ()
+        -> ([String] -> Monitor Bool) -> (String -> IO ()) -> IO ()
+runMBD args conf action wait detect cb = handle (cb . showException) loop
+  where ac = doArgs args action detect
         loop = conf >>= runReaderT ac >>= cb >> wait >> loop
 
 showException :: SomeException -> String
@@ -324,10 +337,10 @@
 combine _ [] = return []
 combine m ((s,ts,ss):xs) =
     do next <- combine m xs
-       let str = Map.findWithDefault err ts m
-           err = "<" ++ ts ++ " not found!>"
-       nstr <- parseTemplate' str m
-       return $ s ++ (if null nstr then str else nstr) ++ ss ++ next
+       str <- case Map.lookup ts m of
+         Nothing -> return $ "<" ++ ts ++ ">"
+         Just  r -> let f "" = r; f n = n; in fmap f $ parseTemplate' r m
+       return $ s ++ str ++ ss ++ next
 
 -- $strings
 
diff --git a/src/Plugins/Monitors/CoreCommon.hs b/src/Plugins/Monitors/CoreCommon.hs
--- a/src/Plugins/Monitors/CoreCommon.hs
+++ b/src/Plugins/Monitors/CoreCommon.hs
@@ -35,7 +35,8 @@
              => [String] -> Maybe (String, String -> Int)
              -> (Double -> a) -> (a -> String) -> Monitor (Maybe String)
 retrieveData path lbl trans fmt = do
-  pairs <- map snd . sortBy (compare `on` fst) <$> (mapM readFiles =<< findFiles path lbl)
+  pairs <- map snd . sortBy (compare `on` fst) <$>
+             (mapM readFiles =<< findFilesAndLabel path lbl)
   if null pairs
     then return Nothing
     else Just <$> (     parseTemplate
@@ -84,9 +85,9 @@
 
 -- | Function to find all files matching the given path and possible label file.
 -- The path must be absolute (start with a leading slash).
-findFiles :: [String] -> Maybe (String, String -> Int)
+findFilesAndLabel :: [String] -> Maybe (String, String -> Int)
           -> Monitor [(String, Either Int (String, String -> Int))]
-findFiles path lbl  =  catMaybes
+findFilesAndLabel path lbl  =  catMaybes
                    <$> (     mapM addLabel . zip [0..] . sort
                          =<< recFindFiles (pathComponents path) "/"
                        )
diff --git a/src/Plugins/Monitors/Disk.hs b/src/Plugins/Monitors/Disk.hs
--- a/src/Plugins/Monitors/Disk.hs
+++ b/src/Plugins/Monitors/Disk.hs
@@ -23,7 +23,8 @@
 import Control.Monad (zipWithM)
 import qualified Data.ByteString.Lazy.Char8 as B
 import Data.List (isPrefixOf, find)
-import System.Directory (canonicalizePath)
+import Data.Maybe (catMaybes)
+import System.Directory (canonicalizePath, doesFileExist)
 
 diskIOConfig :: IO MConfig
 diskIOConfig = mkMConfig "" ["total", "read", "write",
@@ -40,11 +41,15 @@
 mountedDevices :: [String] -> IO [(DevName, Path)]
 mountedDevices req = do
   s <- B.readFile "/etc/mtab"
-  parse `fmap` mapM canon (devs s)
+  parse `fmap` mapM mbcanon (devs s)
   where
+    mbcanon (d, p) = doesFileExist d >>= \e ->
+                     if e
+                        then Just `fmap` canon (d,p)
+                        else return Nothing
     canon (d, p) = do {d' <- canonicalizePath d; return (d', p)}
     devs = filter isDev . map (firstTwo . B.words) . B.lines
-    parse = map undev . filter isReq
+    parse = map undev . filter isReq . catMaybes
     firstTwo (a:b:_) = (B.unpack a, B.unpack b)
     firstTwo _ = ("", "")
     isDev (d, _) = "/dev/" `isPrefixOf` d
diff --git a/src/Plugins/Monitors/MPD.hs b/src/Plugins/Monitors/MPD.hs
--- a/src/Plugins/Monitors/MPD.hs
+++ b/src/Plugins/Monitors/MPD.hs
@@ -12,12 +12,13 @@
 --
 -----------------------------------------------------------------------------
 
-module Plugins.Monitors.MPD ( mpdConfig, runMPD, mpdWait ) where
+module Plugins.Monitors.MPD ( mpdConfig, runMPD, mpdWait, mpdReady ) where
 
 import Data.List
 import Plugins.Monitors.Common
 import System.Console.GetOpt
 import qualified Network.MPD as M
+import Control.Concurrent (threadDelay)
 
 mpdConfig :: IO MConfig
 mpdConfig = mkMConfig "MPD: <state>"
@@ -50,16 +51,29 @@
 runMPD :: [String] -> Monitor String
 runMPD args = do
   opts <- io $ mopts args
-  let mpd = M.withMPD
-  status <- io $ mpd M.status
-  song <- io $ mpd M.currentSong
+  status <- io $ M.withMPD M.status
+  song <- io $ M.withMPD M.currentSong
   s <- parseMPD status song opts
   parseTemplate s
 
 mpdWait :: IO ()
-mpdWait = M.withMPD idle >> return ()
-  where idle = M.idle [M.PlayerS, M.MixerS]
+mpdWait = do
+  status <- M.withMPD $ M.idle [M.PlayerS, M.MixerS]
+  case status of
+    Left _ -> threadDelay 10000000
+    _ -> return ()
 
+mpdReady :: [String] -> Monitor Bool
+mpdReady _ = do
+  response <- io $ M.withMPD M.ping
+  case response of
+    Right _         -> return True
+    -- Only cases where MPD isn't responding is an issue; bogus information at
+    -- least won't hold xmobar up.
+    Left M.NoMPD    -> return False
+    Left M.TimedOut -> return False
+    Left _          -> return True
+
 mopts :: [String] -> IO MOpts
 mopts argv =
   case getOpt Permute options argv of
@@ -68,7 +82,7 @@
 
 parseMPD :: M.Response M.Status -> M.Response (Maybe M.Song) -> MOpts
             -> Monitor [String]
-parseMPD (Left e) _ _ = return $ show e:repeat ""
+parseMPD (Left e) _ _ = return $ show e:replicate 18 ""
 parseMPD (Right st) song opts = do
   songData <- parseSong song
   bar <- showPercentBar (100 * b) b
diff --git a/src/Plugins/Monitors/Mem.hs b/src/Plugins/Monitors/Mem.hs
--- a/src/Plugins/Monitors/Mem.hs
+++ b/src/Plugins/Monitors/Mem.hs
@@ -15,6 +15,7 @@
 module Plugins.Monitors.Mem (memConfig, runMem, totalMem, usedMem) where
 
 import Plugins.Monitors.Common
+import qualified Data.Map as M
 
 memConfig :: IO MConfig
 memConfig = mkMConfig
@@ -28,10 +29,11 @@
 parseMEM :: IO [Float]
 parseMEM =
     do file <- fileMEM
-       let content = map words $ take 4 $ lines file
-           [total, free, buffer, cache] = map (\line -> (read $ line !! 1 :: Float) / 1024) content
+       let content = map words $ take 8 $ lines file
+           info = M.fromList $ map (\line -> (line !! 0, (read $ line !! 1 :: Float) / 1024)) content
+           [total, free, buffer, cache] = map (info M.!) ["MemTotal:", "MemFree:", "Buffers:", "Cached:"]
            rest = free + buffer + cache
-           used = total - rest
+           used = total - (M.findWithDefault rest "MemAvailable:" info)
            usedratio = used / total
            freeratio = free / total
        return [usedratio, freeratio, total, free, buffer, cache, rest, used, freeratio]
diff --git a/src/Plugins/Monitors/Top.hs b/src/Plugins/Monitors/Top.hs
--- a/src/Plugins/Monitors/Top.hs
+++ b/src/Plugins/Monitors/Top.hs
@@ -57,10 +57,15 @@
 processes = fmap (filter isPid) (getDirectoryContents "/proc")
   where isPid = (`elem` ['0'..'9']) . head
 
+statWords :: [String] -> [String]
+statWords line@(x:pn:ppn:xs) =
+  if last pn == ')' then line else statWords (x:(pn ++ " " ++ ppn):xs)
+statWords _ = replicate 52 "0"
+
 getProcessData :: FilePath -> IO [String]
 getProcessData pidf =
   handle ign $ withFile ("/proc" </> pidf </> "stat") ReadMode readWords
-  where readWords = fmap words . hGetLine
+  where readWords = fmap (statWords . words) . hGetLine
         ign = const (return []) :: SomeException -> IO [String]
 
 handleProcesses :: ([String] -> a) -> IO [a]
diff --git a/src/Plugins/Monitors/Volume.hs b/src/Plugins/Monitors/Volume.hs
--- a/src/Plugins/Monitors/Volume.hs
+++ b/src/Plugins/Monitors/Volume.hs
@@ -110,11 +110,13 @@
 runVolume :: String -> String -> [String] -> Monitor String
 runVolume mixerName controlName argv = do
     opts <- io $ parseOpts argv
-    control <- io $ getControlByName mixerName controlName
-    (lo, hi) <- io . liftMaybe $ getRange <$> volumeControl control
-    val <- getVal $ volumeControl control
-    db <- getDB $ volumeControl control
-    sw <- getSw $ switchControl control
+    (lo, hi, val, db, sw) <- io $ withMixer mixerName $ \mixer -> do
+        control <- getControlByName mixer controlName
+        (lo, hi) <- liftMaybe $ getRange <$> volumeControl control
+        val <- getVal $ volumeControl control
+        db <- getDB $ volumeControl control
+        sw <- getSw $ switchControl control
+        return (lo, hi, val, db, sw)
     p <- liftMonitor $ liftM3 formatVol lo hi val
     b <- liftMonitor $ liftM3 formatVolBar lo hi val
     d <- getFormatDB opts db
@@ -138,18 +140,18 @@
     liftMonitor Nothing = unavailable
     liftMonitor (Just m) = m
 
-    getDB :: Maybe Volume -> Monitor (Maybe Integer)
+    getDB :: Maybe Volume -> IO (Maybe Integer)
     getDB Nothing = return Nothing
-    getDB (Just v) = io $ AE.catch (getChannel FrontLeft $ dB v)
-                                   (const $ return $ Just 0)
+    getDB (Just v) = AE.catch (getChannel FrontLeft $ dB v)
+                              (const $ return $ Just 0)
 
-    getVal :: Maybe Volume -> Monitor (Maybe Integer)
+    getVal :: Maybe Volume -> IO (Maybe Integer)
     getVal Nothing = return Nothing
-    getVal (Just v) = io $ getChannel FrontLeft $ value v
+    getVal (Just v) = getChannel FrontLeft $ value v
 
-    getSw :: Maybe Switch -> Monitor (Maybe Bool)
+    getSw :: Maybe Switch -> IO (Maybe Bool)
     getSw Nothing = return Nothing
-    getSw (Just s) = io $ getChannel FrontLeft s
+    getSw (Just s) = getChannel FrontLeft s
 
     getFormatDB :: VolumeOpts -> Maybe Integer -> Monitor String
     getFormatDB _ Nothing = unavailable
diff --git a/src/Plugins/Monitors/Weather.hs b/src/Plugins/Monitors/Weather.hs
--- a/src/Plugins/Monitors/Weather.hs
+++ b/src/Plugins/Monitors/Weather.hs
@@ -16,10 +16,8 @@
 
 import Plugins.Monitors.Common
 
-import Control.Monad (when)
-import System.Process
-import System.Exit
-import System.IO
+import Control.Exception (catch, IOException)
+import Network.HTTP
 
 import Text.ParserCombinators.Parsec
 
@@ -129,20 +127,15 @@
 defUrl :: String
 defUrl = "http://weather.noaa.gov/pub/data/observations/metar/decoded/"
 
+stationUrl :: String -> String
+stationUrl station = defUrl ++ station ++ ".TXT"
+
 getData :: String -> IO String
-getData url=
-        do (i,o,e,p) <- runInteractiveCommand ("curl " ++ defUrl ++ url ++ ".TXT")
-           exit <- waitForProcess p
-           let closeHandles = do hClose o
-                                 hClose i
-                                 hClose e
-           case exit of
-             ExitSuccess -> do str <- hGetContents o
-                               when (str == str) $ return ()
-                               closeHandles
-                               return str
-             _ -> do closeHandles
-                     return "Could not retrieve data"
+getData station = do
+    let request = getRequest (stationUrl station)
+    catch (simpleHTTP request >>= getResponseBody) errHandler
+    where errHandler :: IOException -> IO String
+          errHandler _ = return "<Could not retrieve data>"
 
 formatWeather :: [WeatherInfo] -> Monitor String
 formatWeather [(WI st ss y m d h w v sk tC tF dp r p)] =
@@ -156,3 +149,21 @@
     do d <- io $ getData $ head str
        i <- io $ runP parseData d
        formatWeather i
+
+weatherReady :: [String] -> Monitor Bool
+weatherReady str = do
+    let station = head str
+        request = headRequest (stationUrl station)
+    io $ catch (simpleHTTP request >>= checkResult) errHandler
+    where errHandler :: IOException -> IO Bool
+          errHandler _ = return False
+          checkResult result = do
+            case result of
+                Left _ -> return False
+                Right response -> do
+                    case rspCode response of
+                        -- Permission or network errors are failures; anything
+                        -- else is recoverable.
+                        (4, _, _) -> return False
+                        (5, _, _) -> return False
+                        (_, _, _) -> return True
diff --git a/src/Signal.hs b/src/Signal.hs
--- a/src/Signal.hs
+++ b/src/Signal.hs
@@ -22,6 +22,7 @@
 import Control.Concurrent.STM
 import Control.Exception hiding (handle)
 import System.Posix.Signals
+import Graphics.X11.Types (Button)
 import Graphics.X11.Xlib.Types (Position)
 
 #ifdef DBUS
@@ -41,7 +42,7 @@
                 | Reveal Int
                 | Toggle Int
                 | TogglePersistent
-                | Action Position
+                | Action Button Position
     deriving (Read, Show)
 
 #ifdef DBUS
diff --git a/src/Window.hs b/src/Window.hs
--- a/src/Window.hs
+++ b/src/Window.hs
@@ -22,7 +22,9 @@
 import Graphics.X11.Xinerama
 import Foreign.C.Types (CLong)
 
-import Data.Maybe(fromMaybe)
+import Data.Function (on)
+import Data.List (maximumBy)
+import Data.Maybe (fromMaybe)
 import System.Posix.Process (getProcessID)
 
 import Config
@@ -72,8 +74,8 @@
     OnScreen _ p'' -> setPosition p'' [scr] ht
   where
     (scr@(Rectangle rx ry rw rh), p') =
-      case p of OnScreen i x -> (fromMaybe (head rs) $ safeIndex i rs, x)
-                _ -> (head rs, p)
+      case p of OnScreen i x -> (fromMaybe (broadest rs) $ safeIndex i rs, x)
+                _ -> (broadest rs, p)
     ny = ry + fi (rh - ht)
     center i = rx + fi (div (remwid i) 2)
     right  i = rx + fi (remwid i)
@@ -87,6 +89,7 @@
     mh h' = max (fi h') h
     ny' h' = ry + fi (rh - mh h')
     safeIndex i = lookup i . zip [0..]
+    broadest = maximumBy (compare `on` rect_width)
 
 setProperties :: Config -> Display -> Window -> IO ()
 setProperties c d w = do
diff --git a/src/Xmobar.hs b/src/Xmobar.hs
--- a/src/Xmobar.hs
+++ b/src/Xmobar.hs
@@ -122,7 +122,7 @@
             ConfigureEvent {} -> atomically $ putTMVar signal Reposition
             ExposeEvent {} -> atomically $ putTMVar signal Wakeup
             RRScreenChangeNotifyEvent {} -> atomically $ putTMVar signal Reposition
-            ButtonEvent {} -> atomically $ putTMVar signal (Action (fi $ ev_x ev))
+            ButtonEvent {} -> atomically $ putTMVar signal (Action (ev_button ev) (fi $ ev_x ev))
             _ -> return ()
 
 -- | Send signal to eventLoop every time a var is updated
@@ -144,7 +144,7 @@
 
 
 -- | Continuously wait for a signal from a thread or a interrupt handler
-eventLoop :: TVar [String] -> XConf -> [(Action, Position, Position)] -> TMVar SignalType -> IO ()
+eventLoop :: TVar [String] -> XConf -> [([Action], Position, Position)] -> TMVar SignalType -> IO ()
 eventLoop tv xc@(XConf d r w fs is cfg) as signal = do
       typ <- atomically $ takeTMVar signal
       case typ of
@@ -169,7 +169,7 @@
          TogglePersistent -> eventLoop
             tv xc { config = cfg { persistent = not $ persistent cfg } } as signal
 
-         Action x -> action x
+         Action but x -> action but x
 
     where
         isPersistent = not $ persistent cfg
@@ -211,8 +211,12 @@
             o ->
               return (ocfg {position = OnScreen 1 o})
 
-        action x = do mapM_ (\(a,_,_) -> runAction a) $ filter (\(_, from, to) -> x >= from && x <= to) as
-                      eventLoop tv xc as signal
+        action button x = do
+          mapM_ runAction $
+            filter (\(Spawn b _) -> button `elem` b) $
+            concatMap (\(a,_,_) -> a) $
+            filter (\(_, from, to) -> x >= from && x <= to) as
+          eventLoop tv xc as signal
 
 -- $command
 
@@ -233,17 +237,17 @@
                            return (Just h,var)
     where is = s ++ "Updating..." ++ ss
 
-updateString :: Config -> TVar [String] -> IO [[(Widget, String, Maybe Action)]]
+updateString :: Config -> TVar [String] -> IO [[(Widget, String, Maybe [Action])]]
 updateString conf v = do
   s <- atomically $ readTVar v
   let l:c:r:_ = s ++ repeat ""
   io $ mapM (parseString conf) [l, c, r]
 
-updateActions :: XConf -> Rectangle -> [[(Widget, String, Maybe Action)]] ->
-                 IO [(Action, Position, Position)]
+updateActions :: XConf -> Rectangle -> [[(Widget, String, Maybe [Action])]] ->
+                 IO [([Action], Position, Position)]
 updateActions conf (Rectangle _ _ wid _) ~[left,center,right] = do
   let (d,fs) = (display &&& fontS) conf
-      strLn :: [(Widget, String, Maybe Action)] -> IO [(Maybe Action, Position, Position)]
+      strLn :: [(Widget, String, Maybe [Action])] -> IO [(Maybe [Action], Position, Position)]
       strLn  = io . mapM getCoords
       iconW i = maybe 0 Bitmap.width (lookup i $ iconS conf)
       getCoords (Text s,_,a) = textWidth d fs s >>= \tw -> return (a, 0, fi tw)
@@ -266,7 +270,7 @@
 -- $print
 
 -- | Draws in and updates the window
-drawInWin :: Rectangle -> [[(Widget, String, Maybe Action)]] -> X ()
+drawInWin :: Rectangle -> [[(Widget, String, Maybe [Action])]] -> X ()
 drawInWin (Rectangle _ _ wid ht) ~[left,center,right] = do
   r <- ask
   let (c,d ) = (config &&& display) r
diff --git a/xmobar.cabal b/xmobar.cabal
--- a/xmobar.cabal
+++ b/xmobar.cabal
@@ -1,5 +1,5 @@
 name:               xmobar
-version:            0.19
+version:            0.20
 homepage:           http://projects.haskell.org/xmobar/
 bug-reports:        http://code.google.com/p/xmobar/issues
 synopsis:           A Minimalistic Text Based Status Bar
@@ -108,6 +108,7 @@
       X11 >= 1.6.1,
       mtl >= 2.0 && < 2.2,
       parsec == 3.1.*,
+      HTTP >= 4000,
       stm >= 2.3 && < 2.5
 
     if flag(with_threaded)
@@ -145,7 +146,7 @@
        cpp-options: -DLIBMPD
 
     if flag(with_alsa) || flag(all_extensions)
-       build-depends: alsa-mixer == 0.1.*
+       build-depends: alsa-mixer == 0.2.*
        build-depends: alsa-core == 0.5.*
        other-modules: Plugins.Monitors.Volume
        cpp-options: -DALSA
