diff --git a/bin/xmobar.hs b/bin/xmobar.hs index 1f7110a..a003112 100644 --- a/bin/xmobar.hs +++ b/bin/xmobar.hs @@ -32,6 +32,7 @@ import Xmobar.Plugins.VPN import XMonad (getXMonadDir) import XMonad.Hooks.DynamicLog (wrap, xmobarColor) +import XMonad.Internal.Command.Power (hasBattery) import XMonad.Internal.DBus.Common (xmonadBus) import XMonad.Internal.DBus.Control (pathExists) import XMonad.Internal.DBus.IntelBacklight (blPath) @@ -138,6 +139,31 @@ getEthernet = do [n] -> Just $ ethernetCmd n _ -> Nothing +batteryCmd :: CmdSpec +batteryCmd = CmdSpec + { csAlias = "battery" + , csDepends = Nothing + , csRunnable = Run + $ Battery + [ "--template", "" + , "--Low", "10" + , "--High", "80" + , "--low", "red" + , "--normal", T.fgColor + , "--high", T.fgColor + , "--" + , "-P" + , "-o" , "\xf0e7" + , "-O" , "\xf1e6" + , "-i" , "\xf1e6" + ] 50 + } + +getBattery :: IO (Maybe CmdSpec) +getBattery = do + b <- hasBattery + return $ if b then Just batteryCmd else Nothing + vpnCmd :: CmdSpec vpnCmd = CmdSpec { csAlias = vpnAlias @@ -161,6 +187,7 @@ myCommands = do wirelessSpec <- getWireless ethernetSpec <- getEthernet vpnSpec <- getVPN + batterySpec <- getBattery let left = [ CmdSpec { csAlias = "UnsafeStdinReader" @@ -196,24 +223,7 @@ myCommands = do ] } - , Just $ CmdSpec - { csAlias = "battery" - , csDepends = Nothing - , csRunnable = Run - $ Battery - [ "--template", "" - , "--Low", "10" - , "--High", "80" - , "--low", "red" - , "--normal", T.fgColor - , "--high", T.fgColor - , "--" - , "-P" - , "-o" , "\xf0e7" - , "-O" , "\xf1e6" - , "-i" , "\xf1e6" - ] 50 - } + , batterySpec , Just $ CmdSpec { csAlias = "intelbacklight" diff --git a/lib/XMonad/Internal/Command/Power.hs b/lib/XMonad/Internal/Command/Power.hs index 1eee5a4..f9e0e36 100644 --- a/lib/XMonad/Internal/Command/Power.hs +++ b/lib/XMonad/Internal/Command/Power.hs @@ -11,16 +11,20 @@ module XMonad.Internal.Command.Power , runSuspend , runSuspendPrompt , runQuitPrompt + , hasBattery ) where import Control.Arrow (first) +import Data.Either import qualified Data.Map as M import Graphics.X11.Types import System.Directory import System.Exit +import System.FilePath.Posix +import System.IO.Error import System.Process import XMonad.Core @@ -98,18 +102,22 @@ hasSwitchableGPU = withShellOutput cmd hasIntelAndOther ivendors = filter (== "Intel Corporation") vendors in length vendors > length ivendors && not (null ivendors) --- this is hacky but so much easier than the "pure haskell" solution -hasBattery :: IO (Maybe Bool) -hasBattery = withShellOutput (fmtCmd "cat" ["/sys/class/power_supply/*/type"]) - $ elem "Battery" . lines +hasBattery :: IO Bool +hasBattery = do + ps <- fromRight [] <$> tryIOError (listDirectory syspath) + ts <- mapM readType ps + return $ "Battery\n" `elem` ts + where + readType p = fromRight [] <$> tryIOError (readFile $ syspath p "type") + syspath = "/sys/class/power_supply" requireOptimus :: IO Bool requireOptimus = do s <- hasSwitchableGPU b <- hasBattery case (s, b) of - (Just True, Just True) -> return True - _ -> warn >> return False + (Just True, True) -> return True + _ -> warn >> return False where warn = putStrLn "WARNING: could not determine if switchable GPU present. Assuming not"