aboutsummaryrefslogtreecommitdiffstats
path: root/XMonad/Layout/Master.hs
blob: dfa1633852263e1dd4cb0755cbe17ebeca92f545 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, TypeSynonymInstances, FlexibleContexts, PatternGuards #-}

-----------------------------------------------------------------------------
-- |
-- Module      :  XMonad.Layout.Master
-- Copyright   :  (c) Ismael Carnales, Lukas Mai
-- License     :  BSD-style (see LICENSE)
--
-- Maintainer  :  Ismael Carnales <icarnales@gmail.com>
-- Stability   :  unstable
-- Portability :  unportable
--
-- Layout modfier that adds a master window to another layout.
-----------------------------------------------------------------------------

module XMonad.Layout.Master (
    -- * Usage
    -- $usage

    mastered
) where

import XMonad
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
--
-- Then edit your @layoutHook@ and add the Master modifier to the layout that
-- you prefer.
--
-- > mastered (1/100) (1/2) $ Grid
--
-- 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', '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)

-- | 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

instance LayoutModifier AddMaster Window where
    modifyLayout (AddMaster delta frac) = applyMaster delta frac
    modifierDescription _               = "Mastered"

    pureMess (AddMaster delta frac) m
        | Just Shrink <- fromMessage m = Just $ AddMaster delta (frac-delta)
        | Just Expand <- fromMessage m = Just $ AddMaster delta (frac+delta)

    pureMess _ _ = Nothing

-- | 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)

        else runLayout wksp rect