diff --git a/news.md b/news.md
--- a/news.md
+++ b/news.md
@@ -1,5 +1,21 @@
 % xmobar - Release notes
 
+## Version 0.23.1 (Apr 14, 2015)
+
+_Bug fixes_
+
+  - Vertical alignment for icons, [issue #216]
+  - Improvements to vertical text alignment, with many thanks to Jan
+    Palus (see ongoing discussion in [issue #221]).
+  - Better error handling in `Volume` monitor, [issue #215]
+  - Compilation with ghc 7.8 and 7.10 (thanks to Edward Tjörnhammar,
+    see [issue #225]).
+
+[issue #225]: https://github.com/jaor/xmobar/issues/225
+[issue #221]: https://github.com/jaor/xmobar/issues/221
+[issue #216]: https://github.com/jaor/xmobar/issues/216
+[issue #215]: https://github.com/jaor/xmobar/issues/215
+
 ## Version 0.23 (Mar 8, 2015)
 
 _New features_
diff --git a/readme.md b/readme.md
--- a/readme.md
+++ b/readme.md
@@ -10,7 +10,7 @@
 features, like dynamic color management, icons, output templates, and
 extensibility through plugins.
 
-This page documents xmobar 0.23 (see [release notes]).
+This page documents xmobar 0.23.1 (see [release notes]).
 
 [This screenshot] shows xmobar running under [sawfish], with
 antialiased fonts. And [this one] is my desktop with [xmonad] and two
@@ -198,16 +198,17 @@
 - `<fc=#FF0000>string</fc>` will print `string` with `#FF0000` color
   (red).
 
-- `<fn=1>string</fn>` will print `string` with the first font from `additionalFonts`.
-  The index `0` corresponds to the standard font.
+- `<fn=1>string</fn>` will print `string` with the first font from
+  `additionalFonts`.  The index `0` corresponds to the standard font.
 
 - `<icon=/path/to/icon.xbm/>` will insert the given bitmap. XPM image
   format is also supported when compiled with `--flags="with_xpm"`.
 
-- ```<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.
+- ```<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.
 
 - `<raw=len:str/>` allows the encapsulation of arbitrary text `str` (which
   must be `len` `Char`s long, where `len` is encoded as a decimal sequence).
@@ -219,8 +220,7 @@
 
   and receives on standard input the line
 
-    ```<action=`echo test` button=1><raw=41:<action=`echo mooo`
-button=1>foo</action>/></action>```
+    ```<action=`echo test` button=1><raw=41:<action=`echo mooo` button=1>foo</action>/></action>```
 
   then it will display the text ```<action=`echo mooo` button=1>foo</action>```,
   which, when clicked, will cause `test` to be echoed.
@@ -1527,9 +1527,9 @@
 Perner, Jens Petersen, Alexander Polakov, Petr Rockai, Andrew
 Sackville-West, Markus Scherer, Alexander Shabalin, Peter Simons,
 Alexander Solovyov, John Soros, Travis Staton, Artem Tarasov, Samuli
-Thomasson, Sergei Trofimovich, Thomas Tuegel, Jan Vornberger, Anton
-Vorontsov, Daniel Wagner, Phil Xiaojun Hu, Edward Z. Yang and Norbert
-Zeh.
+Thomasson, Edward Tjörnhammar, Sergei Trofimovich, Thomas Tuegel, Jan
+Vornberger, Anton Vorontsov, Daniel Wagner, Phil Xiaojun Hu, Edward
+Z. Yang and Norbert Zeh.
 
 [jao]: http://jao.io
 [incorporates patches]: http://www.ohloh.net/p/xmobar/contributors
diff --git a/src/Bitmap.hs b/src/Bitmap.hs
--- a/src/Bitmap.hs
+++ b/src/Bitmap.hs
@@ -2,7 +2,7 @@
 -----------------------------------------------------------------------------
 -- |
 -- Module      :  Bitmap
--- Copyright   :  (C) 2013 Alexander Polakov
+-- Copyright   :  (C) 2013, 2015 Alexander Polakov
 -- License     :  BSD3
 --
 -- Maintainer  :  jao@gnu.org
@@ -16,7 +16,6 @@
  , drawBitmap
  , Bitmap(..)) where
 
-import Control.Applicative((<|>))
 import Control.Monad
 import Control.Monad.Trans(MonadIO(..))
 import Data.Map hiding (foldr, map, filter)
@@ -30,6 +29,7 @@
 
 #ifdef XPM
 import XPMFile(readXPMFile)
+import Control.Applicative((<|>))
 #endif
 
 #if MIN_VERSION_mtl(2, 2, 1)
diff --git a/src/Localize.hsc b/src/Localize.hsc
--- a/src/Localize.hsc
+++ b/src/Localize.hsc
@@ -19,7 +19,11 @@
     ) where
 
 import Foreign.C
+#if ! MIN_VERSION_time(1,5,0)
 import qualified System.Locale as L
+#else
+import qualified Data.Time.Format as L
+#endif
 
 #ifdef UTF8
 import Codec.Binary.UTF8.String
diff --git a/src/Plugins/Date.hs b/src/Plugins/Date.hs
--- a/src/Plugins/Date.hs
+++ b/src/Plugins/Date.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE CPP #-}
 -----------------------------------------------------------------------------
 -- |
 -- Module      :  Plugins.Date
@@ -20,7 +21,9 @@
 
 import Plugins
 
+#if ! MIN_VERSION_time(1,5,0)
 import System.Locale
+#endif
 import Control.Monad (liftM)
 import Data.Time
 
diff --git a/src/Plugins/DateZone.hs b/src/Plugins/DateZone.hs
--- a/src/Plugins/DateZone.hs
+++ b/src/Plugins/DateZone.hs
@@ -31,12 +31,14 @@
 import System.IO.Unsafe
 
 import Localize
-import Data.Time.LocalTime
 import Data.Time.Format
+import Data.Time.LocalTime
 import Data.Time.LocalTime.TimeZone.Olson
 import Data.Time.LocalTime.TimeZone.Series
 
+#if ! MIN_VERSION_time(1,5,0)
 import System.Locale (TimeLocale)
+#endif
 #else
 import System.IO
 import Plugins.Date
diff --git a/src/Plugins/EWMH.hs b/src/Plugins/EWMH.hs
--- a/src/Plugins/EWMH.hs
+++ b/src/Plugins/EWMH.hs
@@ -1,5 +1,5 @@
 {-# OPTIONS_GHC -w #-}
-{-# LANGUAGE CPP, NamedFieldPuns, GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE CPP, NamedFieldPuns, GeneralizedNewtypeDeriving, FlexibleContexts #-}
 
 -----------------------------------------------------------------------------
 -- |
@@ -17,6 +17,7 @@
 
 module Plugins.EWMH (EWMH(..)) where
 
+import Control.Applicative (Applicative(..))
 import Control.Monad.State
 import Control.Monad.Reader
 import Graphics.X11 hiding (Modifier, Color)
@@ -176,7 +177,7 @@
                  , ("_NET_WM_DESKTOP", updateDesktop) ]
 
 newtype M a = M (ReaderT EwmhConf (StateT EwmhState IO) a)
-    deriving (Monad, Functor, MonadIO, MonadReader EwmhConf, MonadState EwmhState)
+    deriving (Monad, Functor, Applicative, MonadIO, MonadReader EwmhConf, MonadState EwmhState)
 
 execM :: M a -> IO a
 execM (M m) = do
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
@@ -1,7 +1,7 @@
 -----------------------------------------------------------------------------
 -- |
 -- Module      :  Plugins.Monitors.Volume
--- Copyright   :  (c) 2011, 2013 Thomas Tuegel
+-- Copyright   :  (c) 2011, 2013, 2015 Thomas Tuegel
 -- License     :  BSD-style (see LICENSE)
 --
 -- Maintainer  :  Jose A. Ortega Ruiz <jao@gnu.org>
@@ -122,13 +122,7 @@
 runVolume :: String -> String -> [String] -> Monitor String
 runVolume mixerName controlName argv = do
     opts <- io $ parseOpts argv
-    (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)
+    (lo, hi, val, db, sw) <- io readMixer
     p <- liftMonitor $ liftM3 formatVol lo hi val
     b <- liftMonitor $ liftM3 formatVolBar lo hi val
     v <- liftMonitor $ liftM3 formatVolVBar lo hi val
@@ -139,6 +133,16 @@
 
   where
 
+    readMixer =
+      AE.catch (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))
+                (const $ return (Nothing, Nothing, Nothing, Nothing, Nothing))
+
     volumeControl :: Maybe Control -> Maybe Volume
     volumeControl c = join $
            (playback . volume <$> c) `mplus` (common . volume <$> c)
@@ -154,18 +158,19 @@
     liftMonitor Nothing = unavailable
     liftMonitor (Just m) = m
 
+    channel v r = AE.catch (getChannel FrontLeft v) (const $ return $ Just r)
+
     getDB :: Maybe Volume -> IO (Maybe Integer)
     getDB Nothing = return Nothing
-    getDB (Just v) = AE.catch (getChannel FrontLeft $ dB v)
-                              (const $ return $ Just 0)
+    getDB (Just v) = channel (dB v) 0
 
     getVal :: Maybe Volume -> IO (Maybe Integer)
     getVal Nothing = return Nothing
-    getVal (Just v) = getChannel FrontLeft $ value v
+    getVal (Just v) = channel (value v) 0
 
     getSw :: Maybe Switch -> IO (Maybe Bool)
     getSw Nothing = return Nothing
-    getSw (Just s) = getChannel FrontLeft s
+    getSw (Just s) = channel s False
 
     getFormatDB :: VolumeOpts -> Maybe Integer -> Monitor String
     getFormatDB _ Nothing = unavailable
diff --git a/src/Window.hs b/src/Window.hs
--- a/src/Window.hs
+++ b/src/Window.hs
@@ -1,7 +1,7 @@
 -----------------------------------------------------------------------------
 -- |
 -- Module      :  Window
--- Copyright   :  (c) 2011-14 Jose A. Ortega Ruiz
+-- Copyright   :  (c) 2011-15 Jose A. Ortega Ruiz
 --             :  (c) 2012 Jochen Keil
 -- License     :  BSD-style (see LICENSE)
 --
@@ -171,15 +171,18 @@
   TopB       -> drawBorder (TopBM 0) lw d p gc c wi ht
   BottomB    -> drawBorder (BottomBM 0) lw d p gc c wi ht
   FullB      -> drawBorder (FullBM 0) lw d p gc c wi ht
-  TopBM m    -> sf >> sla >> drawLine d p gc 0 (fi m + boff) (fi wi) (fi m + boff)
+  TopBM m    -> sf >> sla >>
+                 drawLine d p gc 0 (fi m + boff) (fi wi) (fi m + boff)
   BottomBM m -> let rw = fi ht - fi m + boff in
                  sf >> sla >> drawLine d p gc 0 rw (fi wi) rw
-  FullBM m   -> let pad = 2 * fi m + 2 * fi boff'; mp = fi m + fi boff' in
-                 sf >> sla >> drawRectangle d p gc mp mp (wi - pad) (ht - pad)
+  FullBM m   -> let mp = fi m
+                    pad = 2 * fi mp +  fi lw
+                in sf >> sla >>
+                     drawRectangle d p gc mp mp (wi - pad + 1) (ht - pad)
   where sf    = setForeground d gc c
         sla   = setLineAttributes d gc (fi lw) lineSolid capNotLast joinMiter
         boff  = borderOffset b lw
-        boff' = calcBorderOffset lw :: Int
+--        boff' = calcBorderOffset lw :: Int
 
 hideWindow :: Display -> Window -> IO ()
 hideWindow d w = do
@@ -209,4 +212,3 @@
 calcBorderOffset :: (Integral a) => Int -> a
 calcBorderOffset = ceiling . (/2) . toDouble
   where toDouble = fi :: (Integral a) => a -> Double
-
diff --git a/src/XUtil.hsc b/src/XUtil.hsc
--- a/src/XUtil.hsc
+++ b/src/XUtil.hsc
@@ -184,9 +184,8 @@
     when (al == 255) $ do
       (a,d)  <- textExtents fs s
       gi <- xftTxtExtents' dpy fonts s
-      drawXftRect draw bc' (x + 1 - fi (xglyphinfo_x gi))
-                  (y - (a + d) + 1) (xglyphinfo_xOff gi) (a + d)
-    (drawXftString' draw fc' fonts (toInteger x) (toInteger (y - 2)) s)
+      drawXftRect draw bc' x (y - a + 1) (xglyphinfo_xOff gi) (a + d + 1)
+    drawXftString' draw fc' fonts (toInteger x) (toInteger y) s
 #endif
 
 
diff --git a/src/Xmobar.hs b/src/Xmobar.hs
--- a/src/Xmobar.hs
+++ b/src/Xmobar.hs
@@ -202,7 +202,7 @@
             eventLoop tv xc as signal
 
         reposWindow rcfg = do
-          r' <- repositionWin d w (fs!!0) rcfg
+          r' <- repositionWin d w (head fs) rcfg
           eventLoop tv (XConf d r' w fs is rcfg) as signal
 
         updateConfigPosition ocfg =
@@ -306,7 +306,7 @@
     printStrings p gc fs 1 L =<< strLn left
     printStrings p gc fs 1 R =<< strLn right
     printStrings p gc fs 1 C =<< strLn center
-    -- draw 1 pixel border if requested
+    -- draw border if requested
     io $ drawBorder (border c) (borderWidth c) d p gc bdcolor wid ht
     -- copy the pixmap with the new string to the window
     io $ copyArea d p w gc 0 0 wid ht 0 0
@@ -316,20 +316,17 @@
     -- resync
     io $ sync d True
 
-verticalOffset ::  (Integral b, Integral a, MonadIO m) =>
-                   a -> Widget -> XFont -> Config -> m b
+verticalOffset :: (Integral b, Integral a, MonadIO m) =>
+                  a -> Widget -> XFont -> Config -> m b
 verticalOffset ht (Text t) fontst conf
   | textOffset conf > -1 = return $ fi (textOffset conf)
   | otherwise = do
      (as,ds) <- io $ textExtents fontst t
-     let bwidth = borderOffset (border conf) (borderWidth conf)
-         verticalMargin = fi ht - fi (as + ds) - 2 * fi (abs bwidth)
-     return $ fi ht - fi ds - (verticalMargin `div` 2) + bwidth + 1
-verticalOffset _ (Icon _) _ conf
+     let margin = (fi ht - fi ds - fi as) `div` 2
+     return $ fi as + margin - 1
+verticalOffset ht (Icon _) _ conf
   | iconOffset conf > -1 = return $ fi (iconOffset conf)
-  | otherwise = do
-     let bwidth = borderOffset (border conf) (borderWidth conf)
-     return $ bwidth + 1
+  | otherwise = return $ fi (ht `div` 2) - 1
 
 -- | An easy way to print the stuff we need to print
 printStrings :: Drawable -> GC -> [XFont] -> Position
diff --git a/xmobar.cabal b/xmobar.cabal
--- a/xmobar.cabal
+++ b/xmobar.cabal
@@ -1,5 +1,5 @@
 name:               xmobar
-version:            0.23
+version:            0.23.1
 homepage:           http://xmobar.org
 synopsis:           A Minimalistic Text Based Status Bar
 description: 	    Xmobar is a minimalistic text based status bar.
@@ -128,12 +128,12 @@
        cpp-options: -DGHC6
 
     if flag(with_xft) || flag(all_extensions)
-       build-depends: utf8-string == 0.3.*, X11-xft >= 0.2 && < 0.4
+       build-depends: utf8-string >= 0.3 && < 1.1, X11-xft >= 0.2 && < 0.4
        other-modules: MinXft
        cpp-options: -DXFT
 
     if flag(with_utf8) || flag(all_extensions)
-       build-depends: utf8-string == 0.3.*
+       build-depends: utf8-string >= 0.3 && < 1.1
        cpp-options: -DUTF8
 
     if flag(with_inotify) || flag(all_extensions)
