haskellxmonadxmobar

How can I figure out specific app is running on Xmonad?


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?


Solution

  • 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 or withDisplay to retrieve the X connection, screenCount to determine how many screens there are, rootWindow to retrieve the root for each screen, and queryTree to peruse the children (recursively, presumably).

    It's possible there's something in xmonad already to help with this, I'm not sure.