如何在多个屏幕上运行自定义构建的 xmobar

问题描述 投票:0回答:1

我当前正在使用

xmobar
参数运行在两台显示器上安装
-x
的系统。我的
xmonad
是使用堆栈自定义构建的,并生成两个独立的 xmobar 进程,如下所示:

main :: IO ()
main = do
  bars <- traverse (spawnPipe . mappend "xmobar ~/.xmonad/resources/xmobar.hs -x ") ["0", "1"]
  xmonad . plugins $
    def
      { manageHook = myManageHook,
        layoutHook = myLayout,
        logHook = for_ bars myLogHook,
      }

我想迁移到自定义构建我自己的 xmobar 实例,但如果我这样做,我将无法使用

-x <screen>
功能,除非我自己实现它。我想,如果我要自己做这件事,为什么不让我的自定义 xmobar 自动在多个屏幕上运行? 所以我把它作为我的
App/xmobar/Main.hs

import Control.Concurrent (MVar, ThreadId, forkFinally, newEmptyMVar, newMVar, putMVar, takeMVar)
import Control.Concurrent.Async (forConcurrently_)
import XMonad.Theme.XMobar (configFromTheme)
import XMonad.Theme.XResources (loadXResources)
import Xmobar
import Xmobar.App.Opts

-- import Control.Concurrent (forkIO)

type ChildPool = MVar [MVar ()]

main :: IO ()
main = do
  children <- newMVar []
  config <- fmap configFromTheme <$> loadXResources
  let configs = maybe [] (flip fmap [0, 1] . setScreen) config
  forConcurrently_ configs $ forkChild children . xmobar
  waitForChildren children
  where
    setScreen config sid = config {position = OnScreen sid (position config)}

forkChild :: ChildPool -> IO () -> IO ThreadId
forkChild children io = do
  mvar <- newEmptyMVar
  childs <- takeMVar children
  putMVar children (mvar : childs)
  forkFinally io (const $ putMVar mvar ())

waitForChildren :: ChildPool -> IO ()
waitForChildren children = do
  cs <- takeMVar children
  case cs of
    [] -> return ()
    m : ms -> do
      putMVar children ms
      takeMVar m
      waitForChildren children

并更新

app/xmonad/Main.hs
以使用
bar <- spawnPipe "~/.xmonad/xmobar"

除了有一些错误之外,这种方法是有效的:

  1. 内存使用情况监视器始终是
    Updating...
    (我认为这只是缺少一个库)。
  2. 时钟和系统监视器插件只会在第一次定期更新。第二个屏幕的栏将具有冻结的系统监视器。
  3. UnsafeStdinReader
    一次仅更新一根柱,有时根本不更新。我怀疑这是两个酒吧争夺标准输入的结果。

是否可以从一个进程运行多个xmobars,而我只是做错了(如果是的话,怎么办)或者这整个尝试应该是一个死胡同,我应该实现一个自定义的

-x <SCREENID>
参数并回到我之前所做的事情?

haskell concurrency xmonad xmobar
1个回答
0
投票

我不必自己实现

-x <screen>
功能。我可以使用
configFromArgs
导出的
Xmobar
函数。

main :: IO ()
main = do
  theme <- loadXResources
  let config = maybe defaultConfig configFromTheme theme
  xmobar =<< configFromArgs config

这就是我所需要的。

© www.soinside.com 2019 - 2024. All rights reserved.