{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeSynonymInstances #-}
module XMonad.Layout.SortedLayout
(
sorted
, Property(..)
) where
import Control.Monad
import Data.Functor ((<$>))
import Data.List
import XMonad
import XMonad.Layout.LayoutModifier
import XMonad.StackSet as W
import XMonad.Util.WindowProperties
sorted :: [Property]
-> l a
-> ModifiedLayout SortedLayout l a
sorted props = ModifiedLayout . SortedLayout $ props ++ [Const True]
data WindowDescriptor = WindowDescriptor { wdSeqn :: !Integer
, wdProp :: !Property
, wdId :: !Window
} deriving (Show, Read)
instance Eq WindowDescriptor where
(==) a b = wdId a == wdId b
instance Ord WindowDescriptor where
compare a b = compare (wdSeqn a) (wdSeqn b)
data SortedLayout a = SortedLayout [Property] deriving (Show, Read)
instance LayoutModifier SortedLayout Window where
modifyLayout (SortedLayout props) = sortLayout props
modifierDescription _ = "Sorted"
findMatchingWindows :: Integer -> Property -> [Window] -> X [WindowDescriptor]
findMatchingWindows seqn prop wids = fmap (fmap (WindowDescriptor seqn prop)) matching where
matching = filterM (hasProperty prop) wids
sortLayout :: (LayoutClass l Window)
=> [Property]
-> W.Workspace WorkspaceId (l Window) Window
-> Rectangle
-> X ([(Window, Rectangle)], Maybe (l Window))
sortLayout props (W.Workspace w l r) rect = do
let wids = W.integrate' r
sortedWids <- map wdId . nub . sort . concat <$> zipWithM (\s p -> findMatchingWindows s p wids) [0..] props
let sr = W.differentiate sortedWids
runLayout (W.Workspace w l sr) rect