{-# LANGUAGE DeriveDataTypeable #-} ----------------------------------------------------------------------------- -- | -- Module : XMonad.Util.SpawnNamedPipe -- Copyright : (c) Christian Wills 2014 -- License : BSD3-style (see LICENSE) -- -- Maintainer : cwills.dev@gmail.com -- Stability : unstable -- Portability : not portable -- -- A module for spawning a pipe whose "Handle" lives in the Xmonad state. -- ----------------------------------------------------------------------------- module XMonad.Util.SpawnNamedPipe ( -- * Usage -- $usage spawnNamedPipe , getNamedPipe ) where import XMonad import XMonad.Util.Run import System.IO import qualified XMonad.Util.ExtensibleState as XS import Control.Monad import qualified Data.Map as Map -- $usage -- This module makes it possible to spawn a pipe to Dzen2 in the startupHook -- and write to it from inside the logHook without the need for global -- variables. -- -- > import XMonad.Util.SpawnNamedPipe -- > import Data.Maybe -- > -- > -- StartupHook -- > startupHook' = spawnNamedPipe "dzen2" "dzenPipe" -- > -- > -- LogHook -- > logHook' = do -- > mh <- getNamedPipeHandle "dzenPipe" -- > dynamicLogWithPP $ defaultPP { -- > ppOutput = maybe (\s -> return ()) (hPutStrLn) mh} -- > -- > -- Main -- > main = xmonad $ defaultConfig { -- > startupHook = startupHook' -- > , logHook = logHook'} -- data NamedPipes = NamedPipes { pipeMap :: Map.Map String Handle } deriving (Show, Typeable) instance ExtensionClass NamedPipes where initialValue = NamedPipes Map.empty -- | When 'spawnNamedPipe' is executed with a command "String" and a name -- "String" respectively. The command string is spawned with 'spawnPipe' (as -- long as the name chosen hasn't been used already) and the "Handle" returned -- is saved in Xmonad's state associated with the name "String". spawnNamedPipe :: String -> String -> X () spawnNamedPipe cmd name = do b <- XS.gets (Map.member name . pipeMap) unless b $ do h <- spawnPipe cmd XS.modify (NamedPipes . Map.insert name h . pipeMap) -- | Attempts to retrieve a "Handle" to a pipe previously stored in Xmonad's -- state associated with the given string via a call to 'spawnNamedPipe'. If the -- given string doesn't exist in the map stored in Xmonad's state Nothing is -- returned. getNamedPipe :: String -> X (Maybe Handle) getNamedPipe name = XS.gets (Map.lookup name . pipeMap)