
New patches:

[switch to nested stacks
David Roundy <droundy@darcs.net>**20071223140340] {
hunk ./XMonad/Operations.hs 133
             this   = W.view n ws
             l = W.layout (W.workspace w)
             flt = filter (flip M.member (W.floating ws)) (W.index this)
-            tiled = (W.stack . W.workspace . W.current $ this)
+            tilednest = (W.nest . W.workspace . W.current $ this)
                     >>= W.filter (`M.notMember` W.floating ws)
                     >>= W.filter (`notElem` vis)
hunk ./XMonad/Operations.hs 136
+            tiled = W.nest2stack `fmap` tilednest
             (SD (Rectangle sx sy sw sh)
                 (gt,gb,gl,gr))          = W.screenDetail w
             viewrect = Rectangle (sx + fromIntegral gl)        (sy + fromIntegral gt)
hunk ./XMonad/StackSet.hs 27
         -- ** Master and Focus
         -- $focus
 
-        StackSet(..), Workspace(..), Screen(..), Stack(..), RationalRect(..),
+        StackSet(..), Workspace(..), Screen(..), Stack(..), Nest, RationalRect(..),
+        stack, nest2stack,
         -- *  Construction
         -- $construction
         new, view, greedyView,
hunk ./XMonad/StackSet.hs 56
     ) where
 
 import Prelude hiding (filter)
-import Data.Maybe   (listToMaybe,fromJust,isJust)
+import Data.Maybe   (listToMaybe,fromJust,isJust,catMaybes)
 import qualified Data.List as L (deleteBy,find,splitAt,filter,nub)
 import Data.List ( (\\) )
 import qualified Data.Map  as M (Map,insert,delete,empty)
hunk ./XMonad/StackSet.hs 183
 -- |
 -- A workspace is just a tag - its index - and a stack
 --
-data Workspace i l a = Workspace  { tag :: !i, layout :: l, stack :: Maybe (Stack a) }
+data Workspace i l a = Workspace  { tag :: !i, layout :: l, nest :: Maybe (Nest a) }
     deriving (Show, Read, Eq)
 
hunk ./XMonad/StackSet.hs 186
+stack :: Workspace i l a -> Maybe (Stack a)
+stack w = nest2stack `fmap` nest w
+
 -- | A structure for window geometries
 data RationalRect = RationalRect Rational Rational Rational Rational
     deriving (Show, Read, Eq)
hunk ./XMonad/StackSet.hs 216
                      , down   :: [a] }     -- jokers to the right
     deriving (Show, Read, Eq)
 
+data Nest a = N1 !a | Nest [Nest a] !(Nest a) [Nest a] deriving (Show, Read, Eq)
+
+nestFocus :: Nest a -> a
+nestFocus (N1 a) = a
+nestFocus (Nest _ f _) = nestFocus f
+
+flattenNest :: Nest a -> [a]
+flattenNest (N1 a) = [a]
+flattenNest (Nest xs y zs) = concatMap flattenNest (xs++y:zs)
+
+nest2stack :: Nest a -> Stack a
+nest2stack (N1 a) = Stack a [] []
+nest2stack (Nest xs y zs) =
+    case nest2stack y of
+    Stack f l r -> Stack f (l++concatMap flattenNest xs) (r++concatMap flattenNest zs)
 
 -- | this function indicates to catch that an error is expected
 abort :: String -> a
hunk ./XMonad/StackSet.hs 320
 -- default value. Otherwise, it applies the function to the stack,
 -- 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 :: b -> (Nest a -> b) -> StackSet i l a s sd -> b
+with dflt f = maybe dflt f . nest . workspace . current
 
 -- |
 -- Apply a function, and a default value for Nothing, to modify the current stack.
hunk ./XMonad/StackSet.hs 326
 --
-modify :: Maybe (Stack a) -> (Stack a -> Maybe (Stack a)) -> StackSet i l a s sd -> StackSet i l a s sd
+modify :: Maybe (Nest a) -> (Nest a -> Maybe (Nest a)) -> StackSet i l a s sd -> StackSet i l a s sd
 modify d f s = s { current = (current s)
hunk ./XMonad/StackSet.hs 328
-                        { workspace = (workspace (current s)) { stack = with d f s }}}
+                        { workspace = (workspace (current s)) { nest = with d f s }}}
 
 -- |
 -- Apply a function to modify the current stack if it isn't empty, and we don't
hunk ./XMonad/StackSet.hs 334
 --  want to empty it.
 --
-modify' :: (Stack a -> Stack a) -> StackSet i l a s sd -> StackSet i l a s sd
+modify' :: (Nest a -> Nest a) -> StackSet i l a s sd -> StackSet i l a s sd
 modify' f = modify Nothing (Just . f)
 
 -- |
hunk ./XMonad/StackSet.hs 342
 -- Return Just that element, or Nothing for an empty stack.
 --
 peek :: StackSet i l a s sd -> Maybe a
-peek = with Nothing (return . focus)
+peek = with Nothing (return . nestFocus)
 
 -- |
 -- /O(n)/. Flatten a Stack into a list.
