.files/nix/configurations/vanadium/home/xmobar/xmobar.hs

144 lines
4.3 KiB
Haskell

import Xmobar
import Data.Function ((&))
import Data.List (intercalate)
import Data.Map qualified as M
import System.Process
parseXRDB :: String -> M.Map String String
parseXRDB = M.fromList . parseXRDBLines . lines
parseXRDBLines :: [String] -> [(String, String)]
parseXRDBLines = map parseXRDBLine
parseXRDBLine :: String -> (String, String)
parseXRDBLine s = case break (== ':') s of
(k, ':' : v) -> (k, dropWhile (== '\t') v)
_ -> error $ "Failed to parse " <> s
-- | Hack to adapt the bar height, fontsize, etc, with the chosen dpi in XRDB
withDynamicDPI :: Config -> IO Config
withDynamicDPI cfg = do
xrdbConfig <- parseXRDB <$> readCreateProcess (shell "xrdb -query") mempty
case xrdbConfig M.!? "Xft.dpi" of
Nothing -> pure cfg
Just dpiStr ->
let
dpi = read dpiStr
-- In case of low DPI:
-- * reduce height
-- * increase font size
isLowDPI = dpi < 120
updatePosition (BottomH x) = BottomH $ if isLowDPI then 15 else x
updatePosition x = x
updateFontSize x = k <> " " <> v'
where
(k, ' ' : v) = break (== ' ') x
v' = if isLowDPI then "9" else v
in
pure $ cfg
{ dpi = dpi
, position = updatePosition (position cfg)
, font = updateFontSize (font cfg)
}
config :: Config
config =
defaultConfig
{
-- as docked
overrideRedirect = False
-- For framework 13
, dpi = 150
, font = "Iosevka 8"
, fgColor = "#FFFFFF"
, bgColor = "#000000"
, position = BottomH 24
, textOffset = 2
, commands =
[ Run $ DateZone "%a %d %H:%M:%S" "" "" "hereClock" (1 &second)
, Run $ DateZone "%H:%M" "" "Europe/Dublin" "dublinClock" (10 &second)
, Run $ DateZone "%H:%M" "" "Europe/Paris" "parisClock" (10 &second)
, Run $ DateZone "%H:%M" "" "Asia/Taipei" "tstClock" (10 &second)
, Run $
Com
"tomorrow"
[ "--target", "2025-08-14"
, "--target", "2025-08-21"
, "--target", "2025-08-22"
, "--target", "2025-09-16=snip snip"
, "--target", "2025-10-13=no teef"
, "--target", "2025-10-31=dragon book"
, "--target", "2025-11-21=scalpel"
, "--target", "2025-11-21=baguette"
, "--target", "2025-11-29=à deux"
, "--target", "2025-12-16=dragon book"
, "--target", "2025-12-30=seule"
]
""
(60 &minute)
, Run $
Battery
[ "-t", "<acstatus> <left> (<timeleft>"
, "-H", "70"
, "-L", "20"
, "-h", "green"
, "-n", "orange"
, "-l", "red"
, "--"
, "-O", "Charging"
, "-i", "Idle"
, "-o", "Battery"
, "-P"
, "-A", "10"
-- TODO: File a bug upstream about notify-send
-- https://codeberg.org/xmobar/xmobar/issues/746
, "-a", "notify-send -u critical \"Battery Low\" \"Please charge your battery\""
]
(6 &second)
, Run $ Com "powerprofilesctl" ["get"] "" (6 &second)
, Run XMonadLog
, Run $
Weather
"RCSS"
[ "-t", "<station>: <tempC>°C"
, "-L", "10"
, "-H", "25"
, "--normal", "white"
, "--high", "orange"
, "--low", "blue"
]
(15 &minute)
]
, template =
let
greyFg x = "<fc=#c9c9c9>" <> x <> "</fc>"
in
" %XMonadLog% "
<> alignSep config
<> intercalate "|"
[ (unwords . map greyFg)
[ "[DUB: %dublinClock%]"
, "[CDG: %parisClock%]"
, "[TPE: %tstClock%]"
]
<> " "
, " %RCSS% "
, " %battery%, %powerprofilesctl%) "
, " %hereClock% (%tomorrow%) "
]
}
second :: Int -> Int
second = (* 10)
minute :: Int -> Int
minute = (* 60) . second
main :: IO ()
main = withDynamicDPI config >>= xmobar