summaryrefslogtreecommitdiffstats
path: root/XMonad/StackSet.hs
diff options
context:
space:
mode:
Diffstat (limited to 'XMonad/StackSet.hs')
-rw-r--r--XMonad/StackSet.hs75
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) }
------------------------------------------------------------------------