xmonad-config/lib/XMonad/Internal/Command/Power.hs

195 lines
5.9 KiB
Haskell
Raw Normal View History

2020-04-01 20:17:47 -04:00
--------------------------------------------------------------------------------
-- | Commands for controlling power
module XMonad.Internal.Command.Power
2020-03-28 18:38:38 -04:00
( runHibernate
, runOptimusPrompt
, runPowerOff
, runPowerPrompt
, runReboot
, runScreenLock
, runSuspend
, runSuspendPrompt
, runQuitPrompt
, hasBattery
2020-04-01 20:17:47 -04:00
) where
2020-03-28 18:38:38 -04:00
import Control.Arrow (first)
import Data.Either
2020-03-28 18:38:38 -04:00
import qualified Data.Map as M
import Graphics.X11.Types
2020-04-01 20:17:47 -04:00
import System.Directory
import System.Exit
import System.FilePath.Posix
import System.IO.Error
2020-04-01 20:17:47 -04:00
2020-03-28 18:38:38 -04:00
import XMonad.Core
import XMonad.Internal.Dependency
2020-04-01 20:17:47 -04:00
import qualified XMonad.Internal.Theme as T
2020-03-28 18:38:38 -04:00
import XMonad.Prompt
import XMonad.Prompt.ConfirmPrompt
--------------------------------------------------------------------------------
-- | Executables
myScreenlock :: String
myScreenlock = "screenlock"
myOptimusManager :: String
myOptimusManager = "optimus-manager"
2020-03-28 18:38:38 -04:00
--------------------------------------------------------------------------------
-- | Core commands
2021-11-19 22:42:19 -05:00
-- runScreenLock :: IO MaybeX
-- runScreenLock = spawnIfInstalled myScreenlock
runScreenLock :: Feature (X ()) (X ())
runScreenLock = Feature
{ ftrAction = spawn myScreenlock
, ftrSilent = False
, ftrChildren = [exe myScreenlock]
}
2020-03-28 18:38:38 -04:00
runPowerOff :: X ()
runPowerOff = spawn "systemctl poweroff"
runSuspend :: X ()
runSuspend = spawn "systemctl suspend"
runHibernate :: X ()
runHibernate = spawn "systemctl hibernate"
runReboot :: X ()
runReboot = spawn "systemctl reboot"
--------------------------------------------------------------------------------
-- | Confirm prompt wrappers
runSuspendPrompt :: X ()
runSuspendPrompt = confirmPrompt T.promptTheme "suspend?" runSuspend
runQuitPrompt :: X ()
runQuitPrompt = confirmPrompt T.promptTheme "quit?" $ io exitSuccess
--------------------------------------------------------------------------------
-- | Nvidia Optimus
-- TODO for some reason the screen never wakes up after suspend when
-- the nvidia card is up, so block suspend if nvidia card is running
-- and warn user
isUsingNvidia :: IO Bool
isUsingNvidia = doesDirectoryExist "/sys/module/nvidia"
2021-11-19 00:35:54 -05:00
hasBattery :: IO (Maybe String)
hasBattery = do
ps <- fromRight [] <$> tryIOError (listDirectory syspath)
ts <- mapM readType ps
2021-11-11 23:25:11 -05:00
-- TODO this is obviously stupid
2021-11-19 00:35:54 -05:00
return $ if "Battery\n" `elem` ts then Nothing else Just "battery not found"
where
readType p = fromRight [] <$> tryIOError (readFile $ syspath </> p </> "type")
syspath = "/sys/class/power_supply"
runOptimusPrompt' :: X ()
runOptimusPrompt' = do
2020-03-28 18:38:38 -04:00
nvidiaOn <- io isUsingNvidia
switch $ if nvidiaOn then "integrated" else "nvidia"
2020-03-28 18:38:38 -04:00
where
switch mode = confirmPrompt T.promptTheme (prompt mode) (cmd mode)
prompt mode = "gpu switch to " ++ mode ++ "?"
cmd mode = spawn $
"prime-offload"
#!&& unwords [myOptimusManager, "--switch", mode, "--no-confirm"]
#!&& "killall xmonad"
2020-03-28 18:38:38 -04:00
runOptimusPrompt :: IO MaybeX
runOptimusPrompt = runIfInstalled [exe myOptimusManager] runOptimusPrompt'
2021-11-19 22:42:19 -05:00
-- runOptimusPrompt :: Feature (X ()) (X ())
-- runOptimusPrompt = Feature
-- { ftrAction = runOptimusPrompt'
-- , ftrSilent = False
-- , ftrChildren = [exe myOptimusManager]
-- }
2020-03-28 18:38:38 -04:00
--------------------------------------------------------------------------------
-- | Universal power prompt
data PowerAction = Poweroff
| Shutdown
| Hibernate
| Reboot
deriving (Eq)
instance Enum PowerAction where
toEnum 0 = Poweroff
toEnum 1 = Shutdown
toEnum 2 = Hibernate
toEnum 3 = Reboot
toEnum _ = errorWithoutStackTrace "Main.Enum.PowerAction.toEnum: bad argument"
fromEnum Poweroff = 0
fromEnum Shutdown = 1
fromEnum Hibernate = 2
fromEnum Reboot = 3
data PowerPrompt = PowerPrompt
instance XPrompt PowerPrompt where
showXPrompt PowerPrompt = "(P)oweroff (S)uspend (H)ibernate (R)eboot:"
2021-11-19 22:42:19 -05:00
runPowerPrompt :: X () -> X ()
runPowerPrompt lock = mkXPrompt PowerPrompt theme comp executeAction
2020-03-28 18:38:38 -04:00
where
comp = mkComplFunFromList []
theme = T.promptTheme { promptKeymap = keymap }
keymap = M.fromList
$ ((controlMask, xK_g), quit) :
map (first $ (,) 0)
[ (xK_p, sendAction Poweroff)
, (xK_s, sendAction Shutdown)
, (xK_h, sendAction Hibernate)
, (xK_r, sendAction Reboot)
, (xK_Return, quit)
, (xK_Escape, quit)
]
sendAction a = setInput (show $ fromEnum a) >> setSuccess True >> setDone True
executeAction a = case toEnum $ read a of
Poweroff -> runPowerOff
-- TODO these dependency functions need to be assembled elsewhere and fed
-- to this function
2021-11-19 22:42:19 -05:00
-- Shutdown -> (io runScreenLock >>= whenInstalled) >> runSuspend
-- Hibernate -> (io runScreenLock >>= whenInstalled) >> runHibernate
Shutdown -> lock >> runSuspend
Hibernate -> lock >> runHibernate
2020-03-28 18:38:38 -04:00
Reboot -> runReboot
2021-11-19 22:42:19 -05:00
-- runPowerPrompt :: Feature (X ()) (X ()) -> IO (X ())
-- runPowerPrompt lock = do
-- lock' <- evalFeature lock
-- return $ mkXPrompt PowerPrompt theme comp $ executeAction $ fromRight (return ()) lock'
-- where
-- comp = mkComplFunFromList []
-- theme = T.promptTheme { promptKeymap = keymap }
-- keymap = M.fromList
-- $ ((controlMask, xK_g), quit) :
-- map (first $ (,) 0)
-- [ (xK_p, sendAction Poweroff)
-- , (xK_s, sendAction Shutdown)
-- , (xK_h, sendAction Hibernate)
-- , (xK_r, sendAction Reboot)
-- , (xK_Return, quit)
-- , (xK_Escape, quit)
-- ]
-- sendAction a = setInput (show $ fromEnum a) >> setSuccess True >> setDone True
-- executeAction l a = case toEnum $ read a of
-- Poweroff -> runPowerOff
-- -- TODO these dependency functions need to be assembled elsewhere and fed
-- -- to this function
-- Shutdown -> l >> runSuspend
-- Hibernate -> l >> runHibernate
-- Reboot -> runReboot