Skip to content
Snippets Groups Projects
Commit 7245fc09 authored by Jens Nolte's avatar Jens Nolte
Browse files

Allow configuration of blocks from cli

This reverses the control flow between 'Cli' and 'Server'
parent 109cbc0b
No related branches found
No related tags found
No related merge requests found
module Main where module Main where
import QBar.Cli import QBar.Cli
import QBar.DefaultConfig
import QBar.Server
main :: IO () main :: IO ()
main = parseOptions >>= runQBar generateDefaultBarConfig main = runQBar
\ No newline at end of file \ No newline at end of file
...@@ -2,47 +2,55 @@ ...@@ -2,47 +2,55 @@
module QBar.Cli where module QBar.Cli where
import QBar.ControlSocket
import QBar.Core
import QBar.DefaultConfig
import QBar.Server
import QBar.Theme import QBar.Theme
import qualified Data.Text as T import Control.Monad (join, sequence_)
import qualified Data.Text.Lazy as TL import qualified Data.Text.Lazy as T
import Options.Applicative import Options.Applicative
data BarCommand = BarServerCommand | SetThemeCommand Text | ConnectSocket -- |Entry point.
runQBar :: IO ()
runQBar = join parseMain
barCommandParser :: Parser BarCommand parseMain :: IO (IO ())
barCommandParser = hsubparser ( parseMain = customExecParser parserPrefs parser
command "server" (info (pure BarServerCommand) (progDesc "Start a new qbar server. Should be called by swaybar, i3bar or or another i3bar-protocol compatible host process.")) <> where
command "connect" (info (pure ConnectSocket) (progDesc "Run blocks on this process but display them on the qbar server.")) <> parser :: ParserInfo (IO ())
command "theme" (info themeCommandParser (progDesc "Change the theme of the running qbar server.")) <> parser = info (mainParser <**> helper)
command "default" (info (pure $ SetThemeCommand "default") (progDesc "Shortcut for 'qbar theme default'.")) <> (fullDesc <> header "qbar - queezles {i3,sway}bar infrastructure")
command "rainbow" (info (pure $ SetThemeCommand "rainbow") (progDesc "Shortcut for 'qbar theme rainbow'."))
)
themeCommandParser :: Parser BarCommand
themeCommandParser = SetThemeCommand <$> strArgument (metavar "THEME" <> completeWith (map TL.unpack themeNames))
data MainOptions = MainOptions { parserPrefs :: ParserPrefs
verbose :: Bool, parserPrefs = prefs showHelpOnEmpty
indicator :: Bool,
socketLocation :: Maybe T.Text,
barCommand :: BarCommand
}
mainOptionsParser :: Parser MainOptions mainParser :: Parser (IO ())
mainOptionsParser = do mainParser = do
verbose <- switch $ long "verbose" <> short 'v' <> help "Print more diagnostic output to stderr (including a copy of every bar update)." verbose <- switch $ long "verbose" <> short 'v' <> help "Print more diagnostic output to stderr (including a copy of every bar update)."
indicator <- switch $ long "indicator" <> short 'i' <> help "Show render indicator." indicator <- switch $ long "indicator" <> short 'i' <> help "Show render indicator."
socketLocation <- optional $ strOption $ long "socket" <> short 's' <> metavar "SOCKET" <> help "Control socket location. By default determined by WAYLAND_SOCKET location." socketLocation <- optional $ strOption $ long "socket" <> short 's' <> metavar "SOCKET" <> help "Control socket location. By default determined by WAYLAND_SOCKET location."
barCommand <- barCommandParser barCommand <- barCommandParser
return MainOptions {verbose, indicator, socketLocation, barCommand} return (barCommand MainOptions {verbose, indicator, socketLocation})
parser :: ParserInfo MainOptions barCommandParser :: Parser (MainOptions -> IO ())
parser = info (mainOptionsParser <**> helper) barCommandParser = hsubparser (
(fullDesc <> header "qbar - queezles {i3,sway}bar infrastructure") command "server" (info (runBarServer <$> barConfigurationParser) (progDesc "Start a new qbar server. Should be called by swaybar, i3bar or or another i3bar-protocol compatible host process.")) <>
command "connect" (info (sendBlockStream <$> barConfigurationParser) (progDesc "Run blocks on this process but display them on the qbar server.")) <>
parserPrefs :: ParserPrefs command "theme" (info themeCommandParser (progDesc "Change the theme of the running qbar server.")) <>
parserPrefs = prefs showHelpOnEmpty command "default" (info (pure $ sendIpc . SetTheme $ "default") (progDesc "Shortcut for 'qbar theme default'.")) <>
command "rainbow" (info (pure $ sendIpc . SetTheme $ "rainbow") (progDesc "Shortcut for 'qbar theme rainbow'."))
)
parseOptions :: IO MainOptions themeCommandParser :: Parser (MainOptions -> IO ())
parseOptions = customExecParser parserPrefs parser themeCommandParser = sendIpc . SetTheme <$> strArgument (metavar "THEME" <> completeWith (map T.unpack themeNames))
\ No newline at end of file
barConfigurationParser :: Parser (BarIO ())
barConfigurationParser = do
blocks <- many $ hsubparser (
command "default" (info (pure defaultBarConfig) (progDesc "Load default set of blocks."))
)
pure $ case blocks of
[] -> defaultBarConfig
l -> sequence_ l
...@@ -9,7 +9,6 @@ ...@@ -9,7 +9,6 @@
module QBar.ControlSocket where module QBar.ControlSocket where
import QBar.BlockOutput import QBar.BlockOutput
import QBar.Cli (MainOptions(..))
import QBar.Core import QBar.Core
import QBar.Host import QBar.Host
import QBar.Util import QBar.Util
...@@ -27,8 +26,7 @@ import System.IO ...@@ -27,8 +26,7 @@ import System.IO
import Data.Either (either) import Data.Either (either)
import Data.Maybe (maybe) import Data.Maybe (maybe)
import Data.Text.Lazy (Text, pack) import Data.Text.Lazy (Text, pack)
import qualified Data.Text as T import qualified Data.Text.Lazy as T
import qualified Data.Text.Lazy as TL
import Network.Socket import Network.Socket
import Pipes import Pipes
import Pipes.Concurrent as PC (Output, spawn', unbounded, fromInput, send, atomically) import Pipes.Concurrent as PC (Output, spawn', unbounded, fromInput, send, atomically)
...@@ -110,12 +108,15 @@ instance IsStream BlockStream where ...@@ -110,12 +108,15 @@ instance IsStream BlockStream where
type Down BlockStream = BlockEvent type Down BlockStream = BlockEvent
toStreamType = BlockStreamType toStreamType = BlockStreamType
streamHandler _ = do streamHandler _ = do
(cache, updateC, seal) <- newCache' (cache, updateCacheC, sealCache) <- newCache'
(eventOutput, eventInput, eventSeal) <- liftIO $ spawn' unbounded (eventOutput, eventInput, eventSeal) <- liftIO $ spawn' unbounded
bar <- askBar bar <- askBar
addBlock cache addBlock cache
prefix <- liftIO $ (<> "_") <$> randomIdentifier prefix <- liftIO $ (<> "_") <$> randomIdentifier
return (updateBarP bar >-> attachHandlerP eventOutput prefix >-> updateC, fromInput eventInput, seal >> atomically eventSeal) let blockConsumer = updateBarP bar >-> attachHandlerP eventOutput prefix >-> updateCacheC
let eventProducer = fromInput eventInput
let seal = sealCache >> atomically eventSeal >> updateBar' bar
return (blockConsumer, eventProducer, seal)
where where
attachHandlerP :: Output BlockEvent -> Text -> Pipe [BlockOutput] [BlockState] IO () attachHandlerP :: Output BlockEvent -> Text -> Pipe [BlockOutput] [BlockState] IO ()
attachHandlerP eventOutput prefix = attachHandlerP' attachHandlerP eventOutput prefix = attachHandlerP'
...@@ -145,7 +146,7 @@ instance IsStream BlockStream where ...@@ -145,7 +146,7 @@ instance IsStream BlockStream where
data Request = Command Command | StartStream StreamType data Request = Command Command | StartStream StreamType
data Command = SetTheme TL.Text data Command = SetTheme T.Text
deriving Show deriving Show
data CommandResult = Success | Error Text data CommandResult = Success | Error Text
...@@ -189,8 +190,8 @@ $(deriveJSON defaultOptions ''CommandResult) ...@@ -189,8 +190,8 @@ $(deriveJSON defaultOptions ''CommandResult)
$(deriveJSON defaultOptions ''StreamType) $(deriveJSON defaultOptions ''StreamType)
$(deriveJSON defaultOptions ''BlockStream) $(deriveJSON defaultOptions ''BlockStream)
sendIpc :: MainOptions -> Command -> IO () sendIpc :: Command -> MainOptions -> IO ()
sendIpc options@MainOptions{verbose} command = do sendIpc command options@MainOptions{verbose} = do
let request = Command command let request = Command command
sock <- connectIpcSocket options sock <- connectIpcSocket options
runEffect $ encode request >-> toSocket sock runEffect $ encode request >-> toSocket sock
...@@ -206,8 +207,8 @@ sendIpc options@MainOptions{verbose} command = do ...@@ -206,8 +207,8 @@ sendIpc options@MainOptions{verbose} command = do
showResponse Success = when verbose $ hPutStrLn stderr "Success" showResponse Success = when verbose $ hPutStrLn stderr "Success"
showResponse (Error message) = hPrint stderr message showResponse (Error message) = hPrint stderr message
sendBlockStream :: MainOptions -> BarIO () -> IO () sendBlockStream :: BarIO () -> MainOptions -> IO ()
sendBlockStream = runBarHost . streamClient BlockStream sendBlockStream loadBlocks options = runBarHost (streamClient BlockStream options) loadBlocks
listenUnixSocketAsync :: MainOptions -> Bar -> CommandHandler -> IO (Async ()) listenUnixSocketAsync :: MainOptions -> Bar -> CommandHandler -> IO (Async ())
......
...@@ -33,6 +33,12 @@ import System.Process.Typed (Process, shell, setStdin, setStdout, ...@@ -33,6 +33,12 @@ import System.Process.Typed (Process, shell, setStdin, setStdout,
getStdout, closed, createPipe, readProcessStdout, startProcess, stopProcess) getStdout, closed, createPipe, readProcessStdout, startProcess, stopProcess)
data MainOptions = MainOptions {
verbose :: Bool,
indicator :: Bool,
socketLocation :: Maybe T.Text
}
data BlockEvent = Click { data BlockEvent = Click {
name :: T.Text, name :: T.Text,
button :: Int button :: Int
......
...@@ -11,8 +11,8 @@ import Control.Lens ...@@ -11,8 +11,8 @@ import Control.Lens
blockLocation :: String -> FilePath blockLocation :: String -> FilePath
blockLocation name = "~/.config/qbar/blocks/" <> name blockLocation name = "~/.config/qbar/blocks/" <> name
generateDefaultBarConfig :: BarIO () defaultBarConfig :: BarIO ()
generateDefaultBarConfig = do defaultBarConfig = do
systemInfoInterval <- sharedInterval 10 systemInfoInterval <- sharedInterval 10
let todo = systemInfoInterval (blockScript $ blockLocation "todo") let todo = systemInfoInterval (blockScript $ blockLocation "todo")
......
...@@ -5,7 +5,6 @@ module QBar.Server where ...@@ -5,7 +5,6 @@ module QBar.Server where
import QBar.BlockOutput import QBar.BlockOutput
import QBar.Core import QBar.Core
import QBar.Cli
import QBar.ControlSocket import QBar.ControlSocket
import QBar.Host import QBar.Host
import QBar.Pango import QBar.Pango
...@@ -117,8 +116,8 @@ swayBarOutput options@MainOptions{indicator} = do ...@@ -117,8 +116,8 @@ swayBarOutput options@MainOptions{indicator} = do
pangoBlockName = _blockName pangoBlockName = _blockName
} }
runBarServer :: MainOptions -> BarIO () -> IO () runBarServer :: BarIO () -> MainOptions -> IO ()
runBarServer options = runBarHost barServer runBarServer loadBlocks options = runBarHost barServer loadBlocks
where where
barServer :: BarIO (Consumer [BlockOutput] IO (), Producer BlockEvent IO ()) barServer :: BarIO (Consumer [BlockOutput] IO (), Producer BlockEvent IO ())
barServer = do barServer = do
...@@ -190,12 +189,3 @@ runBarServer options = runBarHost barServer ...@@ -190,12 +189,3 @@ runBarServer options = runBarHost barServer
Right theme -> do Right theme -> do
setTheme' theme setTheme' theme
return Success return Success
-- |Entry point.
runQBar :: BarIO () -> MainOptions -> IO ()
runQBar barConfiguration options@MainOptions{barCommand} = runCommand barCommand
where
runCommand BarServerCommand = runBarServer options barConfiguration
runCommand ConnectSocket = sendBlockStream options barConfiguration
runCommand (SetThemeCommand themeName) = sendIpc options $ SetTheme themeName
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment