mirror of
https://github.com/xmonad/xmonad-contrib.git
synced 2025-05-19 11:30:22 -07:00
Rename 'spawnStatusBarAndRemember' and 'cleanupStatusBars', made them
command specific - The names were awfully long. spawnStatusBar and killStatusBar are perfectly fine alternatives. - It's more flexible to have killStatusBar command specific. Also added killAllStatusBars to provide the old functionality
This commit is contained in:
parent
7ad38d4063
commit
b6e364ce42
@ -44,25 +44,23 @@ module XMonad.Hooks.StatusBar (
|
|||||||
xmonadPropLog',
|
xmonadPropLog',
|
||||||
xmonadDefProp,
|
xmonadDefProp,
|
||||||
|
|
||||||
-- * Managing Status Bar Processes
|
-- * Managing status bar Processes
|
||||||
spawnStatusBarAndRemember,
|
-- $sbprocess
|
||||||
cleanupStatusBars,
|
spawnStatusBar,
|
||||||
|
killStatusBar,
|
||||||
-- * Manual Plumbing
|
killAllStatusBars,
|
||||||
-- $plumbing
|
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Control.Exception (SomeException, try)
|
import Control.Exception (SomeException, try)
|
||||||
import qualified Codec.Binary.UTF8.String as UTF8 (encode)
|
import qualified Codec.Binary.UTF8.String as UTF8 (encode)
|
||||||
|
import qualified Data.Map as M
|
||||||
import System.Posix.Signals (sigTERM, signalProcessGroup)
|
import System.Posix.Signals (sigTERM, signalProcessGroup)
|
||||||
import System.Posix.Types (ProcessID)
|
import System.Posix.Types (ProcessID)
|
||||||
|
|
||||||
import qualified Data.Map as M
|
|
||||||
|
|
||||||
import Foreign.C (CChar)
|
import Foreign.C (CChar)
|
||||||
|
|
||||||
import XMonad
|
import XMonad
|
||||||
import XMonad.Prelude (void)
|
import XMonad.Prelude ( traverse_, void )
|
||||||
|
|
||||||
import XMonad.Util.Run
|
import XMonad.Util.Run
|
||||||
import qualified XMonad.Util.ExtensibleState as XS
|
import qualified XMonad.Util.ExtensibleState as XS
|
||||||
@ -70,6 +68,7 @@ import qualified XMonad.Util.ExtensibleState as XS
|
|||||||
import XMonad.Layout.LayoutModifier
|
import XMonad.Layout.LayoutModifier
|
||||||
import XMonad.Hooks.ManageDocks
|
import XMonad.Hooks.ManageDocks
|
||||||
import XMonad.Hooks.StatusBar.PP
|
import XMonad.Hooks.StatusBar.PP
|
||||||
|
import qualified XMonad.StackSet as W
|
||||||
|
|
||||||
-- $usage
|
-- $usage
|
||||||
-- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@:
|
-- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@:
|
||||||
@ -189,7 +188,7 @@ import XMonad.Hooks.StatusBar.PP
|
|||||||
-- chosen status bar from spawning again). Using 'statusBarProp', however, takes
|
-- chosen status bar from spawning again). Using 'statusBarProp', however, takes
|
||||||
-- care of the necessary plumbing /and/ keeps track of the started status bars, so
|
-- care of the necessary plumbing /and/ keeps track of the started status bars, so
|
||||||
-- they can be correctly restarted with xmonad. This is achieved using
|
-- they can be correctly restarted with xmonad. This is achieved using
|
||||||
-- 'spawnStatusBarAndRemember' to start them and 'cleanupStatusBars' to kill
|
-- 'spawnStatusBar' to start them and 'killStatusBar' to kill
|
||||||
-- previously started bars.
|
-- previously started bars.
|
||||||
--
|
--
|
||||||
-- Even if you don't use a status bar, you can still use 'dynamicLogString' to
|
-- Even if you don't use a status bar, you can still use 'dynamicLogString' to
|
||||||
@ -297,8 +296,8 @@ statusBarPropTo :: String -- ^ Property to write the string to
|
|||||||
-> StatusBarConfig
|
-> StatusBarConfig
|
||||||
statusBarPropTo prop cmd pp = def
|
statusBarPropTo prop cmd pp = def
|
||||||
{ sbLogHook = xmonadPropLog' prop =<< dynamicLogString =<< pp
|
{ sbLogHook = xmonadPropLog' prop =<< dynamicLogString =<< pp
|
||||||
, sbStartupHook = spawnStatusBarAndRemember cmd
|
, sbStartupHook = spawnStatusBar cmd
|
||||||
, sbCleanupHook = cleanupStatusBars
|
, sbCleanupHook = killStatusBar cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
-- | Like 'statusBarProp', but uses pipe-based logging instead.
|
-- | Like 'statusBarProp', but uses pipe-based logging instead.
|
||||||
@ -389,41 +388,50 @@ xmonadPropLog' prop msg = do
|
|||||||
|
|
||||||
-- This newtype wrapper, together with the ExtensionClass instance make use of
|
-- This newtype wrapper, together with the ExtensionClass instance make use of
|
||||||
-- the extensible state to save the PIDs bewteen xmonad restarts.
|
-- the extensible state to save the PIDs bewteen xmonad restarts.
|
||||||
newtype StatusBarPIDs = StatusBarPIDs { getPIDs :: [ProcessID] }
|
newtype StatusBarPIDs = StatusBarPIDs { getPIDs :: M.Map String ProcessID }
|
||||||
deriving (Show, Read)
|
deriving (Show, Read)
|
||||||
|
|
||||||
instance ExtensionClass StatusBarPIDs where
|
instance ExtensionClass StatusBarPIDs where
|
||||||
initialValue = StatusBarPIDs []
|
initialValue = StatusBarPIDs mempty
|
||||||
extensionType = PersistentExtension
|
extensionType = PersistentExtension
|
||||||
|
|
||||||
-- | Kills the status bars started with 'spawnStatusBarAndRemember', and resets
|
-- | Kills the status bar started with 'spawnStatusBar' using the given command
|
||||||
-- the state. This could go for example at the beginning of the startupHook.
|
-- and resets the state. This could go for example at the beginning of the
|
||||||
|
-- startupHook, to kill the status bars that need to be restarted.
|
||||||
--
|
--
|
||||||
-- Concretely, this function sends a 'sigTERM' to the saved PIDs using
|
-- Concretely, this function sends a 'sigTERM' to the saved PIDs using
|
||||||
-- 'signalProcessGroup' to effectively terminate all processes, regardless
|
-- 'signalProcessGroup' to effectively terminate all processes, regardless
|
||||||
-- of how many were started by using 'spawnStatusBarAndRemember'.
|
-- of how many were started by using 'spawnStatusBar'.
|
||||||
--
|
--
|
||||||
-- There is one caveat to keep in mind: to keep the implementation simple;
|
-- There is one caveat to keep in mind: to keep the implementation simple;
|
||||||
-- no checks are executed before terminating the processes. This means: if the
|
-- no checks are executed before terminating the processes. This means: if the
|
||||||
-- started process dies for some reason, and enough time passes for the PIDs
|
-- started process dies for some reason, and enough time passes for the PIDs
|
||||||
-- to wrap around, this function might terminate another process that happens
|
-- to wrap around, this function might terminate another process that happens
|
||||||
-- to have the same PID. However, this isn't a typical usage scenario.
|
-- to have the same PID. However, this isn't a typical usage scenario.
|
||||||
cleanupStatusBars :: X ()
|
killStatusBar :: String -- ^ The command used to start the status bar
|
||||||
cleanupStatusBars =
|
-> X ()
|
||||||
getPIDs <$> XS.get
|
killStatusBar cmd = do
|
||||||
>>= (io . mapM_ killPid)
|
XS.gets (M.lookup cmd . getPIDs) >>= flip whenJust (io . killPid)
|
||||||
>> XS.put (StatusBarPIDs [])
|
XS.modify (StatusBarPIDs . M.delete cmd . getPIDs)
|
||||||
where
|
|
||||||
killPid :: ProcessID -> IO ()
|
|
||||||
killPid pidToKill = void $ try @SomeException (signalProcessGroup sigTERM pidToKill)
|
|
||||||
|
|
||||||
-- | Spawns a status bar and saves its PID. This is useful when the status bars
|
killPid :: ProcessID -> IO ()
|
||||||
-- should be restarted with xmonad. Use this in combination with 'cleanupStatusBars'.
|
killPid pidToKill = void $ try @SomeException (signalProcessGroup sigTERM pidToKill)
|
||||||
|
|
||||||
|
-- | Spawns a status bar and saves its PID together with the commands that was
|
||||||
|
-- used to start it. This is useful when the status bars should be restarted
|
||||||
|
-- with xmonad. Use this in combination with 'killStatusBar'.
|
||||||
--
|
--
|
||||||
-- Note: in some systems, multiple processes might start, even though one command is
|
-- Note: in some systems, multiple processes might start, even though one command is
|
||||||
-- provided. This means the first PID, of the group leader, is saved.
|
-- provided. This means the first PID, of the group leader, is saved.
|
||||||
spawnStatusBarAndRemember :: String -- ^ The command used to spawn the status bar
|
spawnStatusBar :: String -- ^ The command used to spawn the status bar
|
||||||
-> X ()
|
-> X ()
|
||||||
spawnStatusBarAndRemember cmd = do
|
spawnStatusBar cmd = do
|
||||||
newPid <- spawnPID cmd
|
newPid <- spawnPID cmd
|
||||||
XS.modify (StatusBarPIDs . (newPid :) . getPIDs)
|
XS.modify (StatusBarPIDs . M.insert cmd newPid . getPIDs)
|
||||||
|
|
||||||
|
|
||||||
|
-- | Kill all status bars started with 'spawnStatusBar'. Note the
|
||||||
|
-- caveats in 'cleanupStatusBar'
|
||||||
|
killAllStatusBars :: X ()
|
||||||
|
killAllStatusBars =
|
||||||
|
XS.gets (M.elems . getPIDs) >>= io . traverse_ killPid >> XS.put (StatusBarPIDs mempty)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user