diff --git a/bin/xmobar.hs b/bin/xmobar.hs
index 363847a..3ecc9e1 100644
--- a/bin/xmobar.hs
+++ b/bin/xmobar.hs
@@ -36,10 +36,7 @@ import Xmobar.Plugins.Screensaver
import Xmobar.Plugins.VPN
import XMonad (getXMonadDir)
-import XMonad.Hooks.DynamicLog
- ( wrap
- , xmobarColor
- )
+import XMonad.Hooks.DynamicLog (wrap)
import XMonad.Internal.Command.Power (hasBattery)
import XMonad.Internal.DBus.Brightness.ClevoKeyboard
import XMonad.Internal.DBus.Brightness.IntelBacklight
@@ -48,6 +45,7 @@ import XMonad.Internal.Dependency
import XMonad.Internal.Shell
import qualified XMonad.Internal.Theme as T
import Xmobar
+import Xmobar.Plugins.Common
main :: IO ()
main = do
@@ -62,10 +60,11 @@ main = do
config :: BarRegions -> String -> Config
config br confDir = defaultConfig
- { font = barFont
- , additionalFonts = [iconFont, iconFontLarge, iconFontXLarge, iconFontXXLarge]
- , textOffset = 16
- , textOffsets = [16, 17, 17, 18]
+ -- TODO head makes me feel icky
+ { font = head allFontStrings
+ , additionalFonts = drop 1 allFontStrings
+ , textOffset = head allFontOffsets
+ , textOffsets = drop 1 allFontOffsets
, bgColor = T.bgColor
, fgColor = T.fgColor
, position = BottomSize C 100 24
@@ -120,7 +119,7 @@ ethernetCmd :: String -> CmdSpec
ethernetCmd iface = CmdSpec
{ csAlias = iface
, csRunnable = Run
- $ Device (iface, "\xf0e8", T.fgColor, T.backdropFgColor)
+ $ Device (iface, fontifyText IconMedium "\xf0e8", colors)
}
batteryCmd :: CmdSpec
@@ -137,12 +136,14 @@ batteryCmd = CmdSpec
, "--"
, "-a", notify
, "-P"
- , "-o" , "\xf0e7"
- , "-O" , "\xf1e6"
- , "-i" , "\xf1e6"
+ , "-o" , fontify "\xf0e7"
+ , "-O" , fontify "\xf1e6"
+ , "-i" , fontify "\xf1e6"
] 50
}
where
+ fontify = fontifyText IconSmall
+ -- TODO format this with standardized notification library from xmonad.internal
notify = fmtCmd "notify-send"
[ "-u"
, "critical"
@@ -154,16 +155,17 @@ batteryCmd = CmdSpec
vpnCmd :: CmdSpec
vpnCmd = CmdSpec
{ csAlias = vpnAlias
- , csRunnable = Run $ VPN ("\xf023", T.fgColor, T.backdropFgColor)
+ , csRunnable = Run $ VPN (fontifyText IconMedium "\xf023", colors)
}
btCmd :: CmdSpec
btCmd = CmdSpec
{ csAlias = btAlias
, csRunnable = Run
- -- $ Bluetooth ("\xf293", T.fgColor, T.backdropFgColor)
- $ Bluetooth ("\xf5b0", "\xf5ae") (T.fgColor, T.backdropFgColor)
+ $ Bluetooth (fontify "\xf5b0", fontify "\xf5ae") colors
}
+ where
+ fontify = fontifyText IconLarge
alsaCmd :: CmdSpec
alsaCmd = CmdSpec
@@ -172,8 +174,8 @@ alsaCmd = CmdSpec
$ Alsa "default" "Master"
[ "-t", "%"
, "--"
- , "-O", "\xf028"
- , "-o", "\xf026 "
+ , "-O", fontifyText IconSmall "\xf028"
+ , "-o", fontifyText IconSmall "\xf026 "
, "-c", T.fgColor
, "-C", T.fgColor
]
@@ -182,20 +184,20 @@ alsaCmd = CmdSpec
blCmd :: CmdSpec
blCmd = CmdSpec
{ csAlias = blAlias
- , csRunnable = Run $ IntelBacklight "\xf185"
+ , csRunnable = Run $ IntelBacklight $ fontifyText IconSmall "\xf185"
}
ckCmd :: CmdSpec
ckCmd = CmdSpec
{ csAlias = ckAlias
- , csRunnable = Run $ ClevoKeyboard "\xf40b"
+ , csRunnable = Run $ ClevoKeyboard $ fontifyText IconSmall "\xf40b"
}
ssCmd :: CmdSpec
ssCmd = CmdSpec
{ csAlias = ssAlias
, csRunnable = Run
- $ Screensaver ("\xf254", T.fgColor, T.backdropFgColor)
+ $ Screensaver (fontifyText IconSmall "\xf254", colors)
}
lockCmd :: CmdSpec
@@ -203,15 +205,20 @@ lockCmd = CmdSpec
{ csAlias = "locks"
, csRunnable = Run
$ Locks
- [ "-N", "\xf8a5"
- , "-n", xmobarColor T.backdropFgColor "" "\xf8a5"
- , "-C", "\xf657"
- , "-c", xmobarColor T.backdropFgColor "" "\xf657"
+ [ "-N", numIcon
+ , "-n", disabledColor numIcon
+ , "-C", capIcon
+ , "-c", disabledColor capIcon
, "-s", ""
, "-S", ""
, "-d", " "
]
}
+ where
+ numIcon = fontify "\xf8a5"
+ capIcon = fontify "\xf657"
+ fontify = fontifyText IconXLarge
+ disabledColor = xmobarFGColor T.backdropFgColor
dateCmd :: CmdSpec
dateCmd = CmdSpec
@@ -229,6 +236,8 @@ dateCmd = CmdSpec
-- which case ethernet interfaces always start with "en" and wireless
-- interfaces always start with "wl"
+type BarFeature = Feature CmdSpec
+
isWireless :: String -> Bool
isWireless ('w':'l':_) = True
isWireless _ = False
@@ -301,8 +310,6 @@ getBattery = Feature
, ftrWarning = Default
}
-type BarFeature = Feature CmdSpec
-
getVPN :: Maybe Client -> BarFeature
getVPN client = Feature
{ ftrDepTree = DBusTree (Single (const vpnCmd)) client [vpnDep] [dp]
@@ -361,11 +368,64 @@ getAllCommands right = do
, brRight = catMaybes right
}
+--------------------------------------------------------------------------------
+-- | fonts
+
+data Font = Text
+ | IconSmall
+ | IconMedium
+ | IconLarge
+ | IconXLarge
+ deriving (Eq, Enum, Bounded, Show)
+
+-- font data ~ (offset, fontification string)
+fontData :: Font -> (Int, String)
+fontData Text = (16, barFont)
+fontData IconSmall = (16, nerdFont 13)
+fontData IconMedium = (17, nerdFont 15)
+fontData IconLarge = (17, nerdFont 18)
+fontData IconXLarge = (18, nerdFont 20)
+
+fontString :: Font -> String
+fontString = snd . fontData
+
+fontOffset :: Font -> Int
+fontOffset = fst . fontData
+
+allFonts :: [Font]
+allFonts = enumFrom minBound
+
+allFontOffsets :: [Int]
+allFontOffsets = fontOffset <$> allFonts
+
+allFontStrings :: [String]
+allFontStrings = fontString <$> allFonts
+
+barFont :: String
+barFont = T.fmtFontXFT T.font
+ { T.family = "DejaVu Sans Mono"
+ , T.size = Just 11
+ , T.weight = Just T.Bold
+ }
+
+nerdFont :: Int -> String
+nerdFont size = T.fmtFontXFT T.font
+ { T.family = "Symbols Nerd Font"
+ , T.size = Nothing
+ , T.pixelsize = Just size
+ }
+
+fontifyText :: Font -> String -> String
+fontifyText fnt txt = concat ["", txt, ""]
+
--------------------------------------------------------------------------------
-- | various formatting things
+colors :: Colors
+colors = Colors { colorsOn = T.fgColor, colorsOff = T.backdropFgColor }
+
sep :: String
-sep = xmobarColor T.backdropFgColor "" " : "
+sep = xmobarFGColor T.backdropFgColor " : "
lSep :: Char
lSep = '}'
@@ -385,28 +445,3 @@ fmtRegions :: BarRegions -> String
fmtRegions BarRegions { brLeft = l, brCenter = c, brRight = r } =
fmtSpecs l ++ [lSep] ++ fmtSpecs c ++ [rSep] ++ fmtSpecs r
-barFont :: String
-barFont = T.fmtFontXFT T.font
- { T.family = "DejaVu Sans Mono"
- , T.size = Just 11
- , T.weight = Just T.Bold
- }
-
-nerdFont :: Int -> String
-nerdFont size = T.fmtFontXFT T.font
- { T.family = "Symbols Nerd Font"
- , T.size = Nothing
- , T.pixelsize = Just size
- }
-
-iconFont :: String
-iconFont = nerdFont 13
-
-iconFontLarge :: String
-iconFontLarge = nerdFont 15
-
-iconFontXLarge :: String
-iconFontXLarge = nerdFont 18
-
-iconFontXXLarge :: String
-iconFontXXLarge = nerdFont 20
diff --git a/lib/Xmobar/Plugins/Bluetooth.hs b/lib/Xmobar/Plugins/Bluetooth.hs
index 34b6de1..5344fa1 100644
--- a/lib/Xmobar/Plugins/Bluetooth.hs
+++ b/lib/Xmobar/Plugins/Bluetooth.hs
@@ -93,16 +93,14 @@ type IconFormatter = (Maybe Bool -> Bool -> String)
type Icons = (String, String)
-type Colors = (String, String)
-
displayIcon :: Callback -> IconFormatter -> MutableBtState -> IO ()
displayIcon callback formatter =
callback . uncurry formatter <=< readState
-- TODO maybe I want this to fail when any of the device statuses are Nothing
iconFormatter :: Icons -> Colors -> IconFormatter
-iconFormatter (iconConn, iconDisc) (colorOn, colorOff) powered connected =
- maybe na (chooseColor icon colorOn colorOff) powered
+iconFormatter (iconConn, iconDisc) cs powered connected =
+ maybe na (\p -> colorText cs p icon) powered
where
icon = if connected then iconConn else iconDisc
diff --git a/lib/Xmobar/Plugins/Common.hs b/lib/Xmobar/Plugins/Common.hs
index 5b09185..06ad8fe 100644
--- a/lib/Xmobar/Plugins/Common.hs
+++ b/lib/Xmobar/Plugins/Common.hs
@@ -1,14 +1,16 @@
module Xmobar.Plugins.Common
- ( chooseColor
+ ( colorText
, startListener
, procSignalMatch
, na
, fromSingletonVariant
, withDBusClientConnection
, Callback
+ , Colors(..)
, displayMaybe
, displayMaybe'
+ , xmobarFGColor
)
where
@@ -22,6 +24,12 @@ import XMonad.Hooks.DynamicLog (xmobarColor)
type Callback = String -> IO ()
+data Colors = Colors
+ { colorsOn :: String
+ , colorsOff :: String
+ }
+ deriving (Eq, Show, Read)
+
startListener :: IsVariant a => MatchRule -> (Client -> IO [Variant])
-> ([Variant] -> SignalMatch a) -> (a -> IO String) -> Callback
-> Client -> IO ()
@@ -35,9 +43,12 @@ startListener rule getProp fromSignal toColor cb client = do
procSignalMatch :: Callback -> (a -> IO String) -> SignalMatch a -> IO ()
procSignalMatch cb f = withSignalMatch (displayMaybe cb f)
-chooseColor :: String -> String -> String -> Bool -> String
-chooseColor text colorOn colorOff state =
- xmobarColor (if state then colorOn else colorOff) "" text
+colorText :: Colors -> Bool -> String -> String
+colorText Colors { colorsOn = c } True = xmobarFGColor c
+colorText Colors { colorsOff = c } False = xmobarFGColor c
+
+xmobarFGColor :: String -> String -> String
+xmobarFGColor c = xmobarColor c ""
na :: String
na = "N/A"
diff --git a/lib/Xmobar/Plugins/Device.hs b/lib/Xmobar/Plugins/Device.hs
index f186056..e0aa723 100644
--- a/lib/Xmobar/Plugins/Device.hs
+++ b/lib/Xmobar/Plugins/Device.hs
@@ -21,7 +21,7 @@ import XMonad.Internal.Dependency
import Xmobar
import Xmobar.Plugins.Common
-newtype Device = Device (String, String, String, String) deriving (Read, Show)
+newtype Device = Device (String, String, Colors) deriving (Read, Show)
nmBus :: BusName
nmBus = busName_ "org.freedesktop.NetworkManager"
@@ -59,8 +59,8 @@ matchStatus :: [Variant] -> SignalMatch Word32
matchStatus = matchPropertyChanged nmDeviceInterface devSignal
instance Exec Device where
- alias (Device (iface, _, _, _)) = iface
- start (Device (iface, text, colorOn, colorOff)) cb = do
+ alias (Device (iface, _, _)) = iface
+ start (Device (iface, text, colors)) cb = do
withDBusClientConnection True cb $ \client -> do
path <- getDevice client iface
displayMaybe' cb (listener client) path
@@ -70,4 +70,4 @@ instance Exec Device where
-- TODO warn the user here rather than silently drop the listener
forM_ rule $ \r ->
startListener r (getDeviceConnected path) matchStatus chooseColor' cb client
- chooseColor' = return . chooseColor text colorOn colorOff . (> 1)
+ chooseColor' = return . (\s -> colorText colors s text) . (> 1)
diff --git a/lib/Xmobar/Plugins/Screensaver.hs b/lib/Xmobar/Plugins/Screensaver.hs
index 6ac0738..d44913c 100644
--- a/lib/Xmobar/Plugins/Screensaver.hs
+++ b/lib/Xmobar/Plugins/Screensaver.hs
@@ -14,17 +14,17 @@ import Xmobar
import XMonad.Internal.DBus.Screensaver
import Xmobar.Plugins.Common
-newtype Screensaver = Screensaver (String, String, String) deriving (Read, Show)
+newtype Screensaver = Screensaver (String, Colors) deriving (Read, Show)
ssAlias :: String
ssAlias = "screensaver"
instance Exec Screensaver where
alias (Screensaver _) = ssAlias
- start (Screensaver (text, colorOn, colorOff)) cb = do
+ start (Screensaver (text, colors)) cb = do
withDBusClientConnection False cb $ \c -> do
matchSignal display c
display =<< callQuery c
where
- display = displayMaybe cb $ return . chooseColor text colorOn colorOff
+ display = displayMaybe cb $ return . (\s -> colorText colors s text)
diff --git a/lib/Xmobar/Plugins/VPN.hs b/lib/Xmobar/Plugins/VPN.hs
index 1c6f2af..0177a90 100644
--- a/lib/Xmobar/Plugins/VPN.hs
+++ b/lib/Xmobar/Plugins/VPN.hs
@@ -18,7 +18,7 @@ import XMonad.Internal.Dependency
import Xmobar
import Xmobar.Plugins.Common
-newtype VPN = VPN (String, String, String) deriving (Read, Show)
+newtype VPN = VPN (String, Colors) deriving (Read, Show)
vpnBus :: BusName
vpnBus = busName_ "org.freedesktop.NetworkManager"
@@ -40,7 +40,7 @@ vpnDep = Endpoint vpnBus vpnPath vpnInterface $ Property_ vpnConnType
instance Exec VPN where
alias (VPN _) = vpnAlias
- start (VPN (text, colorOn, colorOff)) cb =
+ start (VPN (text, colors)) cb =
withDBusClientConnection True cb $ \c -> do
rule <- matchPropertyFull c vpnBus (Just vpnPath)
-- TODO intelligently warn user
@@ -48,4 +48,4 @@ instance Exec VPN where
where
getProp = callPropertyGet vpnBus vpnPath vpnInterface $ memberName_ vpnConnType
fromSignal = matchPropertyChanged vpnInterface vpnConnType
- chooseColor' = return . chooseColor text colorOn colorOff . ("vpn" ==)
+ chooseColor' = return . (\s -> colorText colors s text) . ("vpn" ==)