我正在嘗試復制 PopOs 在多顯示幕設定中處理作業區的方式
我從 XMonad 處理多顯示幕系統的默認方式中得到了一部分XMonad.Layout.IndependentScreens,每個螢屏都有 10 個作業區
這有點有效,但現在每個顯示幕都有彼此獨立的作業區。我想改變它,所以當我進入顯示幕 A 或 B 上的作業區 1 時,其他顯示幕也進入具有該編號的作業區
我該怎么做呢?
uj5u.com熱心網友回復:
哎呀,事實證明這有點牽扯。沒有好的開箱即用的方法來做到這一點。這是我將如何做到的。首先,我想辦法在每個螢屏上采取一些行動:
traverseScreens :: Applicative f =>
(Screen i l a sid sd -> f (Screen i l a sid' sd')) ->
(StackSet i l a sid sd -> f (StackSet i l a sid' sd'))
traverseScreens f (StackSet cur vis hid flt) = pure StackSet
<*> f cur
<*> traverse f vis
<*> pure hid
<*> pure flt
我們將要采取的行動是將該螢屏上的當前作業區替換為具有相同ScreenId但不同的VirtualWorkspace.
-- oof, what is currently named PhysicalWorkspace should really have
-- been named PhysicalWorkspaceId (and similarly for VirtualWorkspace)
type PhysicalWorkspace' = Workspace PhysicalWorkspace (Layout Window) Window
type PhysicalScreen = Screen PhysicalWorkspace (Layout Window) Window ScreenId ScreenDetail
swapVirtualWorkspace ::
VirtualWorkspace ->
PhysicalScreen ->
MaybeT (State [PhysicalWorkspace']) PhysicalScreen
swapVirtualWorkspace vIdNew scr
| vIdOld == vIdNew = return scr
| otherwise = do
(pre, here:post) <- gets (break pIdMatches)
put (pre [workspace scr] post)
return scr { workspace = here }
where
(sId, vIdOld) = unmarshall . tag . workspace $ scr
pIdMatches ws = unmarshall (tag ws) == (sId, vIdNew)
(如果你只想要代碼而不關心理解它,你可以跳過這一段。)這個動作會跟蹤隱藏作業區的緩慢變化的集合,并且可能會失敗(如果VirtualWorkspace當前螢屏沒有請求的作業區))。為了幫助你讀出的動作:gets (break pIdMatches)搜索隱藏的作業空間的集一,其ScreenId與VirtualWorkspace匹配所提供的螢屏的ID和所提供的虛擬作業空間-即是Workspace我們希望把當前螢屏上。put (pre [workspace scr] post)將當前螢屏上的作業區放入隱藏作業區串列中,并且return scr { workspace = here }將我們找到的作業區放在當前螢屏上;這兩個一起有效地在當前螢屏和隱藏作業區串列之間交換作業區。最后,作為一種特殊情況,如果我們已經在查看具有適當 的作業區VirtualWorkspace,我們(成功地)不會更改任何內容。(如果沒有這個額外的案例,我們可能找不到合適的隱藏作業區,因此將其標記為失敗的更新。)
現在我們可以撰寫一個為每個螢屏PhysicalWindowSpace呼叫swapVirtualWorkspace一次的操作。我們需要小心,我們將通過這種方式計算的隱藏作業區的新集合放回視窗空間。
viewOnAllScreens :: VirtualWorkspace -> WindowSet -> WindowSet
viewOnAllScreens vId ws = case mws' of
Nothing -> ws
Just ws' -> ws' { hidden = hidden' }
where
swapVirtualWorkspaces = traverseScreens (swapVirtualWorkspace vId) ws
(mws', hidden') = runState (runMaybeT swapVirtualWorkspaces) (hidden ws)
如果任何交換失敗,這將使整個WindowSet保持不變——我認為這是一個理智的默認值,在大多數情況下你不應該出現這種情況。
現在您可以更新您的鍵系結以使用viewOnAllScreens. IndependentScreens檔案中的指南如下所示:
keyBindings conf = let modm = modMask conf in fromList $
{- lots of other keybindings -}
[((m .|. modm, k), windows $ onCurrentScreen f i)
| (i, k) <- zip (workspaces' conf) [xK_1 .. xK_9]
, (f, m) <- [(W.greedyView, 0), (W.shift, shiftMask)]]
一種可能的更新可能如下所示:
keyBindings conf = let modm = modMask conf in fromList $
{- lots of other keybindings -}
[ ((m .|. modm, k), windows f)
| (i, k) <- zip (workspaces' conf) [xK_1 .. xK_9]
, (f, m) <- [ (viewOnAllScreens i, 0)
, (viewOnAllScreens i . onCurrentScreen shift i, shiftMask)
]
]
警告講師:我已經檢查了上述型別檢查,但尚未測驗其行為。這當然不是我第一次撰寫正確型別的錯誤......
為了完整起見,這是我用來對上面的內容進行型別檢查的匯入:
import Control.Monad.State
import Control.Monad.Trans.Maybe
import Data.List
import Data.Map (fromList)
import XMonad hiding (Screen)
import XMonad.StackSet
import XMonad.Layout.IndependentScreens
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/379190.html
