hbro-1.2.0.0: library/Hbro/Boot.hs
module Hbro.Boot (hbro) where
-- {{{ Imports
import Hbro.Config as Config
import Hbro.Core as Core
import Hbro.Dyre as Dyre
import Hbro.Error
import Hbro.Gui as Gui
import Hbro.Hooks as Hooks
import Hbro.IPC as IPC (routine)
import Hbro.K as K
import Hbro.Options as Options
import Hbro.Signals as Signals
import Hbro.Logger
import Hbro.Prelude
import Hbro.Webkit.WebSettings as Settings
import Control.Concurrent.Async.Lifted
import Control.Lens hiding((??))
import Control.Monad.Reader hiding(guard, mapM_, msum, when)
import Filesystem
import Graphics.UI.Gtk.General.General as Gtk
import Paths_hbro
import System.Posix.Signals
import System.ZMQ4.Monadic (runZMQ)
-- }}}
-- | Main function to call in the configuration file (cf file @Hbro/Main.hs@).
hbro :: K () -> IO ()
hbro setup = void . runMaybeT $ do
options <- parseOptions
Dyre.wrap (options^.dyreModeL)
(\x -> withAsyncBound guiThread (mainThread x))
(setup, options)
-- | Gtk main loop thread.
guiThread :: IO ()
guiThread = do
async $ do
installHandler sigINT (Catch onInterrupt) Nothing
installHandler sigTERM (Catch onInterrupt) Nothing
initGUI >> mainGUI
debugM "hbro.main" "GUI thread correctly exited."
where onInterrupt = logInterrupt >> gAsync mainQuit
logInterrupt = infoM "hbro.main" "Received interrupt signal."
mainThread :: (ControlIO m) => (K (), CliOptions) -> Async (StM IO ()) -> m ()
mainThread (customSetup, options) uiThread = logErrors_ $ do
-- Signals
signals <- Signals.initialize
hooks <- Hooks.initialize
-- GUI
uiFiles <- getUIFiles options
gui <- asum $ map Gui.initialize uiFiles
attachGuiSignals gui signals
-- K monad
globalStatus <- K.init gui hooks signals
-- IPC
socketURI <- getSocketURI options
io . (`runReaderT` globalStatus) . runExceptT $ do
resetKeyBindings
Settings.resetAll
lift customSetup
debugM "hbro.boot" . ("Start-up configuration: \n" ++) . describe =<< Config.get id
logErrors_ $ maybe goHome load (options^.startURIL)
io . withAsyncList (Hooks.routines globalStatus signals hooks) $ \_ -> do
withAsync (runZMQ $ IPC.routine socketURI (signals^._ipcSignals)) $ \_ ->
wait uiThread
debugM "hbro.main" "All threads correctly exited."
-- | Return the list of available UI files (from configuration and package)
getUIFiles :: (BaseIO m) => CliOptions -> m [FilePath]
getUIFiles options = do
fileFromConfig <- getAppConfigDirectory "hbro" >/> "ui.xml"
fileFromPackage <- fpFromText . pack <$> (io $ getDataFileName "examples/ui.xml")
return $ catMaybes [options^.uiFileL, Just fileFromConfig, Just fileFromPackage]