How do I change this xmonad.hs
,
import XMonad
main :: IO ()
main = xmonad def { terminal = "urxvt" , modMask = mod4Mask }
in order for XMonad to spawn xmobar correctly (spawn once, and kill and re-spawn if I restart XMonad in place, and any other sensible requirement) without an xmobarrc
config file but with an actual xmobar.hs
Haskell file containing the following?
import Xmobar
main :: IO ()
main = xmobar defaultConfig { commands = [Run XMonadLog], template = "%XMonadLog%" }
From XMonad tutorial I read
It is also possible to completely configure xmobar in Haskell, just like xmonad. If you want to know more about that, you can check out the xmobar.hs example in the official documentation. For a more complicated example, you can also check out jao’s xmobar.hs (he’s the current maintainer of xmobar).
In the file at the first link, the instruction is
-- An example of a Haskell-based xmobar. Compile it with
-- ghc --make -- xmobar.hs
-- with the xmobar library installed or simply call:
-- xmobar /path/to/xmobar.hs
-- and xmobar will compile and launch it for you and
and I have verified that indeed executing ghc --make xmbobar.hs
(GHC 9.4.8) generates an xmobar
executable that, when executed, spawns the bar (xmobar /path/to/xmobar.hs
instead just never returns).
But what is the proper way to tell XMonad to run xmobar
?
From the first link in the quote above, I can get here, where I read
Or put your
xmobar.hs
program in~/.config/xmobar/xmobar.hs
and, when running the system-widexmobar
, it will notice that you have your own implementation and (re)compile and run it as needed.
but I still don't know how to have XMobar do the "running system-wide xmobar
".
I think I've got to a minimal working example, but I don't really understand quite a few details.
Given this ~/.config/xmonad/xmonad.hs
,
import XMonad
import XMonad.Hooks.EwmhDesktops
import XMonad.Hooks.StatusBar.PP
import XMonad.Util.Run
main :: IO ()
main = do
xmproc <- spawnPipe "xmobar ~/.config/xmonad/xmobar.hs"
xmonad . ewmhFullscreen
. ewmh
$ myConfig xmproc
myConfig h = def
{ terminal = "urxvt"
, modMask = mod4Mask
, logHook = dynamicLogWithPP xmobarPP
{ ppOutput = hPutStrLn h
}
}
and this ~/.config/xmonad/xmobar.hs
,
import Xmobar
config :: Config
config = defaultConfig
{
commands =
[ Run StdinReader,
Run $ Date "%a %_d %b %Y <fc=#ee9a00>%H:%M:%S</fc>" "date" 10
],
template = "%StdinReader% }{ %date%",
alignSep = "}{"
}
main :: IO ()
main = xmobar config
the two seem to work fine together.
However, below is what I don't understand.
The tutorial mentions a problem I don't really understand yet,
It is thus much better to switch over to property based logging, where we are writing to an X11 property and having xmobar read that; no danger when things are not being read!
but most importantly it concludes that
For this reason we have to use
XMonadLog
instead ofStdinReader
in our xmobar.
But as you can see, in the xmobar.hs
above, I use StdinReader
; if I plainly substitute that with XMonadLog
without doing any other change anywhere (and I think I should instead do something in xmobar.hs
to make the change work) then two things happen:
xmobar
process to be spawned, without the previous one being killed (in other words, once more I hit Super+q, one more pid is shown by pidof xmobar
).In the xmonad.hs
there a line that doesn't look right to me
xmproc <- spawnPipe "xmobar ~/.config/xmonad/xmobar.hs"
If I'm using XMobar as a library, then why am I running the xmobar
executable (which is at /home/enrico/.cabal/bin/xmobar
) passing to it the path to my xmobar.hs
instead of just spawning the executable I have compiled?
Well, going back to this, I think that probably makes sense:
-- An example of a Haskell-based xmobar. Compile it with -- ghc --make -- xmobar.hs -- with the xmobar library installed or simply call: -- xmobar /path/to/xmobar.hs -- and xmobar will compile and launch it for you and
The bar doesn't impose an offset to the windows, so the windows partly cover the bar
and for the life of me, I can't really find how to prevent that; the same thing doesn't happen with the xmobarrc
approach.
Well, my mistake consisted in think that moving from one approach (xmonad.hs
+ xmobarrc
), call it A, to the other approach (xmonad.hs
+ xmobar.hs
), call it B, I was also removing the usage of withEasySB
,
. withEasySB (statusBarProp (unwords ["xmobar", xmobarhs]) (pure myXmobarPP)) toggleStrutsKey
to launch xmobar and just using spawnPipe
(as shown in the question), thinking that with the approach B the configuration of xmobar was all up to xmobar.hs
.
Apparently, I've misunderstood the way XMonad and XMobar are supposed to work together:
%XMonadLog%
is for.