diff options
Diffstat (limited to 'XMonad/StackSet.hs')
-rw-r--r-- | XMonad/StackSet.hs | 75 |
1 files changed, 35 insertions, 40 deletions
diff --git a/XMonad/StackSet.hs b/XMonad/StackSet.hs index a7e9f6b..da87ccf 100644 --- a/XMonad/StackSet.hs +++ b/XMonad/StackSet.hs @@ -31,12 +31,12 @@ module XMonad.StackSet ( -- * Xinerama operations -- $xinerama lookupWorkspace, - screens, workspaces, allWindows, currentTag, + screens, screenWorkspaces, workspaces, hidden, allWindows, currentTag, -- * Operations on the current stack -- $stackOperations peek, index, integrate, integrate', differentiate, focusUp, focusDown, focusUp', focusDown', focusMaster, focusWindow, - tagMember, renameTag, ensureTags, member, findTag, mapWorkspace, mapLayout, + tagMember, renameTag, member, findTag, mapWorkspace, mapLayout, -- * Modifying the stackset -- $modifyStackset insertUp, delete, delete', filter, @@ -52,9 +52,9 @@ module XMonad.StackSet ( ) where import Prelude hiding (filter) +import Data.Function (on) import Data.Maybe (listToMaybe,isJust,fromMaybe) import qualified Data.List as L (deleteBy,find,splitAt,filter,nub) -import Data.List ( (\\) ) import qualified Data.Map as M (Map,insert,delete,empty) -- $intro @@ -134,12 +134,12 @@ import qualified Data.Map as M (Map,insert,delete,empty) data StackSet i l a sid sd = StackSet { current :: !(Screen i l a sid sd) -- ^ currently focused workspace , visible :: [Screen i l a sid sd] -- ^ non-focused workspaces, visible in xinerama - , hidden :: [Workspace i l a] -- ^ workspaces not visible anywhere , floating :: M.Map a RationalRect -- ^ floating windows } deriving (Show, Read, Eq) -- | Visible workspaces, and their Xinerama screens. -data Screen i l a sid sd = Screen { workspace :: !(Workspace i l a) +data Screen i l a sid sd = Screen { screenWorkspace :: !(Workspace i l a) + , screenHidden :: [Workspace i l a] , screen :: !sid , screenDetail :: !sd } deriving (Show, Read, Eq) @@ -195,9 +195,9 @@ abort x = error $ "xmonad: StackSet: " ++ x -- new :: (Integral s) => l -> [i] -> [sd] -> StackSet i l a s sd new l wids m | not (null wids) && length m <= length wids && not (null m) - = StackSet cur visi unseen M.empty - where (seen,unseen) = L.splitAt (length m) $ map (\i -> Workspace i l Nothing) wids - (cur:visi) = [ Screen i s sd | (i, s, sd) <- zip3 seen [0..] m ] + = StackSet cur visi M.empty + where (seen,_) = L.splitAt (length m) $ map (\i -> Workspace i l Nothing) wids + (cur:visi) = [ Screen i [] s sd | (i, s, sd) <- zip3 seen [0..] m ] -- now zip up visibles with their screen id new _ _ _ = abort "non-positive argument to StackSet.new" @@ -210,21 +210,13 @@ new _ _ _ = abort "non-positive argument to StackSet.new" -- current. view :: (Eq s, Eq i) => i -> StackSet i l a s sd -> StackSet i l a s sd -view i s - | i == currentTag s = s -- current +view i s = s { current = head s', visible = tail s' } + where + s' = map makeVisible (current s : visible s) - | Just x <- L.find ((i==).tag.workspace) (visible s) - -- if it is visible, it is just raised - = s { current = x, visible = current s : L.deleteBy (equating screen) x (visible s) } - - | Just x <- L.find ((i==).tag) (hidden s) -- must be hidden then - -- if it was hidden, it is raised on the xine screen currently used - = s { current = (current s) { workspace = x } - , hidden = workspace (current s) : L.deleteBy (equating tag) x (hidden s) } - - | otherwise = s -- not a member of the stackset - - where equating f = \x y -> f x == f y + makeVisible scr + | Just x <- L.find ((i==) . tag) (screenHidden scr) = scr { screenWorkspace = x, screenHidden = (screenWorkspace scr) : L.deleteBy ((==) `on` tag) x (screenHidden scr)} + | otherwise = scr -- 'Catch'ing this might be hard. Relies on monotonically increasing -- workspace tags defined in 'new' @@ -240,14 +232,15 @@ view i s -- swapped. greedyView :: (Eq s, Eq i) => i -> StackSet i l a s sd -> StackSet i l a s sd -greedyView w ws +{-greedyView w ws | any wTag (hidden ws) = view w ws | (Just s) <- L.find (wTag . workspace) (visible ws) = ws { current = (current ws) { workspace = workspace s } , visible = s { workspace = workspace (current ws) } : L.filter (not . wTag . workspace) (visible ws) } | otherwise = ws - where wTag = (w == ) . tag + where wTag = (w == ) . tag-} +greedyView = view -- --------------------------------------------------------------------- -- $xinerama @@ -255,7 +248,7 @@ greedyView w ws -- | Find the tag of the workspace visible on Xinerama screen 'sc'. -- 'Nothing' if screen is out of bounds. lookupWorkspace :: Eq s => s -> StackSet i l a s sd -> Maybe i -lookupWorkspace sc w = listToMaybe [ tag i | Screen i s _ <- current w : visible w, s == sc ] +lookupWorkspace sc w = listToMaybe [ tag i | Screen i _ s _ <- current w : visible w, s == sc ] -- --------------------------------------------------------------------- -- $stackOperations @@ -267,14 +260,14 @@ lookupWorkspace sc w = listToMaybe [ tag i | Screen i s _ <- current w : visible -- returning the result. It is like 'maybe' for the focused workspace. -- with :: b -> (Stack a -> b) -> StackSet i l a s sd -> b -with dflt f = maybe dflt f . stack . workspace . current +with dflt f = maybe dflt f . stack . screenWorkspace . current -- | -- Apply a function, and a default value for 'Nothing', to modify the current stack. -- modify :: Maybe (Stack a) -> (Stack a -> Maybe (Stack a)) -> StackSet i l a s sd -> StackSet i l a s sd modify d f s = s { current = (current s) - { workspace = (workspace (current s)) { stack = with d f s }}} + { screenWorkspace = (screenWorkspace (current s)) { stack = with d f s }}} -- | -- Apply a function to modify the current stack if it isn't empty, and we don't @@ -379,7 +372,13 @@ screens s = current s : visible s -- | Get a list of all workspaces in the 'StackSet'. workspaces :: StackSet i l a s sd -> [Workspace i l a] -workspaces s = workspace (current s) : map workspace (visible s) ++ hidden s +workspaces s = concatMap screenWorkspaces $ (current s) : (visible s) + +screenWorkspaces :: Screen i l a sid sd -> [Workspace i l a] +screenWorkspaces scr = screenWorkspace scr : screenHidden scr + +hidden :: StackSet i l a s sd -> [Workspace i l a] +hidden = concatMap screenHidden . screens -- | Get a list of all windows in the 'StackSet' in no particular order allWindows :: Eq a => StackSet i l a s sd -> [a] @@ -387,7 +386,7 @@ allWindows = L.nub . concatMap (integrate' . stack) . workspaces -- | Get the tag of the currently focused workspace. currentTag :: StackSet i l a s sd -> i -currentTag = tag . workspace . current +currentTag = tag . screenWorkspace . current -- | Is the given tag present in the 'StackSet'? tagMember :: Eq i => i -> StackSet i l a s sd -> Bool @@ -401,25 +400,24 @@ renameTag o n = mapWorkspace rename -- | Ensure that a given set of workspace tags is present by renaming -- existing workspaces and\/or creating new hidden workspaces as -- necessary. -ensureTags :: Eq i => l -> [i] -> StackSet i l a s sd -> StackSet i l a s sd +{-ensureTags :: Eq i => l -> [i] -> StackSet i l a s sd -> StackSet i l a s sd ensureTags l allt st = et allt (map tag (workspaces st) \\ allt) st where et [] _ s = s et (i:is) rn s | i `tagMember` s = et is rn s et (i:is) [] s = et is [] (s { hidden = Workspace i l Nothing : hidden s }) - et (i:is) (r:rs) s = et is rs $ renameTag r i s + et (i:is) (r:rs) s = et is rs $ renameTag r i s-} -- | Map a function on all the workspaces in the 'StackSet'. mapWorkspace :: (Workspace i l a -> Workspace i l a) -> StackSet i l a s sd -> StackSet i l a s sd mapWorkspace f s = s { current = updScr (current s) - , visible = map updScr (visible s) - , hidden = map f (hidden s) } - where updScr scr = scr { workspace = f (workspace scr) } + , visible = map updScr (visible s) } + where updScr scr = scr { screenWorkspace = f (screenWorkspace scr), screenHidden = map f (screenHidden scr) } -- | Map a function on all the layouts in the 'StackSet'. mapLayout :: (l -> l') -> StackSet i l a s sd -> StackSet i l' a s sd -mapLayout f (StackSet v vs hs m) = StackSet (fScreen v) (map fScreen vs) (map fWorkspace hs) m +mapLayout f (StackSet v vs m) = StackSet (fScreen v) (map fScreen vs) m where - fScreen (Screen ws s sd) = Screen (fWorkspace ws) s sd + fScreen (Screen ws hd s sd) = Screen (fWorkspace ws) (map fWorkspace hd) s sd fWorkspace (Workspace t l s) = Workspace t (f l) s -- | /O(n)/. Is a window in the 'StackSet'? @@ -483,11 +481,8 @@ delete w = sink w . delete' w -- | Only temporarily remove the window from the stack, thereby not destroying special -- information saved in the 'Stackset' delete' :: (Eq a, Eq s) => a -> StackSet i l a s sd -> StackSet i l a s sd -delete' w s = s { current = removeFromScreen (current s) - , visible = map removeFromScreen (visible s) - , hidden = map removeFromWorkspace (hidden s) } +delete' w s = mapWorkspace removeFromWorkspace s where removeFromWorkspace ws = ws { stack = stack ws >>= filter (/=w) } - removeFromScreen scr = scr { workspace = removeFromWorkspace (workspace scr) } ------------------------------------------------------------------------ |