This patch adds support for multiple master windows to X.L.Master

This commit is contained in:
quesel
2010-05-18 06:05:57 +00:00
parent adbb52d4f2
commit 5fb228cfac

View File

@@ -17,7 +17,8 @@ module XMonad.Layout.Master (
-- * Usage -- * Usage
-- $usage -- $usage
mastered mastered,
multimastered
) where ) where
import XMonad import XMonad
@@ -34,6 +35,10 @@ import XMonad.Layout.LayoutModifier
-- --
-- > mastered (1/100) (1/2) $ Grid -- > mastered (1/100) (1/2) $ Grid
-- --
-- Or if you want multiple (here two) master windows from the beginning:
--
-- > multimastered 2 (1/100) (1/2) $ Grid
--
-- This will use the left half of your screen for a master window and let -- This will use the left half of your screen for a master window and let
-- Grid manage the right half. -- Grid manage the right half.
-- --
@@ -45,42 +50,68 @@ import XMonad.Layout.LayoutModifier
-- | Data type for LayoutModifier which converts given layout to a mastered -- | Data type for LayoutModifier which converts given layout to a mastered
-- layout -- layout
data AddMaster a = AddMaster Rational Rational deriving (Show, Read) data AddMaster a = AddMaster Int Rational Rational deriving (Show, Read)
-- | Modifier which converts given layout to a mastered one -- | Modifier which converts given layout to a mastered one
multimastered :: (LayoutClass l a) =>
Int -- ^ @k@, number of master windows
-> Rational -- ^ @delta@, the ratio of the screen to resize by
-> Rational -- ^ @frac@, what portion of the screen to use for the master window
-> l a -- ^ the layout to be modified
-> ModifiedLayout AddMaster l a
multimastered k delta frac = ModifiedLayout $ AddMaster k delta frac
mastered :: (LayoutClass l a) => mastered :: (LayoutClass l a) =>
Rational -- ^ @delta@, the ratio of the screen to resize by Rational -- ^ @delta@, the ratio of the screen to resize by
-> Rational -- ^ @frac@, what portion of the screen to use for the master window -> Rational -- ^ @frac@, what portion of the screen to use for the master window
-> l a -- ^ the layout to be modified -> l a -- ^ the layout to be modified
-> ModifiedLayout AddMaster l a -> ModifiedLayout AddMaster l a
mastered delta frac = ModifiedLayout $ AddMaster delta frac mastered delta frac = multimastered 1 delta frac
instance LayoutModifier AddMaster Window where instance LayoutModifier AddMaster Window where
modifyLayout (AddMaster delta frac) = applyMaster delta frac modifyLayout (AddMaster k delta frac) = applyMaster k delta frac
modifierDescription _ = "Mastered" modifierDescription _ = "Mastered"
pureMess (AddMaster delta frac) m pureMess (AddMaster k delta frac) m
| Just Shrink <- fromMessage m = Just $ AddMaster delta (frac-delta) | Just Shrink <- fromMessage m = Just $ AddMaster k delta (frac-delta)
| Just Expand <- fromMessage m = Just $ AddMaster delta (frac+delta) | Just Expand <- fromMessage m = Just $ AddMaster k delta (frac+delta)
| Just (IncMasterN d) <- fromMessage m = Just $ AddMaster (max 1 (k+d)) delta frac
pureMess _ _ = Nothing pureMess _ _ = Nothing
-- | Internal function for adding a master window and let the modified -- | Internal function for adding a master window and let the modified
-- layout handle the rest of the windows -- layout handle the rest of the windows
applyMaster :: (LayoutClass l Window) => applyMaster :: (LayoutClass l Window) =>
Rational Int
-> Rational
-> Rational -> Rational
-> S.Workspace WorkspaceId (l Window) Window -> S.Workspace WorkspaceId (l Window) Window
-> Rectangle -> Rectangle
-> X ([(Window, Rectangle)], Maybe (l Window)) -> X ([(Window, Rectangle)], Maybe (l Window))
applyMaster _ frac wksp rect = do applyMaster k _ frac wksp rect = do
let st= S.stack wksp let st= S.stack wksp
let ws = S.integrate' $ st let ws = S.integrate' $ st
if length ws > 1 then do let n = length ws
let m = head ws if n > 1 then do
let (mr, sr) = splitHorizontallyBy frac rect if(n<=k) then
let nst = st>>= S.filter (m/=) return ((divideCol rect ws), Nothing)
wrs <- runLayout (wksp {S.stack = nst}) sr else do
return ((m, mr) : fst wrs, snd wrs) let m = take k ws
let (mr, sr) = splitHorizontallyBy frac rect
let nst = st>>= S.filter (\w -> not (w `elem` m))
wrs <- runLayout (wksp {S.stack = nst}) sr
return ((divideCol mr m) ++ (fst wrs), snd wrs)
else runLayout wksp rect else runLayout wksp rect
-- | Shift rectangle down
shiftD :: Position -> Rectangle -> Rectangle
shiftD s (Rectangle x y w h) = Rectangle x (y+s) w h
-- | Divide rectangle between windows
divideCol :: Rectangle -> [a] -> [(a, Rectangle)]
divideCol (Rectangle x y w h) ws = zip ws rects
where n = length ws
oneH = fromIntegral h `div` n
oneRect = Rectangle x y w (fromIntegral oneH)
rects = take n $ iterate (shiftD (fromIntegral oneH)) oneRect