如何让XMonad正确使用基于Haskell的Xmobar?
简短总结
如何修改以下xmonad.hs配置:
import XMonad main :: IO () main = xmonad def { terminal = "urxvt" , modMask = mod4Mask }
让XMonad能够正确启动xmobar(仅启动一次,重启XMonad时自动终止并重新启动),且不使用xmobarrc配置文件,而是使用包含以下内容的Haskell文件xmobar.hs:
import Xmobar main :: IO () main = xmobar defaultConfig { commands = [Run XMonadLog], template = "%XMonadLog%" }
详细说明
从XMonad教程中了解到:
也可以像配置XMonad一样,完全用Haskell配置xmobar。如需了解更多信息,可查看官方文档中的xmobar.hs示例。更复杂的示例可查看jao的xmobar.hs(他是xmobar的现任维护者)。
官方示例文件说明如下:
-- 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
验证发现,执行ghc --make xmobar.hs(GHC 9.4.8)会生成一个xmobar可执行文件,运行该文件即可启动状态栏;而xmobar /path/to/xmobar.hs则不会返回。
但不清楚如何正确配置XMonad以启动xmobar。官方文档提到:
或者将你的
xmobar.hs程序放在~/.config/xmobar/xmobar.hs,运行系统级xmobar时,它会检测到你的自定义实现,并按需重新编译和运行。
但仍不清楚如何让XMobar执行"运行系统级xmobar"这一步骤。
更多发现
已得到一个最小可运行示例,但仍有不少细节不理解。
给定~/.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 } }
以及~/.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
两者配合运行正常,但仍有以下疑问:
- 教程中提到:
因此,最好切换到基于属性的日志记录方式,将内容写入X11属性,再由xmobar读取;这样就不会出现内容未被读取的问题!
最重要的是,教程得出结论:
因此,我们必须在xmobar中使用XMonadLog而非StdinReader。
但当前示例的xmobar.hs用的是StdinReader;若直接替换为XMonadLog(未做其他修改),会出现两个问题:- 当前工作区无法正确显示;
- 按Super+q重启XMonad时,会新生成一个
xmobar进程,旧进程未被终止(每按一次,pidof xmobar就会多一个进程ID)。
- 原本对
xmonad.hs中的代码有疑问:
既然将XMobar作为库使用,为何要运行xmproc <- spawnPipe "xmobar ~/.config/xmonad/xmobar.hs"xmobar可执行文件并传入xmobar.hs路径,而非直接启动编译好的可执行文件?
回顾官方示例后认为这一做法合理:-- 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 - 状态栏未为窗口设置偏移,导致窗口部分覆盖状态栏:

一直未能找到解决方法,而使用xmobarrc配置时不会出现此问题。
内容的提问来源于stack exchange,提问作者Enlico

