summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--NEWS4
-rw-r--r--README22
-rw-r--r--src/Config.hs3
-rw-r--r--src/Parsers.hs3
-rw-r--r--src/Plugins/Kbd.hsc397
-rw-r--r--src/Plugins/Monitors/Volume.hs5
-rw-r--r--src/XUtil.hsc2
-rw-r--r--xmobar.cabal10
8 files changed, 434 insertions, 12 deletions
diff --git a/NEWS b/NEWS
index 72b4ea9..05a98f7 100644
--- a/NEWS
+++ b/NEWS
@@ -7,6 +7,7 @@ _New features_
- New brightness monitor, courtesy of Martin Perner.
- New DateZone plugin, for localized datetimes, also by Martin.
+ - New keyboard layout monitor (Kbd). Yes, by Martin.
- Rewrite of the event handling ([issue 53], [issue 57]), also by Martin.
- Cpu monitor now also reports `iowait` field ([issue 55]).
@@ -18,6 +19,9 @@ _Bug fixes_
- Catch errors when reading battery status (Ben Boeckel).
- Compilation issues with ghc 7.x (Sergei Trofimovich).
- Fixes for CoreTemp monitor in new kernels (Norbert Zeh).
+ - Fix for pulseaudio problems in volume monitor (Martin Perner).
+ - Fix for parsing errors when a `Run` entry ended in an array
+ (Martin).
[issue 48]: http://code.google.com/p/xmobar/issues/detail?id=48
[issue 50]: http://code.google.com/p/xmobar/issues/detail?id=50
diff --git a/README b/README
index 55254a6..c4bf6c8 100644
--- a/README
+++ b/README
@@ -611,10 +611,12 @@ Monitors have default aliases.
- `--lowd` _number_ Low threshold for dB. Defaults to -30.0.
- Variables that can be used with the `-t`/`--template` argument:
`volume`, `volumebar`, `dB`, `status`
+- Note that `dB` might only return 0 on your system. This is known
+ to happen on systems with a pulseaudio backend.
- Default template: `Vol: <volume>% <status>`
-- Requires the package [alsa-mixer] installed in your system. In addition,
- to activate this plugin you must pass `--flags="with_alsa"` during
- compilation.
+- Requires the package [alsa-core] and [alsa-mixer] installed in your
+ system. In addition, to activate this plugin you must pass
+ `--flags="with_alsa"` during compilation.
`MPD Args RefreshRate`
@@ -689,6 +691,8 @@ Monitors have default aliases.
distribution can be used to set the given property from the output
of any other program or script.
+[samples/xmonadpropwrite.hs script]: https://github.com/jaor/xmobar/raw/master/samples/xmonadpropwrite.hs
+
`Brightness Args RefreshRate`
- Aliases to `bright`
@@ -706,8 +710,18 @@ Monitors have default aliases.
Run Brightness ["-t", "<bar>"] 60
+`Kbd Opts`
+
+- Registers to XKB/X11-Events and output the currently active keyboard layout.
+ Supports replacement of layoutnames.
+- Aliases to `kbd`
+- Opts is a list of tuple:
+ - first element of the tuple is the search string
+ - second element of the tuple is the corresponding replacement
+- Example:
+
+ Run Kbd [("us(dvorak)", "DV"), ("us", "US")]
-[samples/xmonadpropwrite.hs script]: https://github.com/jaor/xmobar/raw/master/samples/xmonadpropwrite.hs
## Monitor Plugins Commands Arguments
diff --git a/src/Config.hs b/src/Config.hs
index 3184023..4405314 100644
--- a/src/Config.hs
+++ b/src/Config.hs
@@ -32,6 +32,7 @@ import Plugins.CommandReader
import Plugins.StdinReader
import Plugins.XMonadLog
import Plugins.EWMH
+import Plugins.Kbd
#ifdef INOTIFY
import Plugins.Mail
@@ -112,7 +113,7 @@ infixr :*:
-- the 'Runnable.Runnable' Read instance. To install a plugin just add
-- the plugin's type to the list of types (separated by ':*:') appearing in
-- this function's type signature.
-runnableTypes :: Command :*: Monitors :*: Date :*: PipeReader :*: CommandReader :*: StdinReader :*: XMonadLog :*: EWMH :*:
+runnableTypes :: Command :*: Monitors :*: Date :*: PipeReader :*: CommandReader :*: StdinReader :*: XMonadLog :*: EWMH :*: Kbd :*:
#ifdef INOTIFY
Mail :*: MBox :*:
#endif
diff --git a/src/Parsers.hs b/src/Parsers.hs
index baaa287..f5f00a9 100644
--- a/src/Parsers.hs
+++ b/src/Parsers.hs
@@ -159,7 +159,8 @@ parseConfig = runParser parseConf fields "Config" . stripComments
return ("Static {" ++ p ++ "}")
tillFieldEnd = staticPos <|> many (noneOf ",}\n\r")
- commandsEnd = wrapSkip (string "]") >> oneOf "},"
+ commandsEnd = wrapSkip (string "]") >> (string "}" <|> notNextRun)
+ notNextRun = do { string ","; notFollowedBy $ wrapSkip $ string "Run"; return ","}
readCommands = manyTill anyChar (try commandsEnd) >>= read' commandsErr . flip (++) "]"
strField e n = field e n . between (strDel "start" n) (strDel "end" n) . many $ noneOf "\"\n\r"
diff --git a/src/Plugins/Kbd.hsc b/src/Plugins/Kbd.hsc
new file mode 100644
index 0000000..d19f0c7
--- /dev/null
+++ b/src/Plugins/Kbd.hsc
@@ -0,0 +1,397 @@
+{-# LANGUAGE ScopedTypeVariables, ForeignFunctionInterface, MultiParamTypeClasses, DeriveDataTypeable, FlexibleInstances, PatternGuards #-}
+-----------------------------------------------------------------------------
+-- |
+-- Module : Plugins.Kbd
+-- Copyright : (c) Martin Perner
+-- License : BSD-style (see LICENSE)
+--
+-- Maintainer : Martin Perner <martin@perner.cc>
+-- Stability : unstable
+-- Portability : unportable
+--
+-- A keyboard layout indicator for Xmobar
+--
+-----------------------------------------------------------------------------
+
+module Plugins.Kbd where
+
+import Graphics.X11.Xlib
+import Graphics.X11.Xlib.Extras
+import Foreign
+import Foreign.C.Types (CUInt,CULong,CInt,CUShort,CChar,CUChar)
+import Foreign.C.String
+import Plugins
+import Control.Monad (forever)
+import XUtil (nextEvent')
+import Data.List (isPrefixOf, findIndex)
+import Data.Maybe (fromJust)
+
+#include <X11/XKBlib.h>
+#include <X11/extensions/XKB.h>
+#include <X11/extensions/XKBstr.h>
+
+--
+-- Definition for XkbStaceRec and getKbdLayout taken from
+-- XMonad.Layout.XKBLayout
+--
+data XkbStateRec = XkbStateRec {
+ group :: CUChar,
+ locked_group :: CUChar,
+ base_group :: CUShort,
+ latched_group :: CUShort,
+ mods :: CUChar,
+ base_mods :: CUChar,
+ latched_mods :: CUChar,
+ locked_mods :: CUChar,
+ compat_state :: CUChar,
+ grab_mods :: CUChar,
+ compat_grab_mods :: CUChar,
+ lookup_mods :: CUChar,
+ compat_lookup_mods :: CUChar,
+ ptr_buttons :: CUShort
+}
+
+instance Storable XkbStateRec where
+ sizeOf _ = (#size XkbStateRec)
+ alignment _ = alignment (undefined :: CUShort)
+ peek ptr = do
+ r_group <- (#peek XkbStateRec, group) ptr
+ r_locked_group <- (#peek XkbStateRec, locked_group) ptr
+ r_base_group <- (#peek XkbStateRec, base_group) ptr
+ r_latched_group <- (#peek XkbStateRec, latched_group) ptr
+ r_mods <- (#peek XkbStateRec, mods) ptr
+ r_base_mods <- (#peek XkbStateRec, base_mods) ptr
+ r_latched_mods <- (#peek XkbStateRec, latched_mods) ptr
+ r_locked_mods <- (#peek XkbStateRec, locked_mods) ptr
+ r_compat_state <- (#peek XkbStateRec, compat_state) ptr
+ r_grab_mods <- (#peek XkbStateRec, grab_mods) ptr
+ r_compat_grab_mods <- (#peek XkbStateRec, compat_grab_mods) ptr
+ r_lookup_mods <- (#peek XkbStateRec, lookup_mods) ptr
+ r_compat_lookup_mods <- (#peek XkbStateRec, compat_lookup_mods) ptr
+ r_ptr_buttons <- (#peek XkbStateRec, ptr_buttons) ptr
+ return XkbStateRec {
+ group = r_group,
+ locked_group = r_locked_group,
+ base_group = r_base_group,
+ latched_group = r_latched_group,
+ mods = r_mods,
+ base_mods = r_base_mods,
+ latched_mods = r_latched_mods,
+ locked_mods = r_locked_mods,
+ compat_state = r_compat_state,
+ grab_mods = r_grab_mods,
+ compat_grab_mods = r_compat_grab_mods,
+ lookup_mods = r_lookup_mods,
+ compat_lookup_mods = r_compat_lookup_mods,
+ ptr_buttons = r_ptr_buttons
+ }
+
+foreign import ccall unsafe "X11/XKBlib.h XkbGetState"
+ xkbGetState :: Display -> CUInt -> Ptr XkbStateRec -> IO CInt
+
+
+getKbdLayout :: Display -> IO Int
+getKbdLayout d = alloca $ \stRecPtr -> do
+ xkbGetState d 0x100 stRecPtr
+ st <- peek stRecPtr
+ return $ fromIntegral (group st)
+
+--
+--
+--
+
+data XkbKeyNameRec = XkbKeyNameRec {
+ name :: Ptr CChar -- array
+}
+
+--
+-- the t_ before alias is just because of name collisions
+--
+data XkbKeyAliasRec = XkbKeyAliasRec {
+ real :: Ptr CChar, -- array
+ t_alias :: Ptr CChar -- array
+}
+
+--
+-- the t_ before geometry is just because of name collisions
+--
+data XkbNamesRec = XkbNamesRec {
+ keycodes :: Atom,
+ t_geometry :: Atom,
+ symbols :: Atom,
+ types :: Atom,
+ compat :: Atom,
+ vmods :: Ptr Atom,
+ indicators :: Ptr Atom, -- array
+ groups :: Ptr Atom, -- array
+ keys :: Ptr XkbKeyNameRec,
+ key_aliases :: Ptr CChar, -- dont care XkbKeyAliasRec,
+ radio_groups :: Ptr Atom,
+ phys_symbols :: Atom,
+ num_keys :: CUChar,
+ num_key_aliases :: CUChar,
+ num_rg :: CUShort
+}
+
+--
+-- the t_ before map, indicators and compat are just because of name collisions
+--
+data XkbDescRec = XkbDescRec {
+ t_dpy :: Ptr CChar, -- struct _XDisplay* ; don't care
+ flags :: CUShort,
+ device_spec :: CUShort,
+ min_key_code :: KeyCode,
+ max_key_code :: KeyCode,
+ ctrls :: Ptr CChar, -- XkbControlsPtr ; dont' care
+ server :: Ptr CChar, -- XkbServerMapPtr ; dont' care
+ t_map :: Ptr CChar, --XkbClientMapPtr ; dont' care
+ t_indicators :: Ptr CChar, -- XkbIndicatorPtr ; dont' care
+ names :: Ptr XkbNamesRec, -- array
+ t_compat :: Ptr CChar, -- XkbCompatMap ; dont' care
+ geom :: Ptr CChar -- XkbGeometryPtr ; dont' care
+
+}
+
+instance Storable XkbKeyNameRec where
+ sizeOf _ = (#size XkbKeyNameRec)
+ alignment _ = alignment (undefined :: CUShort)
+ peek ptr = do
+ r_name <- (#peek XkbKeyNameRec, name) ptr
+
+ return XkbKeyNameRec {
+ name = r_name
+ }
+
+instance Storable XkbKeyAliasRec where
+ sizeOf _ = (#size XkbKeyAliasRec)
+ alignment _ = alignment (undefined :: CUShort)
+ peek ptr = do
+ r_real <- (#peek XkbKeyAliasRec, real) ptr
+ r_alias <- (#peek XkbKeyAliasRec, alias) ptr
+
+ return XkbKeyAliasRec {
+ real = r_real,
+ t_alias = r_alias
+ }
+
+instance Storable XkbNamesRec where
+ sizeOf _ = (#size XkbNamesRec)
+ alignment _ = alignment (undefined :: CUShort)
+ peek ptr = do
+ r_keycodes <- (#peek XkbNamesRec, keycodes) ptr
+ r_geometry <- (#peek XkbNamesRec, geometry) ptr
+ r_symbols <- (#peek XkbNamesRec, symbols ) ptr
+ r_types <- (#peek XkbNamesRec, types ) ptr
+ r_compat <- (#peek XkbNamesRec, compat ) ptr
+ r_vmods <- (#peek XkbNamesRec, vmods ) ptr
+ r_indicators <- (#peek XkbNamesRec, indicators ) ptr
+ r_groups <- (#peek XkbNamesRec, groups ) ptr
+ r_keys <- (#peek XkbNamesRec, keys ) ptr
+ r_key_aliases <- (#peek XkbNamesRec, key_aliases ) ptr
+ r_radio_groups <- (#peek XkbNamesRec, radio_groups ) ptr
+ r_phys_symbols <- (#peek XkbNamesRec, phys_symbols ) ptr
+ r_num_keys <- (#peek XkbNamesRec,num_keys ) ptr
+ r_num_key_aliases <- (#peek XkbNamesRec, num_key_aliases ) ptr
+ r_num_rg <- (#peek XkbNamesRec, num_rg ) ptr
+
+ return XkbNamesRec {
+ keycodes = r_keycodes,
+ t_geometry = r_geometry,
+ symbols = r_symbols,
+ types = r_types,
+ compat = r_compat,
+ vmods = r_vmods,
+ indicators = r_indicators,
+ groups = r_groups,
+ keys = r_keys,
+ key_aliases = r_key_aliases,
+ radio_groups = r_radio_groups,
+ phys_symbols = r_phys_symbols,
+ num_keys = r_num_keys,
+ num_key_aliases = r_num_key_aliases,
+ num_rg = r_num_rg
+ }
+
+instance Storable XkbDescRec where
+ sizeOf _ = (#size XkbDescRec)
+ alignment _ = alignment (undefined :: CUShort)
+ peek ptr = do
+ r_dpy <- (#peek XkbDescRec, dpy) ptr
+ r_flags <- (#peek XkbDescRec, flags) ptr
+ r_device_spec <- (#peek XkbDescRec, device_spec) ptr
+ r_min_key_code <- (#peek XkbDescRec, min_key_code) ptr
+ r_max_key_code <- (#peek XkbDescRec, max_key_code) ptr
+ r_ctrls <- (#peek XkbDescRec, ctrls) ptr
+ r_server <- (#peek XkbDescRec, server) ptr
+ r_map <- (#peek XkbDescRec, map) ptr
+ r_indicators <- (#peek XkbDescRec, indicators) ptr
+ r_names <- (#peek XkbDescRec, names) ptr
+ r_compat <- (#peek XkbDescRec, compat) ptr
+ r_geom <- (#peek XkbDescRec, geom) ptr
+
+ return XkbDescRec {
+ t_dpy = r_dpy,
+ flags = r_flags,
+ device_spec = r_device_spec,
+ min_key_code = r_min_key_code,
+ max_key_code = r_max_key_code,
+ ctrls = r_ctrls,
+ server = r_server,
+ t_map = r_map,
+ t_indicators = r_indicators,
+ names = r_names,
+ t_compat = r_compat,
+ geom = r_geom
+ }
+
+--
+-- C bindings
+--
+
+foreign import ccall unsafe "X11/XKBlib.h XkbAllocKeyboard"
+ xkbAllocKeyboard :: IO (Ptr XkbDescRec)
+
+foreign import ccall unsafe "X11/XKBlib.h XkbGetNames"
+ xkbGetNames :: Display -> CUInt -> (Ptr XkbDescRec) -> IO Status
+
+foreign import ccall unsafe "X11/XKBlib.h XGetAtomName"
+ xGetAtomName :: Display -> Atom -> IO CString
+
+foreign import ccall unsafe "X11/XKBlib.h XkbFreeNames"
+ xkbFreeNames :: (Ptr XkbDescRec) -> CUInt -> CInt -> IO ()
+
+foreign import ccall unsafe "X11/XKBlib.h XkbFreeKeyboard"
+ xkbFreeKeyboard :: (Ptr XkbDescRec) -> CUInt -> CInt -> IO ()
+
+foreign import ccall unsafe "X11/XKBlib.h XkbSelectEventDetails"
+ xkbSelectEventDetails :: Display -> CUInt -> CUInt -> CULong -> CULong -> IO CUInt
+
+foreign import ccall unsafe "X11/XKBlib.h XkbSelectEvents"
+ xkbSelectEvents :: Display -> CUInt -> CUInt -> CUInt -> IO CUInt
+
+
+xkbUseCoreKbd :: CUInt
+xkbUseCoreKbd = #const XkbUseCoreKbd
+
+xkbStateNotify :: CUInt
+xkbStateNotify = #const XkbStateNotify
+
+xkbMapNotify :: CUInt
+xkbMapNotify = #const XkbMapNotify
+
+xkbMapNotifyMask :: CUInt
+xkbMapNotifyMask = #const XkbMapNotifyMask
+
+xkbNewKeyboardNotifyMask :: CUInt
+xkbNewKeyboardNotifyMask = #const XkbNewKeyboardNotifyMask
+
+xkbAllStateComponentsMask :: CULong
+xkbAllStateComponentsMask = #const XkbAllStateComponentsMask
+
+xkbGroupStateMask :: CULong
+xkbGroupStateMask = #const XkbGroupStateMask
+
+xkbSymbolsNameMask :: CUInt
+xkbSymbolsNameMask = #const XkbSymbolsNameMask
+
+xkbGroupNamesMask :: CUInt
+xkbGroupNamesMask = #const XkbGroupNamesMask
+
+type KbdOpts = [(String, String)]
+
+-- gets the layout string
+getLayoutStr :: Display -> IO String
+getLayoutStr dpy = do
+ kbdDescPtr <- xkbAllocKeyboard
+ status <- xkbGetNames dpy xkbSymbolsNameMask kbdDescPtr
+ str <- getLayoutStr' status dpy kbdDescPtr
+ xkbFreeNames kbdDescPtr xkbGroupNamesMask 1
+ xkbFreeKeyboard kbdDescPtr 0 1
+ return str
+
+getLayoutStr' :: Status -> Display -> (Ptr XkbDescRec) -> IO String
+getLayoutStr' st dpy kbdDescPtr =
+ if st == 0 then -- Success
+ do
+ kbdDesc <- peek kbdDescPtr
+ nameArray <- peek (names kbdDesc)
+ atom <- xGetAtomName dpy (symbols nameArray)
+ str <- peekCString atom
+ return str
+ else -- Behaviour on error
+ do
+ return "Error while requesting layout!"
+
+
+-- 'Bad' prefixes of layouts
+noLaySymbols :: [String]
+noLaySymbols = ["group", "inet", "ctr", "pc", "ctrl"]
+
+
+-- splits the layout string into the actual layouts
+splitLayout :: String -> [String]
+splitLayout s = splitLayout' noLaySymbols $ split s '+'
+
+splitLayout' :: [String] -> [String] -> [String]
+-- end of recursion, remove empty strings
+splitLayout' [] s = map (takeWhile (\x -> x /= ':')) $ filter (\x -> length x > 0) s
+-- remove current string if it has a 'bad' prefix
+splitLayout' bad s = splitLayout' (tail bad) [x | x <- s, not $ isPrefixOf (head bad) x]
+
+-- split String at each Char
+split :: String -> Char -> [String]
+split [] _ = [""]
+split (c:cs) delim
+ | c == delim = "" : rest
+ | otherwise = (c : head rest) : tail rest
+ where
+ rest = split cs delim
+
+-- replaces input string if on search list (exact match) with corresponding
+-- element on replacement list.
+--
+-- if not found, return string unchanged
+searchReplaceLayout :: KbdOpts -> String -> String
+searchReplaceLayout opts s = let c = findIndex (\x -> fst x == s) opts in
+ case c of
+ Nothing -> s
+ x -> let i = (fromJust x) in
+ snd $ opts!!i
+
+-- returns the active layout
+getKbdLay :: Display -> KbdOpts -> IO String
+getKbdLay dpy opts = do
+ lay <- getLayoutStr dpy
+ curLay <- getKbdLayout dpy
+ return $ searchReplaceLayout opts $ (splitLayout lay)!!(curLay)
+
+
+
+data Kbd = Kbd [(String, String)]
+ deriving (Read, Show)
+
+instance Exec Kbd where
+ alias (Kbd _) = "kbd"
+ start (Kbd opts) cb = do
+
+ dpy <- openDisplay ""
+
+ -- initial set of layout
+ cb =<< (getKbdLay dpy opts)
+
+ -- enable listing for
+ -- group changes
+ _ <- xkbSelectEventDetails dpy xkbUseCoreKbd xkbStateNotify xkbAllStateComponentsMask xkbGroupStateMask
+ -- layout/geometry changes
+ _ <- xkbSelectEvents dpy xkbUseCoreKbd xkbNewKeyboardNotifyMask xkbNewKeyboardNotifyMask
+
+ allocaXEvent $ \e -> forever $ do
+ nextEvent' dpy e
+ _ <- getEvent e
+ cb =<< (getKbdLay dpy opts)
+
+ closeDisplay dpy
+ return ()
+
+-- vim:ft=haskell:ts=4:shiftwidth=4:softtabstop=4:expandtab:foldlevel=20:
+
diff --git a/src/Plugins/Monitors/Volume.hs b/src/Plugins/Monitors/Volume.hs
index 50a6ed4..3e3a8b9 100644
--- a/src/Plugins/Monitors/Volume.hs
+++ b/src/Plugins/Monitors/Volume.hs
@@ -14,10 +14,12 @@
module Plugins.Monitors.Volume (runVolume, volumeConfig) where
+import Prelude hiding ( catch )
import Control.Monad ( liftM, mplus )
import Data.Maybe
import Plugins.Monitors.Common
import Sound.ALSA.Mixer
+import Sound.ALSA.Exception ( catch )
import System.Console.GetOpt
volumeConfig :: IO MConfig
@@ -115,7 +117,8 @@ runVolume mixerName controlName argv = do
maybeNA = maybe (return "N/A")
(lo, hi) <- io $ getRange volumeControl
val <- io $ getChannel FrontLeft $ value volumeControl
- db <- io $ getChannel FrontLeft $ dB volumeControl
+ db <- io $ catch (getChannel FrontLeft $ dB volumeControl)
+ (\_ -> return $ Just 0)
sw <- io $ getChannel FrontLeft switchControl
p <- maybeNA (formatVol lo hi) val
b <- maybeNA (formatVolBar lo hi) val
diff --git a/src/XUtil.hsc b/src/XUtil.hsc
index cb0c89a..ea051f8 100644
--- a/src/XUtil.hsc
+++ b/src/XUtil.hsc
@@ -2,7 +2,7 @@
-----------------------------------------------------------------------------
-- |
-- Module : XUtil
--- Copyright : (C) 2007 Andrea Rossato
+-- Copyright : (C) 2007, 2011 Andrea Rossato
-- License : BSD3
--
-- Maintainer : andrea.rossato@unitn.it
diff --git a/xmobar.cabal b/xmobar.cabal
index e40494f..b0afc26 100644
--- a/xmobar.cabal
+++ b/xmobar.cabal
@@ -68,10 +68,11 @@ executable xmobar
Xmobar, Config, Parsers, Commands, XUtil, StatFS, Runnable,
Plugins, Plugins.CommandReader, Plugins.Date, Plugins.EWMH,
Plugins.PipeReader, Plugins.StdinReader, Plugins.XMonadLog,
- Plugins.Utils, Plugins.Monitors, Plugins.Monitors.Batt,
- Plugins.Monitors.Common, Plugins.Monitors.CoreCommon,
- Plugins.Monitors.CoreTemp, Plugins.Monitors.CpuFreq,
- Plugins.Monitors.Cpu, Plugins.Monitors.Disk, Plugins.Monitors.Mem,
+ Plugins.Utils, Plugins.Kbd, Plugins.Monitors,
+ Plugins.Monitors.Batt, Plugins.Monitors.Common,
+ Plugins.Monitors.CoreCommon, Plugins.Monitors.CoreTemp,
+ Plugins.Monitors.CpuFreq, Plugins.Monitors.Cpu,
+ Plugins.Monitors.Disk, Plugins.Monitors.Mem,
Plugins.Monitors.MultiCpu, Plugins.Monitors.Net,
Plugins.Monitors.Swap, Plugins.Monitors.Thermal,
Plugins.Monitors.ThermalZone, Plugins.Monitors.Top,
@@ -123,6 +124,7 @@ executable xmobar
if flag(with_alsa) || flag(all_extensions)
build-depends: alsa-mixer == 0.1.*
+ build-depends: alsa-core == 0.5.*
other-modules: Plugins.Monitors.Volume
cpp-options: -DALSA