I don't like the behavior of default toggle of xmobar. So I decided to make my own toggle.
toggleXmobar :: X ()
toggleXmobar = do
isRunning <- isApplicationRunning "xmobar"
if isRunning
then spawn "pkill xmobar"
else spawn "xmobar"
isApplicationRunning :: String -> X Bool
isApplicationRunning appName = do
ws <- gets windowset
let wins = allWindows ws
anyM (runQuery (className =? appName)) wins
anyM :: Monad m => (a -> m Bool) -> [a] -> m Bool
anyM _ [] = return False
anyM p (x : xs) = do
result <- p x
if result then return True else anyM p xs
Hard point is isApplicationRunning
.
It always say that xmobar is not running.
How can I fix it?
The most likely explanation for the behavior you're seeing is that xmobar registers itself as a dock, and you have configured xmonad to ignore docks.
One way around would be to manually traverse the window tree. You can use
asks display
orwithDisplay
to retrieve the X connection,screenCount
to determine how many screens there are,rootWindow
to retrieve the root for each screen, andqueryTree
to peruse the children (recursively, presumably).It's possible there's something in xmonad already to help with this, I'm not sure.