mirror of
https://github.com/xmonad/xmonad-contrib.git
synced 2025-08-07 15:31:54 -07:00
X.H.DynamicBars: support per-monitor cleanup
Add functions to allow cleaning up only screens which disappear. This works better where killing the statusbar for a specific screen is possible. The old way is still relevant for setups which do not have such a method (e.g., safeSpawn xmobar/spawnPipe xmonadpropwrite).
This commit is contained in:
@@ -18,8 +18,11 @@ module XMonad.Hooks.DynamicBars (
|
|||||||
-- $usage
|
-- $usage
|
||||||
DynamicStatusBar
|
DynamicStatusBar
|
||||||
, DynamicStatusBarCleanup
|
, DynamicStatusBarCleanup
|
||||||
|
, DynamicStatusBarPartialCleanup
|
||||||
, dynStatusBarStartup
|
, dynStatusBarStartup
|
||||||
|
, dynStatusBarStartup'
|
||||||
, dynStatusBarEventHook
|
, dynStatusBarEventHook
|
||||||
|
, dynStatusBarEventHook'
|
||||||
, multiPP
|
, multiPP
|
||||||
, multiPPFormat
|
, multiPPFormat
|
||||||
) where
|
) where
|
||||||
@@ -30,6 +33,7 @@ import Control.Monad
|
|||||||
import Control.Monad.Trans (lift)
|
import Control.Monad.Trans (lift)
|
||||||
import Control.Monad.Writer (WriterT, execWriterT, tell)
|
import Control.Monad.Writer (WriterT, execWriterT, tell)
|
||||||
|
|
||||||
|
import Data.List
|
||||||
import Data.Maybe
|
import Data.Maybe
|
||||||
import Data.Monoid
|
import Data.Monoid
|
||||||
import Data.Foldable (traverse_)
|
import Data.Foldable (traverse_)
|
||||||
@@ -69,37 +73,67 @@ import qualified XMonad.Util.ExtensibleState as XS
|
|||||||
--
|
--
|
||||||
|
|
||||||
data DynStatusBarInfo = DynStatusBarInfo
|
data DynStatusBarInfo = DynStatusBarInfo
|
||||||
{ dsbInfoScreens :: [ScreenId]
|
{ dsbInfo :: [(ScreenId, Handle)]
|
||||||
, dsbInfoHandles :: [Handle]
|
|
||||||
} deriving (Typeable)
|
} deriving (Typeable)
|
||||||
|
|
||||||
instance ExtensionClass DynStatusBarInfo where
|
instance ExtensionClass DynStatusBarInfo where
|
||||||
initialValue = DynStatusBarInfo [] []
|
initialValue = DynStatusBarInfo []
|
||||||
|
|
||||||
type DynamicStatusBar = ScreenId -> IO Handle
|
type DynamicStatusBar = ScreenId -> IO Handle
|
||||||
type DynamicStatusBarCleanup = IO ()
|
type DynamicStatusBarCleanup = IO ()
|
||||||
|
type DynamicStatusBarPartialCleanup = ScreenId -> IO ()
|
||||||
|
|
||||||
dynStatusBarStartup :: DynamicStatusBar -> DynamicStatusBarCleanup -> X ()
|
dynStatusBarSetup :: X ()
|
||||||
dynStatusBarStartup sb cleanup = do
|
dynStatusBarSetup = do
|
||||||
dpy <- asks display
|
dpy <- asks display
|
||||||
root <- asks theRoot
|
root <- asks theRoot
|
||||||
io $ xrrSelectInput dpy root rrScreenChangeNotifyMask
|
io $ xrrSelectInput dpy root rrScreenChangeNotifyMask
|
||||||
|
|
||||||
|
dynStatusBarStartup :: DynamicStatusBar -> DynamicStatusBarCleanup -> X ()
|
||||||
|
dynStatusBarStartup sb cleanup = do
|
||||||
|
dynStatusBarSetup
|
||||||
updateStatusBars sb cleanup
|
updateStatusBars sb cleanup
|
||||||
|
|
||||||
|
dynStatusBarStartup' :: DynamicStatusBar -> DynamicStatusBarPartialCleanup -> X ()
|
||||||
|
dynStatusBarStartup' sb cleanup = do
|
||||||
|
dynStatusBarSetup
|
||||||
|
updateStatusBars' sb cleanup
|
||||||
|
|
||||||
dynStatusBarEventHook :: DynamicStatusBar -> DynamicStatusBarCleanup -> Event -> X All
|
dynStatusBarEventHook :: DynamicStatusBar -> DynamicStatusBarCleanup -> Event -> X All
|
||||||
dynStatusBarEventHook sb cleanup (RRScreenChangeNotifyEvent {}) = updateStatusBars sb cleanup >> return (All True)
|
dynStatusBarEventHook sb cleanup = dynStatusBarRun (updateStatusBars sb cleanup)
|
||||||
dynStatusBarEventHook _ _ _ = return (All True)
|
|
||||||
|
dynStatusBarEventHook' :: DynamicStatusBar -> DynamicStatusBarPartialCleanup -> Event -> X All
|
||||||
|
dynStatusBarEventHook' sb cleanup = dynStatusBarRun (updateStatusBars' sb cleanup)
|
||||||
|
|
||||||
|
dynStatusBarRun :: X () -> Event -> X All
|
||||||
|
dynStatusBarRun action (RRScreenChangeNotifyEvent {}) = action >> return (All True)
|
||||||
|
dynStatusBarRun _ _ = return (All True)
|
||||||
|
|
||||||
updateStatusBars :: DynamicStatusBar -> DynamicStatusBarCleanup -> X ()
|
updateStatusBars :: DynamicStatusBar -> DynamicStatusBarCleanup -> X ()
|
||||||
updateStatusBars sb cleanup = do
|
updateStatusBars sb cleanup = do
|
||||||
dsbInfo <- XS.get
|
(dsbInfoScreens, dsbInfoHandles) <- XS.get >>= return . unzip . dsbInfo
|
||||||
screens <- getScreens
|
screens <- getScreens
|
||||||
when (screens /= dsbInfoScreens dsbInfo) $ do
|
when (screens /= dsbInfoScreens) $ do
|
||||||
newHandles <- liftIO $ do
|
newHandles <- liftIO $ do
|
||||||
hClose `mapM_` dsbInfoHandles dsbInfo
|
hClose `mapM_` dsbInfoHandles
|
||||||
cleanup
|
cleanup
|
||||||
mapM sb screens
|
mapM sb screens
|
||||||
XS.put $ DynStatusBarInfo screens newHandles
|
XS.put $ DynStatusBarInfo (zip screens newHandles)
|
||||||
|
|
||||||
|
updateStatusBars' :: DynamicStatusBar -> DynamicStatusBarPartialCleanup -> X ()
|
||||||
|
updateStatusBars' sb cleanup = do
|
||||||
|
(dsbInfoScreens, dsbInfoHandles) <- XS.get >>= return . unzip . dsbInfo
|
||||||
|
screens <- getScreens
|
||||||
|
when (screens /= dsbInfoScreens) $ do
|
||||||
|
let oldInfo = zip dsbInfoScreens dsbInfoHandles
|
||||||
|
let (infoToKeep, infoToClose) = partition (flip elem screens . fst) oldInfo
|
||||||
|
newInfo <- liftIO $ do
|
||||||
|
mapM_ hClose $ map snd infoToClose
|
||||||
|
mapM_ cleanup $ map fst infoToClose
|
||||||
|
let newScreens = screens \\ dsbInfoScreens
|
||||||
|
newHandles <- mapM sb newScreens
|
||||||
|
return $ zip newScreens newHandles
|
||||||
|
XS.put . DynStatusBarInfo $ infoToKeep ++ newInfo
|
||||||
|
|
||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
-- The following code is from adamvo's xmonad.hs file.
|
-- The following code is from adamvo's xmonad.hs file.
|
||||||
@@ -112,8 +146,8 @@ multiPP = multiPPFormat dynamicLogString
|
|||||||
|
|
||||||
multiPPFormat :: (PP -> X String) -> PP -> PP -> X ()
|
multiPPFormat :: (PP -> X String) -> PP -> PP -> X ()
|
||||||
multiPPFormat dynlStr focusPP unfocusPP = do
|
multiPPFormat dynlStr focusPP unfocusPP = do
|
||||||
dsbInfo <- XS.get
|
(_, dsbInfoHandles) <- XS.get >>= return . unzip . dsbInfo
|
||||||
multiPP' dynlStr focusPP unfocusPP (dsbInfoHandles dsbInfo)
|
multiPP' dynlStr focusPP unfocusPP dsbInfoHandles
|
||||||
|
|
||||||
multiPP' :: (PP -> X String) -> PP -> PP -> [Handle] -> X ()
|
multiPP' :: (PP -> X String) -> PP -> PP -> [Handle] -> X ()
|
||||||
multiPP' dynlStr focusPP unfocusPP handles = do
|
multiPP' dynlStr focusPP unfocusPP handles = do
|
||||||
|
Reference in New Issue
Block a user