XMonad:如何在使用多个屏幕时在 xmobar 上显示当前可见的工作区?
XMonad: how to show the currently visible workspace on xmobar when using multiple screens?
我在具有多个物理屏幕的设置中使用 XMonad。
我希望每个物理屏幕都有一个 xmobar
的实例,其中
显示哪个工作区在该特定屏幕上可见,无论是否
该工作区是否为“当前”/“活动”。
例如
+--------------+ +--------------+
| | | |
| | | |
| | | |
| | | |
+--------------+ +--------------+
|Workspace 3 | |Workspace 5 |
+--------------+ +--------------+
我的电流(为清楚起见最小化)xmonad.hs
如下。
import XMonad
import XMonad.Layout.NoBorders
import XMonad.Hooks.ManageDocks
import XMonad.Hooks.DynamicLog
import XMonad.Util.Run
import XMonad.Layout.IndependentScreens
main = do
n <- countScreens
xmprocs <- mapM (\i -> spawnPipe $ "xmobar" ++ " -x " ++ show i) [0..n-1]
xmonad $ docks def
{ layoutHook = avoidStruts $ smartBorders $ layoutHook defaultConfig
, logHook = mapM_ (\xmobarPipe -> dynamicLogWithPP $ def
{ ppOutput = hPutStrLn xmobarPipe
, ppCurrent = \s -> s
, ppVisible = \s -> ""
, ppHidden = \s -> ""
, ppLayout = \s -> ""
, ppTitle = \s -> ""
}) xmprocs
}
也就是说,我设法生成了 2 个 xmobar 实例,每个屏幕一个。然而,它只是在两个屏幕的 xmobar 上显示当前活动的工作区(跨屏幕)。例如。它会显示:
+--------------+ +--------------+
| | | |
| | | |
| | | |
| | | |
+--------------+ +--------------+
|Workspace 3 | |Workspace 3 |
+--------------+ +--------------+
现在,我该如何实现我真正想要的东西?
我认为这里的配置
https://github.com/nwf/xconfig/blob/208e6d6ce48fba45ec30bb1df1389f9ff2263edd/xmonad/lib/XMonad/Actions/XMobars.hs#L163
可能包含答案的提示,但我在 Haskell 到
方面不够熟练
从那个例子回到我可以使用的最小的东西。
这个有效:
import GHC.IO.Handle.Types (Handle)
import XMonad (MonadIO, WorkspaceId, Layout, Window, ScreenId, ScreenDetail, WindowSet, layoutHook, logHook, X, io, ScreenId(..), gets, windowset, xmonad)
import Graphics.X11.ExtraTypes.XF86 (xF86XK_MonBrightnessUp, xF86XK_MonBrightnessDown)
import XMonad.Layout.NoBorders (smartBorders)
import XMonad.Hooks.ManageDocks (docks, avoidStruts)
import XMonad.Hooks.DynamicLog (def)
import XMonad.Util.Run (spawnPipe, hPutStrLn)
import XMonad.Layout.IndependentScreens (countScreens)
import XMonad.StackSet (current, screen, visible, Screen, workspace, tag)
spawnXMobar :: MonadIO m => Int -> m (Int, Handle)
spawnXMobar i = (spawnPipe $ "xmobar" ++ " -x " ++ show i) >>= (\handle -> return (i, handle))
spawnXMobars :: MonadIO m => Int -> m [(Int, Handle)]
spawnXMobars n = mapM spawnXMobar [0..n-1]
type ScreenFoo = Screen WorkspaceId (Layout Window) Window ScreenId ScreenDetail
visibleScreens :: WindowSet -> [ScreenFoo]
visibleScreens cws = ([current cws]) ++ (visible cws)
joinToString :: [String] -> String
joinToString workspaceIds = foldl (++) "" workspaceIds
myLogHookForPipe :: WindowSet -> (Int, Handle) -> X ()
myLogHookForPipe currentWindowSet (i, xmobarPipe) =
io $ hPutStrLn xmobarPipe $ -- write to pipe and lift to XMonad
joinToString $ map (tag . workspace) $ -- extract workspace names and join into a single string
filter ((==) (S i) . screen) $ -- filter to this xmobar's screen only
visibleScreens currentWindowSet -- get list of all visible screens
myLogHook :: [(Int, Handle)] -> X ()
myLogHook xmobarPipes = do
currentWindowSet <- gets windowset
mapM_ (myLogHookForPipe currentWindowSet) xmobarPipes
main = do
n <- countScreens
xmobarPipes <- spawnXMobars n
xmonad $ docks def
{ layoutHook = avoidStruts $ smartBorders $ layoutHook def
, logHook = myLogHook xmobarPipes
}
我在具有多个物理屏幕的设置中使用 XMonad。
我希望每个物理屏幕都有一个 xmobar
的实例,其中
显示哪个工作区在该特定屏幕上可见,无论是否
该工作区是否为“当前”/“活动”。
例如
+--------------+ +--------------+
| | | |
| | | |
| | | |
| | | |
+--------------+ +--------------+
|Workspace 3 | |Workspace 5 |
+--------------+ +--------------+
我的电流(为清楚起见最小化)xmonad.hs
如下。
import XMonad
import XMonad.Layout.NoBorders
import XMonad.Hooks.ManageDocks
import XMonad.Hooks.DynamicLog
import XMonad.Util.Run
import XMonad.Layout.IndependentScreens
main = do
n <- countScreens
xmprocs <- mapM (\i -> spawnPipe $ "xmobar" ++ " -x " ++ show i) [0..n-1]
xmonad $ docks def
{ layoutHook = avoidStruts $ smartBorders $ layoutHook defaultConfig
, logHook = mapM_ (\xmobarPipe -> dynamicLogWithPP $ def
{ ppOutput = hPutStrLn xmobarPipe
, ppCurrent = \s -> s
, ppVisible = \s -> ""
, ppHidden = \s -> ""
, ppLayout = \s -> ""
, ppTitle = \s -> ""
}) xmprocs
}
也就是说,我设法生成了 2 个 xmobar 实例,每个屏幕一个。然而,它只是在两个屏幕的 xmobar 上显示当前活动的工作区(跨屏幕)。例如。它会显示:
+--------------+ +--------------+
| | | |
| | | |
| | | |
| | | |
+--------------+ +--------------+
|Workspace 3 | |Workspace 3 |
+--------------+ +--------------+
现在,我该如何实现我真正想要的东西?
我认为这里的配置
https://github.com/nwf/xconfig/blob/208e6d6ce48fba45ec30bb1df1389f9ff2263edd/xmonad/lib/XMonad/Actions/XMobars.hs#L163
可能包含答案的提示,但我在 Haskell 到
方面不够熟练
从那个例子回到我可以使用的最小的东西。
这个有效:
import GHC.IO.Handle.Types (Handle)
import XMonad (MonadIO, WorkspaceId, Layout, Window, ScreenId, ScreenDetail, WindowSet, layoutHook, logHook, X, io, ScreenId(..), gets, windowset, xmonad)
import Graphics.X11.ExtraTypes.XF86 (xF86XK_MonBrightnessUp, xF86XK_MonBrightnessDown)
import XMonad.Layout.NoBorders (smartBorders)
import XMonad.Hooks.ManageDocks (docks, avoidStruts)
import XMonad.Hooks.DynamicLog (def)
import XMonad.Util.Run (spawnPipe, hPutStrLn)
import XMonad.Layout.IndependentScreens (countScreens)
import XMonad.StackSet (current, screen, visible, Screen, workspace, tag)
spawnXMobar :: MonadIO m => Int -> m (Int, Handle)
spawnXMobar i = (spawnPipe $ "xmobar" ++ " -x " ++ show i) >>= (\handle -> return (i, handle))
spawnXMobars :: MonadIO m => Int -> m [(Int, Handle)]
spawnXMobars n = mapM spawnXMobar [0..n-1]
type ScreenFoo = Screen WorkspaceId (Layout Window) Window ScreenId ScreenDetail
visibleScreens :: WindowSet -> [ScreenFoo]
visibleScreens cws = ([current cws]) ++ (visible cws)
joinToString :: [String] -> String
joinToString workspaceIds = foldl (++) "" workspaceIds
myLogHookForPipe :: WindowSet -> (Int, Handle) -> X ()
myLogHookForPipe currentWindowSet (i, xmobarPipe) =
io $ hPutStrLn xmobarPipe $ -- write to pipe and lift to XMonad
joinToString $ map (tag . workspace) $ -- extract workspace names and join into a single string
filter ((==) (S i) . screen) $ -- filter to this xmobar's screen only
visibleScreens currentWindowSet -- get list of all visible screens
myLogHook :: [(Int, Handle)] -> X ()
myLogHook xmobarPipes = do
currentWindowSet <- gets windowset
mapM_ (myLogHookForPipe currentWindowSet) xmobarPipes
main = do
n <- countScreens
xmobarPipes <- spawnXMobars n
xmonad $ docks def
{ layoutHook = avoidStruts $ smartBorders $ layoutHook def
, logHook = myLogHook xmobarPipes
}