-------------------------------------------------------------------------------- -- rofi-autorandr - a rofi prompt to select autorandr profiles -- -- Simple wrapper to select an autorandr profile. module Main (main) where import RIO import RIO.Directory import qualified RIO.Text as T import Rofi.Command import System.FilePath.Posix import System.Process import UnliftIO.Environment main :: IO () main = runSimpleApp $ do runChecks getArgs >>= runPrompt runChecks :: (MonadReader c m, HasLogFunc c, MonadIO m) => m () runChecks = checkExe "autorandr" >> checkExe "rofi" checkExe :: (MonadReader c m, HasLogFunc c, MonadIO m) => String -> m () checkExe cmd = do res <- findExecutable cmd unless (isJust res) $ do logError $ displayBytesUtf8 $ encodeUtf8 $ T.append "Could not find executable: " $ T.pack cmd exitWith $ ExitFailure 1 newtype ARClientConf = ARClientConf [T.Text] instance HasRofiConf ARClientConf where defArgs (ARClientConf a) = a runPrompt :: MonadIO m => [String] -> m () runPrompt a = do let c = ARClientConf $ fmap T.pack a staticProfs <- getAutoRandrProfiles runRofi c $ emptyMenu { groups = [mkGroup "Static" staticProfs, mkGroup "Virtual" virtProfs] , prompt = Just "Select Profile" } where mkGroup header = titledGroup header . toRofiActions . fmap (\s -> (T.append " " s, selectProfile s)) virtProfs :: [T.Text] virtProfs = ["off", "common", "clone-largest", "horizontal", "vertical"] -- TODO filter profiles based on which xrandr outputs are actually connected getAutoRandrProfiles :: MonadIO m => m [T.Text] getAutoRandrProfiles = do dir <- getAutoRandrDir contents <- listDirectory dir (fmap T.pack) <$> filterM (doesDirectoryExist . (dir )) contents getAutoRandrDir :: MonadIO m => m FilePath getAutoRandrDir = do c <- getXdgDirectory XdgConfig "autorandr" e <- doesDirectoryExist c if e then return c else appendToHome ".autorandr" where appendToHome p = ( p) <$> getHomeDirectory selectProfile :: T.Text -> RIO ARClientConf () selectProfile name = liftIO $ void $ spawnProcess "autorandr" ["--change", T.unpack name]