hunk ./XMonad/StackSet.hs 350
 integrate :: Stack a -> [a]
 integrate (Stack x l r) = reverse l ++ x : r
 
+integrateNest :: Nest a -> [a]
+integrateNest = integrate . nest2stack
+
 -- |
 -- /O(n)/ Flatten a possibly empty stack into a list.
 integrate' :: Maybe (Stack a) -> [a]
hunk ./XMonad/StackSet.hs 370
 -- /O(n)/. 'filter p s' returns the elements of 's' such that 'p' evaluates to
 -- True.  Order is preserved, and focus moves as described for 'delete'.
 --
-filter :: (a -> Bool) -> Stack a -> Maybe (Stack a)
-filter p (Stack f ls rs) = case L.filter p (f:rs) of
-    f':rs' -> Just $ Stack f' (L.filter p ls) rs'    -- maybe move focus down
-    []     -> case L.filter p ls of                  -- filter back up
-                    f':ls' -> Just $ Stack f' ls' [] -- else up
-                    []     -> Nothing
+filter :: (a -> Bool) -> Nest a -> Maybe (Nest a)
+filter p (Nest ls f rs) = case filterl (f:rs) of
+                          f':rs' -> Just $ Nest (filterl ls) f' rs' -- move focus down
+                          [] -> do f':ls' <- return $ filterl ls    -- filter back up
+                                   Just $ Nest ls' f' []            -- else up
+    where filterl = catMaybes . map (filter p)
+filter p (N1 x) = if p x then Just (N1 x) else Nothing
 
 -- |
 -- /O(s)/. Extract the stack on the current workspace, as a list.
hunk ./XMonad/StackSet.hs 385
 -- integration of a one-hole list cursor, back to a list.
 --
 index :: StackSet i l a s sd -> [a]
-index = with [] integrate
+index = with [] integrateNest
 
 -- |
 -- /O(1), O(w) on the wrapping case/.
hunk ./XMonad/StackSet.hs 401
 --
 focusUp, focusDown, swapUp, swapDown :: StackSet i l a s sd -> StackSet i l a s sd
 focusUp   = modify' focusUp'
-focusDown = modify' (reverseStack . focusUp' . reverseStack)
+focusDown = modify' (reverseNest . focusUp' . reverseNest)
 
 swapUp    = modify' swapUp'
hunk ./XMonad/StackSet.hs 404
-swapDown  = modify' (reverseStack . swapUp' . reverseStack)
+swapDown  = modify' (reverseNest . swapUp' . reverseNest)
+
+focusUp', swapUp' :: Nest a -> Nest a
+focusUp' (Nest (l:ls) t rs) = Nest ls l (t:rs)
+focusUp' (Nest []     t rs) = Nest xs x [] where (x:xs) = reverse (t:rs)
+focusUp' n1 = n1
 
hunk ./XMonad/StackSet.hs 411
-focusUp', swapUp' :: Stack a -> Stack a
-focusUp' (Stack t (l:ls) rs) = Stack l ls (t:rs)
-focusUp' (Stack t []     rs) = Stack x xs [] where (x:xs) = reverse (t:rs)
 
hunk ./XMonad/StackSet.hs 412
-swapUp'  (Stack t (l:ls) rs) = Stack t ls (l:rs)
-swapUp'  (Stack t []     rs) = Stack t (reverse rs) []
+swapUp'  (Nest (l:ls) t rs) = Nest ls t (l:rs)
+swapUp'  (Nest []     t rs) = Nest (reverse rs) t []
+swapUp'  n1 = n1
 
hunk ./XMonad/StackSet.hs 416
--- | reverse a stack: up becomes down and down becomes up.
-reverseStack :: Stack a -> Stack a
-reverseStack (Stack t ls rs) = Stack t rs ls
+-- | reverse a nest: up becomes down and down becomes up.
+reverseNest :: Nest a -> Nest a
+reverseNest (Nest ls t rs) = Nest (map reverseNest rs) (reverseNest t) (map reverseNest ls)
+reverseNest n1 = n1
 
 --
 -- | /O(1) on current window, O(n) in general/. Focus the window 'w',
hunk ./XMonad/StackSet.hs 505
 -- However, we choose to insert above, and move the focus.
 --
 insertUp :: Eq a => a -> StackSet i l a s sd -> StackSet i l a s sd
-insertUp a s = if member a s then s else insert
-  where insert = modify (Just $ Stack a [] []) (\(Stack t l r) -> Just $ Stack a l (t:r)) s
+insertUp a s = if member a s then s else modify (Just $ N1 a) insert s
+  where insert (Nest l t r) = Just $ Nest l (N1 a) (t:r)
+        insert n1 = Just $ Nest [] (N1 a) [n1]
 
 -- insertDown :: a -> StackSet i l a s sd -> StackSet i l a s sd
 -- insertDown a = modify (Stack a [] []) $ \(Stack t l r) -> Stack a (t:l) r
