module XMonad.Util.WorkspaceCompare ( WorkspaceCompare, WorkspaceSort
, getWsIndex
, getWsCompare
, getWsCompareByTag
, getXineramaWsCompare
, mkWsSort
, getSortByIndex
, getSortByTag
, getSortByXineramaRule ) where
import XMonad
import qualified XMonad.StackSet as S
import Data.List
import Data.Monoid
import Data.Ord
import Data.Maybe
type WorkspaceCompare = WorkspaceId -> WorkspaceId -> Ordering
type WorkspaceSort = [WindowSpace] -> [WindowSpace]
getWsIndex :: X (WorkspaceId -> Maybe Int)
getWsIndex = do
spaces <- asks (workspaces . config)
return $ flip elemIndex spaces
getWsCompare :: X WorkspaceCompare
getWsCompare = do
wsIndex <- getWsIndex
return $ \a b -> f (wsIndex a) (wsIndex b) `mappend` compare a b
where
f Nothing Nothing = EQ
f (Just _) Nothing = LT
f Nothing (Just _) = GT
f (Just x) (Just y) = compare x y
getWsCompareByTag :: X WorkspaceCompare
getWsCompareByTag = return compare
getXineramaWsCompare :: X WorkspaceCompare
getXineramaWsCompare = do
w <- gets windowset
return $ \ a b -> case (isOnScreen a w, isOnScreen b w) of
(True, True) -> comparing (tagToSid (onScreen w)) a b
(False, False) -> compare a b
(True, False) -> LT
(False, True) -> GT
where
onScreen w = S.current w : S.visible w
isOnScreen a w = a `elem` map (S.tag . S.workspace) (onScreen w)
tagToSid s x = S.screen $ fromJust $ find ((== x) . S.tag . S.workspace) s
mkWsSort :: X WorkspaceCompare -> X WorkspaceSort
mkWsSort cmpX = do
cmp <- cmpX
return $ sortBy (\a b -> cmp (S.tag a) (S.tag b))
getSortByIndex :: X WorkspaceSort
getSortByIndex = mkWsSort getWsCompare
getSortByTag :: X WorkspaceSort
getSortByTag = mkWsSort getWsCompareByTag
getSortByXineramaRule :: X WorkspaceSort
getSortByXineramaRule = mkWsSort getXineramaWsCompare