module System.Taffybar.SimpleConfig
( SimpleTaffyConfig(..)
, Position(..)
, defaultSimpleTaffyConfig
, simpleTaffybar
, toTaffyConfig
, useAllMonitors
, usePrimaryMonitor
) where
import qualified Control.Concurrent.MVar as MV
import Control.Monad
import Control.Monad.Trans.Class
import Data.List
import Data.Maybe
import Data.Unique
import qualified GI.Gtk as Gtk
import GI.Gdk
import Graphics.UI.GIGtkStrut
import System.Taffybar.Information.X11DesktopInfo
import System.Taffybar
import qualified System.Taffybar.Context as BC (BarConfig(..), TaffybarConfig(..))
import System.Taffybar.Context hiding (TaffybarConfig(..), BarConfig(..))
import System.Taffybar.Util
data Position = Top | Bottom deriving (Show, Eq)
data SimpleTaffyConfig = SimpleTaffyConfig
{
monitorsAction :: TaffyIO [Int]
, barHeight :: Int
, barPadding :: Int
, barPosition :: Position
, widgetSpacing :: Int
, startWidgets :: [TaffyIO Gtk.Widget]
, centerWidgets :: [TaffyIO Gtk.Widget]
, endWidgets :: [TaffyIO Gtk.Widget]
, cssPath :: Maybe FilePath
, startupHook :: TaffyIO ()
}
defaultSimpleTaffyConfig :: SimpleTaffyConfig
defaultSimpleTaffyConfig = SimpleTaffyConfig
{ monitorsAction = useAllMonitors
, barHeight = 30
, barPadding = 0
, barPosition = Top
, widgetSpacing = 5
, startWidgets = []
, centerWidgets = []
, endWidgets = []
, cssPath = Nothing
, startupHook = return ()
}
toStrutConfig :: SimpleTaffyConfig -> Int -> StrutConfig
toStrutConfig SimpleTaffyConfig { barHeight = size
, barPadding = padding
, barPosition = pos
} monitor =
defaultStrutConfig
{ strutHeight = ExactSize $ fromIntegral size
, strutYPadding = fromIntegral padding
, strutXPadding = fromIntegral padding
, strutAlignment = Center
, strutMonitor = Just $ fromIntegral monitor
, strutPosition =
case pos of
Top -> TopPos
Bottom -> BottomPos
}
toBarConfig :: SimpleTaffyConfig -> Int -> IO BC.BarConfig
toBarConfig config monitor = do
let strutConfig = toStrutConfig config monitor
barId <- newUnique
return
BC.BarConfig
{ BC.strutConfig = strutConfig
, BC.widgetSpacing = fromIntegral $ widgetSpacing config
, BC.startWidgets = startWidgets config
, BC.centerWidgets = centerWidgets config
, BC.endWidgets = endWidgets config
, BC.barId = barId
}
newtype SimpleBarConfigs = SimpleBarConfigs (MV.MVar [(Int, BC.BarConfig)])
toTaffyConfig :: SimpleTaffyConfig -> BC.TaffybarConfig
toTaffyConfig conf =
defaultTaffybarConfig
{ BC.getBarConfigsParam = configGetter
, BC.cssPath = cssPath conf
, BC.startupHook = startupHook conf
}
where
configGetter = do
SimpleBarConfigs configsVar <-
getStateDefault $ lift (SimpleBarConfigs <$> MV.newMVar [])
monitorNumbers <- monitorsAction conf
let lookupWithIndex barConfigs monitorNumber =
(monitorNumber, lookup monitorNumber barConfigs)
lookupAndUpdate barConfigs = do
let (alreadyPresent, toCreate) =
partition (isJust . snd) $
map (lookupWithIndex barConfigs) monitorNumbers
alreadyPresentConfigs = mapMaybe snd alreadyPresent
newlyCreated <-
mapM (forkM return (toBarConfig conf) . fst) toCreate
let result = map snd newlyCreated ++ alreadyPresentConfigs
return (barConfigs ++ newlyCreated, result)
lift $ MV.modifyMVar configsVar lookupAndUpdate
simpleTaffybar :: SimpleTaffyConfig -> IO ()
simpleTaffybar conf = dyreTaffybar $ toTaffyConfig conf
getMonitorCount :: IO Int
getMonitorCount =
fromIntegral <$> (screenGetDefault >>= maybe (return 0) (screenGetDisplay >=> displayGetNMonitors))
useAllMonitors :: TaffyIO [Int]
useAllMonitors = lift $ do
count <- getMonitorCount
return [0..count-1]
usePrimaryMonitor :: TaffyIO [Int]
usePrimaryMonitor =
return . fromMaybe 0 <$> lift (withDefaultCtx getPrimaryOutputNumber)