hunk ./XMonad/StackSet.hs 537
 delete' w s = s { current = removeFromScreen        (current s)
                 , visible = map removeFromScreen    (visible s)
                 , hidden  = map removeFromWorkspace (hidden  s) }
-    where removeFromWorkspace ws = ws { stack = stack ws >>= filter (/=w) }
+    where removeFromWorkspace ws = ws { nest = nest ws >>= filter (/=w) }
           removeFromScreen scr   = scr { workspace = removeFromWorkspace (workspace scr) }
 
 ------------------------------------------------------------------------
hunk ./XMonad/StackSet.hs 558
 -- The old master window is swapped in the tiling order with the focused window.
 -- Focus stays with the item moved.
 swapMaster :: StackSet i l a s sd -> StackSet i l a s sd
-swapMaster = modify' $ \c -> case c of
-    Stack _ [] _  -> c    -- already master.
-    Stack t ls rs -> Stack t [] (xs ++ x : rs) where (x:xs) = reverse ls
+swapMaster = modify' sm
+    where sm (Nest [] t rs) = Nest [] (sm t) rs
+          sm (Nest ls t rs) = Nest [] (sm t) (xs ++ x : rs) where (x:xs) = reverse ls
+          sm n1 = n1
 
 -- natural! keep focus, move current to the top, move top to current.
 
hunk ./XMonad/StackSet.hs 567
 -- | /O(s)/. Set focus to the master window.
 focusMaster :: StackSet i l a s sd -> StackSet i l a s sd
-focusMaster = modify' $ \c -> case c of
-    Stack _ [] _  -> c
-    Stack t ls rs -> Stack x [] (xs ++ t : rs) where (x:xs) = reverse ls
+focusMaster = modify' fm
+    where fm (Nest ls t rs) = Nest [] (fm x) (xs ++ rs) where (x:xs) = reverse (t:ls)
+          fm n1 = n1
 
 --
 -- ---------------------------------------------------------------------
}

Context:

[Remove desktop manageHook rules in favor of ManageDocks
Spencer Janssen <sjanssen@cse.unl.edu>**20071222113735] 
[Wibble
Spencer Janssen <sjanssen@cse.unl.edu>**20071222041151] 
[Add support for several flags:
Spencer Janssen <sjanssen@cse.unl.edu>**20071222020520
  --version: print xmonad's version
  --recompile: recompile xmonad.hs if it is out of date
  --force-recompile: recompile xmonad.hs unconditionally
] 
[Remove getProgName capability from restart, we don't use it anymore
Spencer Janssen <sjanssen@cse.unl.edu>**20071219215011] 
[Flush pending X calls before restarting
Spencer Janssen <sjanssen@cse.unl.edu>**20071219162029] 
[Allow for sharing of home directory across architectures.
tim.thelion@gmail.com**20071218065146] 
[Call 'broadcastMessage ReleaseResources' in restart
Spencer Janssen <sjanssen@cse.unl.edu>**20071219065710] 
[Manpage now describes config in ~/.xmonad/xmonad.hs
Adam Vogt <vogt.adam@gmail.com>**20071219023918] 
[Update manpage to describe greedyView
Adam Vogt <vogt.adam@gmail.com>**20071219023726] 
[Depend on X11-1.4.1, it has crucial bugfixes
Spencer Janssen <sjanssen@cse.unl.edu>**20071215022100] 
[1.4.1 X11 dep
Don Stewart <dons@galois.com>**20071214160558] 
[Set withdrawnState after calling hide
Spencer Janssen <sjanssen@cse.unl.edu>**20071212060250] 
[Remove stale comment
Spencer Janssen <sjanssen@cse.unl.edu>**20071211084236] 
[Make windows responsible for setting withdrawn state
Spencer Janssen <sjanssen@cse.unl.edu>**20071211080117] 
[Remove stale comment
Spencer Janssen <sjanssen@cse.unl.edu>**20071211075641] 
[Clean up stale mapped/waitingUnmap state in handle rather than unmanage.
Spencer Janssen <sjanssen@cse.unl.edu>**20071211074810
 This is an attempt to fix issue #96.  Thanks to jcreigh for the insights
 necessary to fix the bug.
] 
[Delete windows from waitingUnmap that aren't waitng for any unmaps
Spencer Janssen <sjanssen@cse.unl.edu>**20071211074506] 
[man/xmonad.hs: add some documentation explaining that 'title' can be used in the manageHook just like 'resource' and 'className'.
Brent Yorgey <byorgey@gmail.com>**20071210173357] 
[normalize Module headers
Lukas Mai <l.mai@web.de>**20071210085327] 
[Add 'testing' mode, this should reduce 'darcs check' time significantly
Spencer Janssen <sjanssen@cse.unl.edu>**20071210004704] 
[Use XMonad meta-module in Main.hs
Spencer Janssen <sjanssen@cse.unl.edu>**20071210004456] 
[TAG 0.5
Spencer Janssen <sjanssen@cse.unl.edu>**20071209233044] 
Patch bundle hash:
ff948b212124cbf47f6916c5e127724599195ffa
