我目前正在使用 alt + ctrl + left 和 alt + ctrl + right 在工作区之间循环:
...
, ((altModMask .|. controlMask, xK_Left),
prevWS)
, ((altModMask .|. controlMask, xK_Right),
nextWS)
这对于单显示器设置来说效果很好。然而,使用双显示器设置时有点令人困惑。这是因为如果当前在另一个屏幕上可见,则要显示的工作区将更改屏幕。例如,如果我在屏幕 0 上有 ws 1,在屏幕 1 上有 ws 2,并且焦点在屏幕 0 上:
1:term (2:web) 3:txt
当我现在执行
nextWS
时,当前在屏幕 1 上的 ws 2 将被绘制到屏幕 0,而屏幕 1 将显示 ws 1。
(1:term) 2:web 3:txt
我想要的是一种行为,其中
prexWS
和nextWS
将跳过当前在另一台显示器上显示的工作区,并且仅选择当前未显示的工作区。
是否已经有这样的命令或者是否有一些
xmonad.hs
示例可以实现此功能?
使用XMonad.Actions.DynamicWorkspaceOrder
中的
xmonad-contrib
:
import qualified XMonad.Actions.DynamicWorkspaceOrder as DO
...
, ((altModMask .|. controlMask, xK_Left),
DO.moveTo Prev HiddenNonEmptyWS)
, ((altModMask .|. controlMask, xK_Right),
DO.moveTo Next HiddenNonEmptyWS)
cycleRecentNonEmptyWS
的版本,它会跳过在其他监视器上可见的工作区:
import Data.Maybe (isJust)
import XMonad
import qualified XMonad.StackSet as W
import XMonad.Actions.CycleRecentWS (cycleWindowSets, recentWS)
cycleRecentHiddenNonEmptyWS :: [KeySym] -> KeySym -> KeySym -> X ()
cycleRecentHiddenNonEmptyWS mods keyNext keyPrev = do
pred <- getPred
cycleWindowSets (recentWS pred) mods keyNext keyPrev
where
-- Based on private function @wsTypeToPred@ in
-- @Xmonad.Actions.CycleWS@. Select workspaces that are non-empty
-- and not on another screen.
getPred :: X (WindowSpace -> Bool)
getPred = withWindowSet $ \ws -> do
-- The hidden windows don't include the currently focused
-- window, which means we can't abort once we start cycling. So,
-- instead, we define "hidden" as "focused or not visible". The
-- @W.visible@ screens are the non-focused but visible ones.
let visibles = map (W.tag . W.workspace) $ W.visible ws
let hidden w = W.tag w `notElem` visibles
let nonEmpty w = isJust (W.stack w)
return (\w -> hidden w && nonEmpty w)
您可以像
cycleRecentNonEmptyWS
一样使用它,例如将其添加到您的按键映射中:
-- The 'xK_grave' is backtick ("`"), so tab cycles
-- forward, and backtick cycles back.
, ((modm, xK_Tab), cycleRecentHiddenNonEmptyWS [xK_Super_L] xK_Tab xK_grave)