From ec96ec469e9dff06bc503366ff7e3022c595d8f7 Mon Sep 17 00:00:00 2001 From: Guy Gastineau Date: Tue, 14 Sep 2021 13:05:49 -0400 Subject: Add the QueueReader plugin. * A queue reader for xmobar using `TQueue a` from `stm`. This is a flexible and performat solution for sharing data between arbitrary haskell and xmobar. * I am not sure if I did the haddocks correctly. --- src/Xmobar.hs | 2 ++ src/Xmobar/Plugins/QueueReader.hs | 50 +++++++++++++++++++++++++++++++++++++++ xmobar.cabal | 1 + 3 files changed, 53 insertions(+) create mode 100644 src/Xmobar/Plugins/QueueReader.hs diff --git a/src/Xmobar.hs b/src/Xmobar.hs index f37f065..28ef354 100644 --- a/src/Xmobar.hs +++ b/src/Xmobar.hs @@ -33,6 +33,7 @@ module Xmobar (xmobar #endif , module Xmobar.Plugins.EWMH , module Xmobar.Plugins.HandleReader + , module Xmobar.Plugins.QueueReader , module Xmobar.Plugins.Kbd , module Xmobar.Plugins.Locks #ifdef INOTIFY @@ -60,6 +61,7 @@ import Xmobar.Plugins.DateZone #endif import Xmobar.Plugins.EWMH import Xmobar.Plugins.HandleReader +import Xmobar.Plugins.QueueReader import Xmobar.Plugins.Kbd import Xmobar.Plugins.Locks #ifdef INOTIFY diff --git a/src/Xmobar/Plugins/QueueReader.hs b/src/Xmobar/Plugins/QueueReader.hs new file mode 100644 index 0000000..cf60c1d --- /dev/null +++ b/src/Xmobar/Plugins/QueueReader.hs @@ -0,0 +1,50 @@ +{-# LANGUAGE RecordWildCards #-} +module Xmobar.Plugins.QueueReader + (QueueReader (..) + ) where + +import Xmobar.Run.Exec (Exec (..)) + +import Control.Monad (forever) +import qualified Control.Concurrent.STM as STM + +-- | A 'QueueReader' displays data from an 'TQueue a' where +-- the data items 'a' are rendered by a user supplied function. +-- +-- Like the 'HandleReader' plugin this is only useful if you are +-- running @xmobar@ from other Haskell code. You should create a +-- new @TQueue a@ and pass it to this plugin. +-- +-- @ +-- main :: IO +-- main = do +-- q <- STM.newQueueIO @String +-- bar <- forkIO $ xmobar conf +-- { commands = Run (QueueReader q id "Queue") : commands conf } +-- STM.atomically $ STM.writeTQueue q "Some Message" +-- @ +data QueueReader a + = QueueReader + { qQueue :: STM.TQueue a + , qShowItem :: a -> String + , qName :: String + } + +-- | This cannot be read back. +instance Show (QueueReader a) where + -- | Only show the name/alias for the queue reader. + show q = "QueueReader " <> qName q + +-- | WARNING: This read instance will throw an exception if used! It is +-- only implemented, because it is required by 'Xmobar.Run` in 'Xmobar.commands'. +instance Read (QueueReader a) where + -- | Throws an 'error'! + readsPrec = error "QueueReader: instance is a stub" + +-- | Async queue/channel reading. +instance Exec (QueueReader a) where + -- | Read from queue as data arrives. + start QueueReader{..} cb = + forever (STM.atomically (qShowItem <$> STM.readTQueue qQueue) >>= cb) + + alias = qName diff --git a/xmobar.cabal b/xmobar.cabal index 5c16dc1..7bc6a61 100644 --- a/xmobar.cabal +++ b/xmobar.cabal @@ -140,6 +140,7 @@ library Xmobar.Plugins.Date, Xmobar.Plugins.EWMH, Xmobar.Plugins.HandleReader, + Xmobar.Plugins.QueueReader, Xmobar.Plugins.PipeReader, Xmobar.Plugins.MarqueePipeReader, Xmobar.Plugins.StdinReader, -- cgit v1.2.3