如何在 XMonad 的每个屏幕上放置一个 XMobar 实例?

How to put an instance of XMobar on each screen in XMonad?

我 运行 XMonad 在笔记本电脑上使用,我有时(但并非总是)附加了一个额外的显示器。我想检测我的 xmonad.hs 中的屏幕数量,每个屏幕有一个 XMobar 实例。

我看过 this question and answer,但我并没有真正了解 monad 转换器以及如何使用 X [Rectangle].

类型的值

现在,我大概有这个:

import XMonad
import XMonad.Config.Desktop
import XMonad.Hooks.DynamicLog
import XMonad.Hooks.ManageDocks
import XMonad.Util.Run(spawnPipe)
import XMonad.Core (X ,withDisplay ,io)
import Graphics.X11.Xinerama (getScreenInfo)
import Graphics.X11.Xlib.Types (Rectangle)
import System.IO

xdisplays :: X [Rectangle]
xdisplays = withDisplay $ io . getScreenInfo

main = do
    xmproc <- spawnPipe "/usr/bin/xmobar /home/liam/.xmobarrc"
    xmonad $ desktopConfig
        { layoutHook = avoidStruts $ layoutHook defaultConfig,
          manageHook = manageHook defaultConfig <+> manageDocks,
          logHook = dynamicLogWithPP xmobarPP
            { ppOutput = hPutStrLn xmproc
            }
        }

天真地,我想把 rects <- xdisplays 放在我的 do 块的开头,然后适当地生成 xmobar 实例,但显然这不起作用,因为类型是 X [Rectangle] 而不是 IO [Rectangle]。我想知道我是否需要以某种方式使用 runX

对 xmonad 的每次调用使用 startupHook 到 运行 一个 X 操作。例如,

main = xmonad $ desktopConfig
    { startupHook = do
        rects <- xdisplays
        {- spawn xmobar -}
    }

您可能还喜欢 countScreens if all you actually care about is how many screens there are and spawnOnce 这样您就不会在每次重新启动 xmonad 时都获得额外的 xmobar 副本。