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

Remove duplicates after theming

parent 7a3586c9
No related branches found
No related tags found
No related merge requests found
...@@ -34,13 +34,12 @@ installSignalHandlers bar = void $ installHandler sigCONT (Catch sigContAction) ...@@ -34,13 +34,12 @@ installSignalHandlers bar = void $ installHandler sigCONT (Catch sigContAction)
hPutStrLn stderr "SIGCONT received" hPutStrLn stderr "SIGCONT received"
updateBar' bar updateBar' bar
eventDispatcher :: IORef [(T.Text, BlockEventHandler)] -> Consumer BlockEvent BarIO () eventDispatcher :: Bar -> IORef [(T.Text, BlockEventHandler)] -> Consumer BlockEvent IO ()
eventDispatcher eventHandlerListIORef = eventDispatcher' eventDispatcher bar eventHandlerListIORef = eventDispatcher'
where where
eventDispatcher' :: Consumer BlockEvent BarIO () eventDispatcher' :: Consumer BlockEvent IO ()
eventDispatcher' = do eventDispatcher' = do
blockEvent <- await blockEvent <- await
bar <- askBar
eventHandlerList <- liftIO $ readIORef eventHandlerListIORef eventHandlerList <- liftIO $ readIORef eventHandlerListIORef
let maybeEventHandler = getEventHandler eventHandlerList blockEvent let maybeEventHandler = getEventHandler eventHandlerList blockEvent
case maybeEventHandler of case maybeEventHandler of
...@@ -51,10 +50,10 @@ eventDispatcher eventHandlerListIORef = eventDispatcher' ...@@ -51,10 +50,10 @@ eventDispatcher eventHandlerListIORef = eventDispatcher'
getEventHandler eventHandlerList blockEvent = lookup (name blockEvent) eventHandlerList getEventHandler eventHandlerList blockEvent = lookup (name blockEvent) eventHandlerList
runBlocks :: HostHandle -> Producer [BlockOutput] BarIO () runBlocks :: Bar -> HostHandle -> Producer [BlockOutput] IO ()
runBlocks HostHandle{barUpdateEvent, newBlockChan, eventHandlerListIORef} = runBlocks' [] runBlocks bar HostHandle{barUpdateEvent, newBlockChan, eventHandlerListIORef} = runBlocks' []
where where
runBlocks' :: [CachedBlock] -> Producer [BlockOutput] BarIO () runBlocks' :: [CachedBlock] -> Producer [BlockOutput] IO ()
runBlocks' blocks = do runBlocks' blocks = do
liftIO $ do liftIO $ do
-- Wait for an update request -- Wait for an update request
...@@ -64,9 +63,9 @@ runBlocks HostHandle{barUpdateEvent, newBlockChan, eventHandlerListIORef} = runB ...@@ -64,9 +63,9 @@ runBlocks HostHandle{barUpdateEvent, newBlockChan, eventHandlerListIORef} = runB
threadDelay 10000 threadDelay 10000
Event.clear barUpdateEvent Event.clear barUpdateEvent
blocks' <- lift $ addNewBlocks blocks blocks' <- liftIO $ runBarIO bar $ addNewBlocks blocks
(blockStates, blocks'') <- lift $ getBlockStates blocks' (blockStates, blocks'') <- liftIO $ runBarIO bar $ getBlockStates blocks'
-- Pass blocks to output -- Pass blocks to output
yield $ map fst $ catMaybes blockStates yield $ map fst $ catMaybes blockStates
...@@ -125,10 +124,11 @@ filterDuplicates = do ...@@ -125,10 +124,11 @@ filterDuplicates = do
filterDuplicates' value filterDuplicates' value
runBarHost :: Consumer [BlockOutput] BarIO () runBarHost :: Consumer [BlockOutput] IO ()
-> Producer BlockEvent BarIO () -> Producer BlockEvent IO ()
-> BarIO ()
-> IO () -> IO ()
runBarHost host barEventProducer = do runBarHost host barEventProducer loadBlocks = do
-- Create an event used to signal bar updates -- Create an event used to signal bar updates
barUpdateEvent <- Event.newSet barUpdateEvent <- Event.newSet
let requestBarUpdate = Event.set barUpdateEvent let requestBarUpdate = Event.set barUpdateEvent
...@@ -150,10 +150,12 @@ runBarHost host barEventProducer = do ...@@ -150,10 +150,12 @@ runBarHost host barEventProducer = do
eventHandlerListIORef eventHandlerListIORef
} }
let handleStdin = runEffect $ barEventProducer >-> eventDispatcher eventHandlerListIORef runBarIO bar loadBlocks
let handleStdin = liftIO $ runEffect $ barEventProducer >-> eventDispatcher bar eventHandlerListIORef
-- Fork stdin handler -- Fork stdin handler
void $ forkFinally (runBarIO bar handleStdin) (\result -> hPutStrLn stderr $ "handleStdin failed: " <> show result) void $ forkFinally (runBarIO bar handleStdin) (\result -> hPutStrLn stderr $ "handleStdin failed: " <> show result)
-- Run bar host -- Run bar host
runBarIO bar $ runEffect $ runBlocks hostHandle >-> filterDuplicates >-> host runEffect $ runBlocks bar hostHandle >-> filterDuplicates >-> host
...@@ -52,10 +52,10 @@ instance ToJSON PangoBlock where ...@@ -52,10 +52,10 @@ instance ToJSON PangoBlock where
-- |A producer that reads swaybar/i3bar-input events from stdin and emits them as 'BlockEvent's. -- |A producer that reads swaybar/i3bar-input events from stdin and emits them as 'BlockEvent's.
swayBarInput :: MainOptions -> Producer BlockEvent BarIO () swayBarInput :: MainOptions -> Producer BlockEvent IO ()
swayBarInput MainOptions{verbose} = swayBarInput' swayBarInput MainOptions{verbose} = swayBarInput'
where where
swayBarInput' :: Producer BlockEvent BarIO () swayBarInput' :: Producer BlockEvent IO ()
swayBarInput' = do swayBarInput' = do
line <- liftIO $ BSSC8.hGetLine stdin line <- liftIO $ BSSC8.hGetLine stdin
...@@ -77,20 +77,32 @@ swayBarInput MainOptions{verbose} = swayBarInput' ...@@ -77,20 +77,32 @@ swayBarInput MainOptions{verbose} = swayBarInput'
| otherwise = line | otherwise = line
outputLine :: MainOptions -> [ThemedBlockOutput] -> IO () swayBarOutput :: MainOptions -> Consumer [ThemedBlockOutput] IO ()
outputLine MainOptions{verbose} themedBlocks = do swayBarOutput options = do
let encodedOutput = encodeOutput themedBlocks -- Print header
liftIO $ do liftIO $ do
hPut stdout encodedOutput putStrLn "{\"version\":1,\"click_events\":true}"
putStrLn "," putStrLn "["
hFlush stdout
-- Echo output to stderr when verbose flag is set swayBarOutput'
when verbose $ do
hPut stderr encodedOutput
hPut stderr "\n"
hFlush stderr
where where
swayBarOutput' :: Consumer [ThemedBlockOutput] IO ()
swayBarOutput' = do
await >>= (liftIO . outputLine options)
swayBarOutput'
outputLine :: MainOptions -> [ThemedBlockOutput] -> IO ()
outputLine MainOptions{verbose} themedBlocks = do
let encodedOutput = encodeOutput themedBlocks
liftIO $ do
hPut stdout encodedOutput
putStrLn ","
hFlush stdout
-- Echo output to stderr when verbose flag is set
when verbose $ do
hPut stderr encodedOutput
hPut stderr "\n"
hFlush stderr
encodeOutput :: [ThemedBlockOutput] -> BS.ByteString encodeOutput :: [ThemedBlockOutput] -> BS.ByteString
encodeOutput blocks = encode $ map renderPangoBlock $ blocks encodeOutput blocks = encode $ map renderPangoBlock $ blocks
renderPangoBlock :: ThemedBlockOutput -> PangoBlock renderPangoBlock :: ThemedBlockOutput -> PangoBlock
...@@ -101,16 +113,16 @@ outputLine MainOptions{verbose} themedBlocks = do ...@@ -101,16 +113,16 @@ outputLine MainOptions{verbose} themedBlocks = do
} }
runBarServer :: BarIO () -> MainOptions -> IO () runBarServer :: BarIO () -> MainOptions -> IO ()
runBarServer defaultBarConfig options = runBarHost barServer (swayBarInput options) runBarServer defaultBarConfig options = runBarHost barServer (swayBarInput options) loadBlocks
where where
barServer :: Consumer [BlockOutput] BarIO () loadBlocks :: BarIO ()
barServer = do loadBlocks = do
-- Load blocks -- Load blocks
lift $ do when (indicator options) $ addBlock renderIndicator
when (indicator options) $ addBlock renderIndicator defaultBarConfig
defaultBarConfig
barServer :: Consumer [BlockOutput] IO ()
barServer = do
-- Event to render the bar (fired when block output or theme is changed) -- Event to render the bar (fired when block output or theme is changed)
renderEvent <- liftIO Event.new renderEvent <- liftIO Event.new
...@@ -118,7 +130,7 @@ runBarServer defaultBarConfig options = runBarHost barServer (swayBarInput optio ...@@ -118,7 +130,7 @@ runBarServer defaultBarConfig options = runBarHost barServer (swayBarInput optio
(output, input) <- liftIO $ spawn $ latest [] (output, input) <- liftIO $ spawn $ latest []
-- MVar that holds the current theme, linked to the input from the above mailbox -- MVar that holds the current theme, linked to the input from the above mailbox
(themedBlockProducerMVar :: MVar (Producer [ThemedBlockOutput] IO (), Bool)) <- liftIO $ newMVar $ (return (), False) (themedBlockProducerMVar :: MVar (Producer [ThemedBlockOutput] IO (), Bool)) <- liftIO $ newMVar $ throw $ userError "Unexpected behavior: Default theme not set"
-- Create control socket -- Create control socket
...@@ -143,9 +155,6 @@ runBarServer defaultBarConfig options = runBarHost barServer (swayBarInput optio ...@@ -143,9 +155,6 @@ runBarServer defaultBarConfig options = runBarHost barServer (swayBarInput optio
-- Set default theme -- Set default theme
setTheme input themedBlockProducerMVar defaultTheme setTheme input themedBlockProducerMVar defaultTheme
-- Print header
putStrLn "{\"version\":1,\"click_events\":true}"
putStrLn "["
-- Run render loop -- Run render loop
liftIO $ link =<< async (renderLoop renderEvent themedBlockProducerMVar) liftIO $ link =<< async (renderLoop renderEvent themedBlockProducerMVar)
...@@ -153,21 +162,29 @@ runBarServer defaultBarConfig options = runBarHost barServer (swayBarInput optio ...@@ -153,21 +162,29 @@ runBarServer defaultBarConfig options = runBarHost barServer (swayBarInput optio
signalPipe renderEvent >-> toOutput output signalPipe renderEvent >-> toOutput output
renderLoop :: Event.Event -> MVar (Producer [ThemedBlockOutput] IO (), Bool) -> IO () renderLoop :: Event.Event -> MVar (Producer [ThemedBlockOutput] IO (), Bool) -> IO ()
renderLoop renderEvent themedBlockProducerMVar = forever $ do renderLoop renderEvent themedBlockProducerMVar = runEffect $
(themedBlocks, isAnimated'') <- modifyMVar themedBlockProducerMVar (\(themedBlockProducer, isAnimated') -> do themeAnimator renderEvent themedBlockProducerMVar >-> filterDuplicates >-> swayBarOutput options
result <- next themedBlockProducer
case result of themeAnimator :: Event.Event -> MVar (Producer [ThemedBlockOutput] IO (), Bool) -> Producer [ThemedBlockOutput] IO ()
-- TODO: fix type safety on this somehow? themeAnimator renderEvent themedBlockProducerMVar = themeAnimator'
Left _ -> throw $ userError "Unexpected behavior: themes and mailboxes should never return" where
Right (themedBlocks, nextThemedBlockProducer) -> themeAnimator' :: Producer [ThemedBlockOutput] IO ()
return ((nextThemedBlockProducer, isAnimated'), (themedBlocks, isAnimated')) themeAnimator' = do
) (themedBlocks, isAnimated'') <- liftIO $ modifyMVar themedBlockProducerMVar (\(themedBlockProducer, isAnimated') -> do
outputLine options themedBlocks result <- next themedBlockProducer
if isAnimated'' case result of
-- Limit to 10 FPS because swaybar rendering is surprisingly expensive -- TODO: fix type safety on this somehow?
-- TODO: make FPS configurable Left _ -> throw $ userError "Unexpected behavior: Themes and output cache mailbox should never return"
then void $ Event.waitTimeout renderEvent 100000 Right (themedBlocks, nextThemedBlockProducer) ->
else Event.wait renderEvent return ((nextThemedBlockProducer, isAnimated'), (themedBlocks, isAnimated'))
)
yield themedBlocks
liftIO $ if isAnimated''
-- Limit to 10 FPS because swaybar rendering is surprisingly expensive
-- TODO: make FPS configurable
then void $ Event.waitTimeout renderEvent 100000
else Event.wait renderEvent
themeAnimator'
setTheme :: Input [BlockOutput] -> MVar (Producer [ThemedBlockOutput] IO (), Bool) -> Theme -> IO () setTheme :: Input [BlockOutput] -> MVar (Producer [ThemedBlockOutput] IO (), Bool) -> Theme -> IO ()
setTheme blockOutputInput themedBlockProducerMVar (StaticTheme theme) = setTheme blockOutputInput themedBlockProducerMVar (StaticTheme theme) =
......
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