aboutsummaryrefslogtreecommitdiffstats
path: root/XMonad
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--XMonad/Layout/Master.hs124
1 files changed, 50 insertions, 74 deletions
diff --git a/XMonad/Layout/Master.hs b/XMonad/Layout/Master.hs
index 41bcc8b..dfa1633 100644
--- a/XMonad/Layout/Master.hs
+++ b/XMonad/Layout/Master.hs
@@ -1,110 +1,86 @@
-{-# LANGUAGE MultiParamTypeClasses, TypeSynonymInstances, FlexibleContexts #-}
-{-# LANGUAGE PatternGuards #-}
+{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, TypeSynonymInstances, FlexibleContexts, PatternGuards #-}
-----------------------------------------------------------------------------
-- |
-- Module : XMonad.Layout.Master
--- Copyright : (c) Lukas Mai
+-- Copyright : (c) Ismael Carnales, Lukas Mai
-- License : BSD-style (see LICENSE)
--
--- Maintainer : <l.mai@web.de>
+-- Maintainer : Ismael Carnales <icarnales@gmail.com>
-- Stability : unstable
-- Portability : unportable
--
--- A layout that adds a distinguished master window to a base layout.
+-- Layout modfier that adds a master window to another layout.
-----------------------------------------------------------------------------
module XMonad.Layout.Master (
-- * Usage
-- $usage
- mastered,
- Master
+
+ mastered
) where
import XMonad
-import XMonad.StackSet
-
-import Data.List
-import Data.Ord
+import qualified XMonad.StackSet as S
+import XMonad.Layout.LayoutModifier
-- $usage
-- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@:
--
-- > import XMonad.Layout.Master
--
--- and add something like
+-- Then edit your @layoutHook@ and add the Master modifier to the layout that
+-- you prefer.
--
-- > mastered (1/100) (1/2) $ Grid
--
--- to your layouts. This will use the left half of your screen for a master
--- window and let Grid manage the right half.
+-- This will use the left half of your screen for a master window and let
+-- Grid manage the right half.
--
-- For more detailed instructions on editing the layoutHook see
-- "XMonad.Doc.Extending#Editing_the_layout_hook".
--
--- Like 'XMonad.Layout.Tall', 'Master' supports the 'XMonad.Layout.Shrink' and
--- 'XMonad.Layout.Expand' messages.
+-- Like 'XMonad.Layout.Tall', 'withMaster' supports the
+-- 'XMonad.Layout.Shrink' and XMonad.Layout.Expand' messages.
+
+-- | Data type for LayoutModifier which converts given layout to a mastered
+-- layout
+data AddMaster a = AddMaster Rational Rational deriving (Show, Read)
-mastered :: (LayoutClass l a)
- => Rational -- ^ @delta@, the ratio of the screen to resize by
- -> Rational -- ^ @frac@, what portion of the screen to reserve for the master window
- -> l a -- ^ the layout to use for the remaining windows
- -> Master l a
-mastered d f b = Master d f' b
- where
- f' = min 1 . max 0 $ f
+-- | Modifier wich converts given layout to a mastered one
+mastered :: (LayoutClass l a) =>
+ 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
+mastered delta frac = ModifiedLayout $ AddMaster delta frac
-data Master l a =
- Master{
- delta :: Rational,
- frac :: Rational,
- base :: l a
- } deriving (Show, Read, Eq, Ord)
+instance LayoutModifier AddMaster Window where
+ modifyLayout (AddMaster delta frac) = applyMaster delta frac
+ modifierDescription _ = "Mastered"
-extractMaster :: Stack a -> (a, Maybe (Stack a))
-extractMaster (Stack x ls rs) = case reverse ls of
- [] -> (x, differentiate rs)
- (m : ls') -> (m, Just $ Stack x (reverse ls') rs)
+ pureMess (AddMaster delta frac) m
+ | Just Shrink <- fromMessage m = Just $ AddMaster delta (frac-delta)
+ | Just Expand <- fromMessage m = Just $ AddMaster delta (frac+delta)
-area :: Rectangle -> Dimension
-area r = rect_width r * rect_height r
+ pureMess _ _ = Nothing
-chop :: D -> Rectangle -> Rectangle
-chop (w, h) (Rectangle rx ry rw rh) =
- let
- r' = maximumBy (comparing area)
- [ Rectangle rx (ry + fromIntegral h) rw (rh - h)
- , Rectangle (rx + fromIntegral w) ry (rw - w) rh]
- in
- r'{ rect_width = max 0 $ rect_width r', rect_height = max 0 $ rect_height r' }
+-- | Internal function for adding a master window and let the modified
+-- layout handle the rest of the windows
+applyMaster :: (LayoutClass l Window) =>
+ Rational
+ -> Rational
+ -> S.Workspace WorkspaceId (l Window) Window
+ -> Rectangle
+ -> X ([(Window, Rectangle)], Maybe (l Window))
+applyMaster _ frac wksp rect = do
+ let st= S.stack wksp
+ let ws = S.integrate' $ st
+ if length ws > 2 then do
+ let m = head ws
+ let (mr, sr) = splitHorizontallyBy frac rect
+ let nst = st>>= S.filter (m/=)
+ wrs <- runLayout (wksp {S.stack = nst}) sr
+ return ((m, mr) : fst wrs, snd wrs)
-instance (LayoutClass l Window) => LayoutClass (Master l) Window where
- description m = "Master " ++ description (base m)
- handleMessage m msg
- | Just Shrink <- fromMessage msg =
- return . Just $ m{ frac = max 0 $ frac m - delta m }
- | Just Expand <- fromMessage msg =
- return . Just $ m{ frac = min 1 $ frac m + delta m }
- | otherwise =
- fmap (fmap (\x -> m{ base = x })) $ handleMessage (base m) msg
- runLayout ws rect = do
- (f, ws', rect') <- case fmap extractMaster $ stack ws of
- Nothing ->
- return (id, ws, rect)
- Just (x, Nothing) -> do
- f <- mkAdjust x
- let
- (w', h') = f (rect_width rect, rect_height rect)
- xr = rect{ rect_width = w', rect_height = h' }
- return (((x, xr) :), ws{ stack = Nothing }, Rectangle (rect_x xr + fromIntegral w') (rect_y xr) 0 0)
- Just (x, Just st) -> do
- f <- mkAdjust x
- let
- d@(w', h') = f (scale $ rect_width rect, rect_height rect)
- xr = rect{ rect_width = w', rect_height = h' }
- return (((x, xr) :), ws{ stack = Just st }, chop d rect)
- (y, l) <- runLayout ws'{ layout = base m } rect'
- return (f y, fmap (\x -> m{ base = x }) l)
- where
- m = layout ws
- scale = round . (* frac m) . fromIntegral
+ else runLayout wksp rect