tl;dr
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%" }
More datails
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.hsprogram in~/.config/xmobar/xmobar.hsand, 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".
Some more finding
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
XMonadLoginstead ofStdinReaderin our xmobar.But as you can see, in the
xmobar.hsabove, I useStdinReader; if I plainly substitute that withXMonadLogwithout doing any other change anywhere (and I think I should instead do something inxmobar.hsto make the change work) then two things happen:- the selected work-space will not reflect anymore what workspace I'm in,
- and restarting XMonad via Super+q results in the one more
xmobarprocess to be spawned, without the previous one being killed (in other words, once more I hit Super+q, one more pid is shown bypidof xmobar).
In thexmonad.hsthere a line that doesn't look right to mexmproc <- spawnPipe "xmobar ~/.config/xmonad/xmobar.hs"If I'm using XMobar as a library, then why am I running the
xmobarexecutable (which is at/home/enrico/.cabal/bin/xmobar) passing to it the path to myxmobar.hsinstead 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 andThe 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
xmobarrcapproach.

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 ofwithEasySB,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 toxmobar.hs.Apparently, I've misunderstood the way XMonad and XMobar are supposed to work together:
%XMonadLog%is for.