    {-# LANGUAGE DeriveDataTypeable, FlexibleInstances, MultiParamTypeClasses #-}

    ----------------------------------------------------------------------
    -- |
    -- Module      : XMonad.Layout.GridVariants
    -- Copyright   : (c) Norbert Zeh
    -- License     : BSD-style (see LICENSE)
    --
    -- Maintainer  : nzeh@cs.dal.ca
    -- Stability   : unstable
    -- Portability : unportable
    --
    -- Two layouts: one is a variant of the Grid layout that allows the
    -- desired aspect ratio of windows to be specified.  The other is like
    -- Tall but places a grid with fixed number of rows and columns in the
    -- master area and uses an aspect-ratio-specified layout for the
    -- slaves.
    ----------------------------------------------------------------------

    module XMonad.Layout.GridVariants ( -- * Usage
                                        -- $usage
                                        ChangeMasterGridGeom(..)
                                      , ChangeGridGeom(..)
                                      , Grid(..)
                                      , TallGrid(..)
                                      , SplitGrid(..)
                                      , Orientation(..)
                                      ) where

    import Control.Monad
    import XMonad
    import qualified XMonad.StackSet as W

    -- $usage
    -- This module can be used as follows:
    --
    -- > import XMonad.Layout.GridVariants
    --
    -- Then add something like this to your layouts:
    --
    -- > Grid (16/10)
    --
    -- for a 16:10 aspect ratio grid, or
    --
    -- > SplitGrid L 2 3 (2/3) (16/10) (5/100)
    --
    -- for a layout with a 2x3 master grid that uses 2/3 of the screen,
    -- and a 16:10 aspect ratio slave grid to its right.  The last
    -- parameter is again the percentage by which the split between master
    -- and slave area changes in response to Expand/Shrink messages.
    --
    -- To be able to change the geometry of the master grid, add something
    -- like this to your keybindings:
    --
    -- > ((modm .|. shiftMask, xK_equal), sendMessage $ IncMasterCols 1),
    -- > ((modm .|. shiftMask, xK_minus), sendMessage $ IncMasterCols (-1)),
    -- > ((modm .|. controlMask,  xK_equal), sendMessage $ IncMasterRows 1),
    -- > ((modm .|. controlMask,  xK_minus), sendMessage $ IncMasterRows (-1))

    -- | Grid layout.  The parameter is the desired x:y aspect ratio of windows
    data Grid a = Grid !Rational
                  deriving (ReadPrec [Grid a]
    ReadPrec (Grid a)
    Int -> ReadS (Grid a)
    ReadS [Grid a]
    (Int -> ReadS (Grid a))
    -> ReadS [Grid a]
    -> ReadPrec (Grid a)
    -> ReadPrec [Grid a]
    -> Read (Grid a)
    forall a. ReadPrec [Grid a]
    forall a. ReadPrec (Grid a)
    forall a. Int -> ReadS (Grid a)
    forall a. ReadS [Grid a]
    forall a.
    (Int -> ReadS a)
    -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
    readListPrec :: ReadPrec [Grid a]
    $creadListPrec :: forall a. ReadPrec [Grid a]
    readPrec :: ReadPrec (Grid a)
    $creadPrec :: forall a. ReadPrec (Grid a)
    readList :: ReadS [Grid a]
    $creadList :: forall a. ReadS [Grid a]
    readsPrec :: Int -> ReadS (Grid a)
    $creadsPrec :: forall a. Int -> ReadS (Grid a)
    Read, Int -> Grid a -> ShowS
    [Grid a] -> ShowS
    Grid a -> String
    (Int -> Grid a -> ShowS)
    -> (Grid a -> String) -> ([Grid a] -> ShowS) -> Show (Grid a)
    forall a. Int -> Grid a -> ShowS
    forall a. [Grid a] -> ShowS
    forall a. Grid a -> String
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    showList :: [Grid a] -> ShowS
    $cshowList :: forall a. [Grid a] -> ShowS
    show :: Grid a -> String
    $cshow :: forall a. Grid a -> String
    showsPrec :: Int -> Grid a -> ShowS
    $cshowsPrec :: forall a. Int -> Grid a -> ShowS
    Show)

    instance LayoutClass Grid a where

        pureLayout :: Grid a -> Rectangle -> Stack a -> [(a, Rectangle)]
    pureLayout (Grid aspect :: Rational
    aspect) rect :: Rectangle
    rect st :: Stack a
    st = [a] -> [Rectangle] -> [(a, Rectangle)]
    forall a b. [a] -> [b] -> [(a, b)]
    zip [a]
    wins [Rectangle]
    rects
            where
              wins :: [a]
    wins  = Stack a -> [a]
    forall a. Stack a -> [a]
    W.integrate Stack a
    st
              nwins :: Int
    nwins = [a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [a]
    wins
              rects :: [Rectangle]
    rects = Rectangle -> Int -> Rational -> [Rectangle]
    arrangeAspectGrid Rectangle
    rect Int
    nwins Rational
    aspect

        pureMessage :: Grid a -> SomeMessage -> Maybe (Grid a)
    pureMessage layout :: Grid a
    layout msg :: SomeMessage
    msg = (ChangeGridGeom -> Grid a)
    -> Maybe ChangeGridGeom -> Maybe (Grid a)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (Grid a -> ChangeGridGeom -> Grid a
    forall a. Grid a -> ChangeGridGeom -> Grid a
    changeGridAspect Grid a
    layout) (SomeMessage -> Maybe ChangeGridGeom
    forall m. Message m => SomeMessage -> Maybe m
    fromMessage SomeMessage
    msg)

        description :: Grid a -> String
    description _ = "Grid"

    changeGridAspect :: Grid a -> ChangeGridGeom -> Grid a
    changeGridAspect :: Grid a -> ChangeGridGeom -> Grid a
    changeGridAspect (Grid _) (SetGridAspect aspect :: Rational
    aspect) = Rational -> Grid a
    forall a. Rational -> Grid a
    Grid Rational
    aspect
    changeGridAspect (Grid aspect :: Rational
    aspect) (ChangeGridAspect delta :: Rational
    delta) =
        Rational -> Grid a
    forall a. Rational -> Grid a
    Grid (Rational -> Rational -> Rational
    forall a. Ord a => a -> a -> a
    max 0.00001 (Rational
    aspect Rational -> Rational -> Rational
    forall a. Num a => a -> a -> a
    + Rational
    delta))

    -- |Geometry change messages understood by Grid and SplitGrid
    data ChangeGridGeom
        = SetGridAspect !Rational
        | ChangeGridAspect !Rational
          deriving Typeable

    instance Message ChangeGridGeom

    -- |SplitGrid layout.  Parameters are
    --
    --   - side where the master is
    --   - number of master rows
    --   - number of master columns
    --   - portion of screen used for master grid
    --   - x:y aspect ratio of slave windows
    --   - increment for resize messages
    data SplitGrid a = SplitGrid Orientation !Int !Int !Rational !Rational !Rational
                       deriving (ReadPrec [SplitGrid a]
    ReadPrec (SplitGrid a)
    Int -> ReadS (SplitGrid a)
    ReadS [SplitGrid a]
    (Int -> ReadS (SplitGrid a))
    -> ReadS [SplitGrid a]
    -> ReadPrec (SplitGrid a)
    -> ReadPrec [SplitGrid a]
    -> Read (SplitGrid a)
    forall a. ReadPrec [SplitGrid a]
    forall a. ReadPrec (SplitGrid a)
    forall a. Int -> ReadS (SplitGrid a)
    forall a. ReadS [SplitGrid a]
    forall a.
    (Int -> ReadS a)
    -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
    readListPrec :: ReadPrec [SplitGrid a]
    $creadListPrec :: forall a. ReadPrec [SplitGrid a]
    readPrec :: ReadPrec (SplitGrid a)
    $creadPrec :: forall a. ReadPrec (SplitGrid a)
    readList :: ReadS [SplitGrid a]
    $creadList :: forall a. ReadS [SplitGrid a]
    readsPrec :: Int -> ReadS (SplitGrid a)
    $creadsPrec :: forall a. Int -> ReadS (SplitGrid a)
    Read, Int -> SplitGrid a -> ShowS
    [SplitGrid a] -> ShowS
    SplitGrid a -> String
    (Int -> SplitGrid a -> ShowS)
    -> (SplitGrid a -> String)
    -> ([SplitGrid a] -> ShowS)
    -> Show (SplitGrid a)
    forall a. Int -> SplitGrid a -> ShowS
    forall a. [SplitGrid a] -> ShowS
    forall a. SplitGrid a -> String
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    showList :: [SplitGrid a] -> ShowS
    $cshowList :: forall a. [SplitGrid a] -> ShowS
    show :: SplitGrid a -> String
    $cshow :: forall a. SplitGrid a -> String
    showsPrec :: Int -> SplitGrid a -> ShowS
    $cshowsPrec :: forall a. Int -> SplitGrid a -> ShowS
    Show)

    -- |Type to specify the side of the screen that holds
    --  the master area of a SplitGrid.
    data Orientation = T | B | L | R
                       deriving (Orientation -> Orientation -> Bool
    (Orientation -> Orientation -> Bool)
    -> (Orientation -> Orientation -> Bool) -> Eq Orientation
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    /= :: Orientation -> Orientation -> Bool
    $c/= :: Orientation -> Orientation -> Bool
    == :: Orientation -> Orientation -> Bool
    $c== :: Orientation -> Orientation -> Bool
    Eq, ReadPrec [Orientation]
    ReadPrec Orientation
    Int -> ReadS Orientation
    ReadS [Orientation]
    (Int -> ReadS Orientation)
    -> ReadS [Orientation]
    -> ReadPrec Orientation
    -> ReadPrec [Orientation]
    -> Read Orientation
    forall a.
    (Int -> ReadS a)
    -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
    readListPrec :: ReadPrec [Orientation]
    $creadListPrec :: ReadPrec [Orientation]
    readPrec :: ReadPrec Orientation
    $creadPrec :: ReadPrec Orientation
    readList :: ReadS [Orientation]
    $creadList :: ReadS [Orientation]
    readsPrec :: Int -> ReadS Orientation
    $creadsPrec :: Int -> ReadS Orientation
    Read, Int -> Orientation -> ShowS
    [Orientation] -> ShowS
    Orientation -> String
    (Int -> Orientation -> ShowS)
    -> (Orientation -> String)
    -> ([Orientation] -> ShowS)
    -> Show Orientation
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    showList :: [Orientation] -> ShowS
    $cshowList :: [Orientation] -> ShowS
    show :: Orientation -> String
    $cshow :: Orientation -> String
    showsPrec :: Int -> Orientation -> ShowS
    $cshowsPrec :: Int -> Orientation -> ShowS
    Show)

    instance LayoutClass SplitGrid a where

        pureLayout :: SplitGrid a -> Rectangle -> Stack a -> [(a, Rectangle)]
    pureLayout (SplitGrid o :: Orientation
    o mrows :: Int
    mrows mcols :: Int
    mcols mfrac :: Rational
    mfrac saspect :: Rational
    saspect _) rect :: Rectangle
    rect st :: Stack a
    st = [a] -> [Rectangle] -> [(a, Rectangle)]
    forall a b. [a] -> [b] -> [(a, b)]
    zip [a]
    wins [Rectangle]
    rects
            where
              wins :: [a]
    wins  = Stack a -> [a]
    forall a. Stack a -> [a]
    W.integrate Stack a
    st
              nwins :: Int
    nwins = [a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [a]
    wins
              rects :: [Rectangle]
    rects = Rectangle
    -> Orientation
    -> Int
    -> Int
    -> Int
    -> Rational
    -> Rational
    -> [Rectangle]
    arrangeSplitGrid Rectangle
    rect Orientation
    o Int
    nwins Int
    mrows Int
    mcols Rational
    mfrac Rational
    saspect

        pureMessage :: SplitGrid a -> SomeMessage -> Maybe (SplitGrid a)
    pureMessage layout :: SplitGrid a
    layout msg :: SomeMessage
    msg =
            [Maybe (SplitGrid a)] -> Maybe (SplitGrid a)
    forall (t :: * -> *) (m :: * -> *) a.
    (Foldable t, MonadPlus m) =>
    t (m a) -> m a
    msum [ (Resize -> SplitGrid a) -> Maybe Resize -> Maybe (SplitGrid a)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (SplitGrid a -> Resize -> SplitGrid a
    forall a. SplitGrid a -> Resize -> SplitGrid a
    resizeMaster SplitGrid a
    layout)          (SomeMessage -> Maybe Resize
    forall m. Message m => SomeMessage -> Maybe m
    fromMessage SomeMessage
    msg)
                 , (ChangeMasterGridGeom -> SplitGrid a)
    -> Maybe ChangeMasterGridGeom -> Maybe (SplitGrid a)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (SplitGrid a -> ChangeMasterGridGeom -> SplitGrid a
    forall a. SplitGrid a -> ChangeMasterGridGeom -> SplitGrid a
    changeMasterGrid SplitGrid a
    layout)      (SomeMessage -> Maybe ChangeMasterGridGeom
    forall m. Message m => SomeMessage -> Maybe m
    fromMessage SomeMessage
    msg)
                 , (ChangeGridGeom -> SplitGrid a)
    -> Maybe ChangeGridGeom -> Maybe (SplitGrid a)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (SplitGrid a -> ChangeGridGeom -> SplitGrid a
    forall a. SplitGrid a -> ChangeGridGeom -> SplitGrid a
    changeSlaveGridAspect SplitGrid a
    layout) (SomeMessage -> Maybe ChangeGridGeom
    forall m. Message m => SomeMessage -> Maybe m
    fromMessage SomeMessage
    msg)
                 ]

        description :: SplitGrid a -> String
    description _ = "SplitGrid"

    -- |The geometry change message understood by the master grid
    data ChangeMasterGridGeom
        = IncMasterRows     !Int      -- ^Change the number of master rows
        | IncMasterCols     !Int      -- ^Change the number of master columns
        | SetMasterRows     !Int      -- ^Set the number of master rows to absolute value
        | SetMasterCols     !Int      -- ^Set the number of master columns to absolute value
        | SetMasterFraction !Rational -- ^Set the fraction of the screen used by the master grid
        deriving Typeable

    instance Message ChangeMasterGridGeom

    arrangeSplitGrid :: Rectangle -> Orientation -> Int -> Int -> Int -> Rational -> Rational -> [Rectangle]
    arrangeSplitGrid :: Rectangle
    -> Orientation
    -> Int
    -> Int
    -> Int
    -> Rational
    -> Rational
    -> [Rectangle]
    arrangeSplitGrid rect :: Rectangle
    rect@(Rectangle rx :: Position
    rx ry :: Position
    ry rw :: Dimension
    rw rh :: Dimension
    rh) o :: Orientation
    o nwins :: Int
    nwins mrows :: Int
    mrows mcols :: Int
    mcols mfrac :: Rational
    mfrac saspect :: Rational
    saspect
        | Int
    nwins Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Int
    mwins = Rectangle -> Int -> Int -> [Rectangle]
    arrangeMasterGrid Rectangle
    rect Int
    nwins Int
    mcols
        | Int
    mwins Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == 0     = Rectangle -> Int -> Rational -> [Rectangle]
    arrangeAspectGrid Rectangle
    rect Int
    nwins Rational
    saspect
        | Bool
    otherwise      = (Rectangle -> Int -> Int -> [Rectangle]
    arrangeMasterGrid Rectangle
    mrect Int
    mwins Int
    mcols) [Rectangle] -> [Rectangle] -> [Rectangle]
    forall a. [a] -> [a] -> [a]
    ++
                           (Rectangle -> Int -> Rational -> [Rectangle]
    arrangeAspectGrid Rectangle
    srect Int
    swins Rational
    saspect)
        where
          mwins :: Int
    mwins            = Int
    mrows Int -> Int -> Int
    forall a. Num a => a -> a -> a
    * Int
    mcols
          swins :: Int
    swins            = Int
    nwins Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    mwins
          mrect :: Rectangle
    mrect            = Position -> Position -> Dimension -> Dimension -> Rectangle
    Rectangle Position
    mx Position
    my Dimension
    mw Dimension
    mh
          srect :: Rectangle
    srect            = Position -> Position -> Dimension -> Dimension -> Rectangle
    Rectangle Position
    sx Position
    sy Dimension
    sw Dimension
    sh
          (mh :: Dimension
    mh, sh :: Dimension
    sh, mw :: Dimension
    mw, sw :: Dimension
    sw) = if Orientation
    o Orientation -> [Orientation] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` [Orientation
    T, Orientation
    B] then
                                 (Rational -> Dimension
    forall a b. (RealFrac a, Integral b) => a -> b
    ceiling (Dimension -> Rational
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Dimension
    rh Rational -> Rational -> Rational
    forall a. Num a => a -> a -> a
    * Rational
    mfrac), Dimension
    rh Dimension -> Dimension -> Dimension
    forall a. Num a => a -> a -> a
    - Dimension
    mh, Dimension
    rw, Dimension
    rw)
                             else
                                 (Dimension
    rh, Dimension
    rh, Rational -> Dimension
    forall a b. (RealFrac a, Integral b) => a -> b
    ceiling (Dimension -> Rational
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Dimension
    rw Rational -> Rational -> Rational
    forall a. Num a => a -> a -> a
    * Rational
    mfrac), Dimension
    rw Dimension -> Dimension -> Dimension
    forall a. Num a => a -> a -> a
    - Dimension
    mw)
          mx :: Position
    mx               = Position -> Position
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Position
    rx Position -> Position -> Position
    forall a. Num a => a -> a -> a
    + if Orientation
    o Orientation -> Orientation -> Bool
    forall a. Eq a => a -> a -> Bool
    == Orientation
    R then Dimension -> Position
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Dimension
    sw else 0
          my :: Position
    my               = Position -> Position
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Position
    ry Position -> Position -> Position
    forall a. Num a => a -> a -> a
    + if Orientation
    o Orientation -> Orientation -> Bool
    forall a. Eq a => a -> a -> Bool
    == Orientation
    B then Dimension -> Position
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Dimension
    sh else 0
          sx :: Position
    sx               = Position -> Position
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Position
    rx Position -> Position -> Position
    forall a. Num a => a -> a -> a
    + if Orientation
    o Orientation -> Orientation -> Bool
    forall a. Eq a => a -> a -> Bool
    == Orientation
    L then Dimension -> Position
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Dimension
    mw else 0
          sy :: Position
    sy               = Position -> Position
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Position
    ry Position -> Position -> Position
    forall a. Num a => a -> a -> a
    + if Orientation
    o Orientation -> Orientation -> Bool
    forall a. Eq a => a -> a -> Bool
    == Orientation
    T then Dimension -> Position
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Dimension
    mh else 0

    arrangeMasterGrid :: Rectangle -> Int -> Int -> [Rectangle]
    arrangeMasterGrid :: Rectangle -> Int -> Int -> [Rectangle]
    arrangeMasterGrid rect :: Rectangle
    rect nwins :: Int
    nwins mcols :: Int
    mcols = Rectangle -> Int -> Int -> [Rectangle]
    arrangeGrid Rectangle
    rect Int
    nwins (Int -> Int -> Int
    forall a. Ord a => a -> a -> a
    min Int
    nwins Int
    mcols)

    arrangeAspectGrid :: Rectangle -> Int -> Rational -> [Rectangle]
    arrangeAspectGrid :: Rectangle -> Int -> Rational -> [Rectangle]
    arrangeAspectGrid rect :: Rectangle
    rect@(Rectangle _ _ rw :: Dimension
    rw rh :: Dimension
    rh) nwins :: Int
    nwins aspect :: Rational
    aspect =
        Rectangle -> Int -> Int -> [Rectangle]
    arrangeGrid Rectangle
    rect Int
    nwins (Int -> Int -> Int
    forall a. Ord a => a -> a -> a
    min Int
    nwins Int
    ncols)
        where
          scr_a :: Rational
    scr_a = Dimension -> Rational
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Dimension
    rw Rational -> Rational -> Rational
    forall a. Fractional a => a -> a -> a
    / Dimension -> Rational
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Dimension
    rh
          fcols :: Double
    fcols = Double -> Double
    forall a. Floating a => a -> a
    sqrt ( Rational -> Double
    forall a. Fractional a => Rational -> a
    fromRational (Rational -> Double) -> Rational -> Double
    forall a b. (a -> b) -> a -> b
    $ Rational
    scr_a Rational -> Rational -> Rational
    forall a. Num a => a -> a -> a
    * Int -> Rational
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    nwins Rational -> Rational -> Rational
    forall a. Fractional a => a -> a -> a
    / Rational
    aspect ) :: Double
          cols1 :: Int
    cols1 = Double -> Int
    forall a b. (RealFrac a, Integral b) => a -> b
    floor Double
    fcols :: Int
          cols2 :: Int
    cols2 = Double -> Int
    forall a b. (RealFrac a, Integral b) => a -> b
    ceiling Double
    fcols :: Int
          rows1 :: Int
    rows1 = Rational -> Int
    forall a b. (RealFrac a, Integral b) => a -> b
    ceiling ( Int -> Rational
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    nwins Rational -> Rational -> Rational
    forall a. Fractional a => a -> a -> a
    / Int -> Rational
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    cols1 :: Rational ) :: Int
          rows2 :: Int
    rows2 = Rational -> Int
    forall a b. (RealFrac a, Integral b) => a -> b
    floor ( Int -> Rational
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    nwins Rational -> Rational -> Rational
    forall a. Fractional a => a -> a -> a
    / Int -> Rational
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    cols2 :: Rational ) :: Int
          a1 :: Rational
    a1    = Rational
    scr_a Rational -> Rational -> Rational
    forall a. Num a => a -> a -> a
    * Int -> Rational
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    rows1 Rational -> Rational -> Rational
    forall a. Fractional a => a -> a -> a
    / Int -> Rational
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    cols1
          a2 :: Rational
    a2    = Rational
    scr_a Rational -> Rational -> Rational
    forall a. Num a => a -> a -> a
    * Int -> Rational
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    rows2 Rational -> Rational -> Rational
    forall a. Fractional a => a -> a -> a
    / Int -> Rational
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    cols2
          ncols :: Int
    ncols | Int
    cols1 Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == 0                = Int
    cols2
                | Int
    rows2 Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == 0                = Int
    cols1
                | Rational
    a1 Rational -> Rational -> Rational
    forall a. Fractional a => a -> a -> a
    / Rational
    aspect Rational -> Rational -> Bool
    forall a. Ord a => a -> a -> Bool
    < Rational
    aspect Rational -> Rational -> Rational
    forall a. Fractional a => a -> a -> a
    / Rational
    a2 = Int
    cols1
                | Bool
    otherwise                 = Int
    cols2

    arrangeGrid :: Rectangle -> Int -> Int -> [Rectangle]
    arrangeGrid :: Rectangle -> Int -> Int -> [Rectangle]
    arrangeGrid (Rectangle rx :: Position
    rx ry :: Position
    ry rw :: Dimension
    rw rh :: Dimension
    rh) nwins :: Int
    nwins ncols :: Int
    ncols =
        [Position -> Position -> Dimension -> Dimension -> Rectangle
    Rectangle (Int -> Position
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    x Position -> Position -> Position
    forall a. Num a => a -> a -> a
    + Position
    rx) (Int -> Position
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    y Position -> Position -> Position
    forall a. Num a => a -> a -> a
    + Position
    ry) (Int -> Dimension
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    w) (Int -> Dimension
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    h)
         | (x :: Int
    x, y :: Int
    y, w :: Int
    w, h :: Int
    h) <- [(Int, Int, Int, Int)]
    rects]
        where
          nrows_in_cols :: [Int]
    nrows_in_cols = [Int] -> [Int]
    listDifference ([Int] -> [Int]) -> [Int] -> [Int]
    forall a b. (a -> b) -> a -> b
    $ Int -> Int -> [Int]
    splitEvenly Int
    nwins Int
    ncols
          x_slabs :: [(Int, Int)]
    x_slabs       = Int -> Int -> [(Int, Int)]
    splitIntoSlabs (Dimension -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Dimension
    rw) Int
    ncols
          y_slabs :: [[(Int, Int)]]
    y_slabs       = [Int -> Int -> [(Int, Int)]
    splitIntoSlabs (Dimension -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Dimension
    rh) Int
    nrows | Int
    nrows <- [Int]
    nrows_in_cols]
          rects_in_cols :: [[(Int, Int, Int, Int)]]
    rects_in_cols = [[(Int
    x, Int
    y, Int
    w, Int
    h) | (y :: Int
    y, h :: Int
    h) <- [(Int, Int)]
    lst]
                           | ((x :: Int
    x, w :: Int
    w), lst :: [(Int, Int)]
    lst) <- [(Int, Int)] -> [[(Int, Int)]] -> [((Int, Int), [(Int, Int)])]
    forall a b. [a] -> [b] -> [(a, b)]
    zip [(Int, Int)]
    x_slabs [[(Int, Int)]]
    y_slabs]
          rects :: [(Int, Int, Int, Int)]
    rects         = ([(Int, Int, Int, Int)]
     -> [(Int, Int, Int, Int)] -> [(Int, Int, Int, Int)])
    -> [(Int, Int, Int, Int)]
    -> [[(Int, Int, Int, Int)]]
    -> [(Int, Int, Int, Int)]
    forall (t :: * -> *) a b.
    Foldable t =>
    (a -> b -> b) -> b -> t a -> b
    foldr [(Int, Int, Int, Int)]
    -> [(Int, Int, Int, Int)] -> [(Int, Int, Int, Int)]
    forall a. [a] -> [a] -> [a]
    (++) [] [[(Int, Int, Int, Int)]]
    rects_in_cols

    splitIntoSlabs :: Int -> Int -> [(Int, Int)]
    splitIntoSlabs :: Int -> Int -> [(Int, Int)]
    splitIntoSlabs width :: Int
    width nslabs :: Int
    nslabs = [Int] -> [Int] -> [(Int, Int)]
    forall a b. [a] -> [b] -> [(a, b)]
    zip (0Int -> [Int] -> [Int]
    forall a. a -> [a] -> [a]
    :[Int]
    xs) [Int]
    widths
        where
          xs :: [Int]
    xs = Int -> Int -> [Int]
    splitEvenly Int
    width Int
    nslabs
          widths :: [Int]
    widths = [Int] -> [Int]
    listDifference [Int]
    xs

    listDifference :: [Int] -> [Int]
    listDifference :: [Int] -> [Int]
    listDifference lst :: [Int]
    lst = [Int
    curInt -> Int -> Int
    forall a. Num a => a -> a -> a
    -Int
    pre | (cur :: Int
    cur,pre :: Int
    pre) <- [Int] -> [Int] -> [(Int, Int)]
    forall a b. [a] -> [b] -> [(a, b)]
    zip [Int]
    lst (0Int -> [Int] -> [Int]
    forall a. a -> [a] -> [a]
    :[Int]
    lst)]

    splitEvenly :: Int -> Int -> [Int]
    splitEvenly :: Int -> Int -> [Int]
    splitEvenly n :: Int
    n parts :: Int
    parts = [ Int
    szInt -> Int -> Int
    forall a. Num a => a -> a -> a
    -Int
    off | (sz :: Int
    sz,off :: Int
    off) <- [Int] -> [Int] -> [(Int, Int)]
    forall a b. [a] -> [b] -> [(a, b)]
    zip [Int]
    sizes [Int]
    offsets]
        where
          size :: Int
    size    = Double -> Int
    forall a b. (RealFrac a, Integral b) => a -> b
    ceiling ( (Int -> Double
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    n Double -> Double -> Double
    forall a. Fractional a => a -> a -> a
    / Int -> Double
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    parts) :: Double )
          extra :: Int
    extra   = Int
    sizeInt -> Int -> Int
    forall a. Num a => a -> a -> a
    *Int
    parts Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    n
          sizes :: [Int]
    sizes   = [Int
    iInt -> Int -> Int
    forall a. Num a => a -> a -> a
    *Int
    size | Int
    i <- [1..Int
    parts]]
          offsets :: [Int]
    offsets = (Int -> [Int] -> [Int]
    forall a. Int -> [a] -> [a]
    take (Int -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    extra) [1..]) [Int] -> [Int] -> [Int]
    forall a. [a] -> [a] -> [a]
    ++ [Int
    extra,Int
    extra..]

    resizeMaster :: SplitGrid a -> Resize -> SplitGrid a
    resizeMaster :: SplitGrid a -> Resize -> SplitGrid a
    resizeMaster (SplitGrid o :: Orientation
    o mrows :: Int
    mrows mcols :: Int
    mcols mfrac :: Rational
    mfrac saspect :: Rational
    saspect delta :: Rational
    delta) Shrink =
        Orientation
    -> Int -> Int -> Rational -> Rational -> Rational -> SplitGrid a
    forall a.
    Orientation
    -> Int -> Int -> Rational -> Rational -> Rational -> SplitGrid a
    SplitGrid Orientation
    o Int
    mrows Int
    mcols (Rational -> Rational -> Rational
    forall a. Ord a => a -> a -> a
    max 0 (Rational
    mfrac Rational -> Rational -> Rational
    forall a. Num a => a -> a -> a
    - Rational
    delta)) Rational
    saspect Rational
    delta
    resizeMaster (SplitGrid o :: Orientation
    o mrows :: Int
    mrows mcols :: Int
    mcols mfrac :: Rational
    mfrac saspect :: Rational
    saspect delta :: Rational
    delta) Expand =
        Orientation
    -> Int -> Int -> Rational -> Rational -> Rational -> SplitGrid a
    forall a.
    Orientation
    -> Int -> Int -> Rational -> Rational -> Rational -> SplitGrid a
    SplitGrid Orientation
    o Int
    mrows Int
    mcols (Rational -> Rational -> Rational
    forall a. Ord a => a -> a -> a
    min 1 (Rational
    mfrac Rational -> Rational -> Rational
    forall a. Num a => a -> a -> a
    + Rational
    delta)) Rational
    saspect Rational
    delta

    changeMasterGrid :: SplitGrid a -> ChangeMasterGridGeom -> SplitGrid a
    changeMasterGrid :: SplitGrid a -> ChangeMasterGridGeom -> SplitGrid a
    changeMasterGrid (SplitGrid o :: Orientation
    o mrows :: Int
    mrows mcols :: Int
    mcols mfrac :: Rational
    mfrac saspect :: Rational
    saspect delta :: Rational
    delta) (IncMasterRows d :: Int
    d) =
        Orientation
    -> Int -> Int -> Rational -> Rational -> Rational -> SplitGrid a
    forall a.
    Orientation
    -> Int -> Int -> Rational -> Rational -> Rational -> SplitGrid a
    SplitGrid Orientation
    o (Int -> Int -> Int
    forall a. Ord a => a -> a -> a
    max 0 (Int
    mrows Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    d)) Int
    mcols Rational
    mfrac Rational
    saspect Rational
    delta
    changeMasterGrid (SplitGrid o :: Orientation
    o mrows :: Int
    mrows mcols :: Int
    mcols mfrac :: Rational
    mfrac saspect :: Rational
    saspect delta :: Rational
    delta) (IncMasterCols d :: Int
    d) =
        Orientation
    -> Int -> Int -> Rational -> Rational -> Rational -> SplitGrid a
    forall a.
    Orientation
    -> Int -> Int -> Rational -> Rational -> Rational -> SplitGrid a
    SplitGrid Orientation
    o Int
    mrows (Int -> Int -> Int
    forall a. Ord a => a -> a -> a
    max 0 (Int
    mcols Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    d)) Rational
    mfrac Rational
    saspect Rational
    delta
    changeMasterGrid (SplitGrid o :: Orientation
    o _ mcols :: Int
    mcols mfrac :: Rational
    mfrac saspect :: Rational
    saspect delta :: Rational
    delta) (SetMasterRows mrows :: Int
    mrows) =
        Orientation
    -> Int -> Int -> Rational -> Rational -> Rational -> SplitGrid a
    forall a.
    Orientation
    -> Int -> Int -> Rational -> Rational -> Rational -> SplitGrid a
    SplitGrid Orientation
    o (Int -> Int -> Int
    forall a. Ord a => a -> a -> a
    max 0 Int
    mrows) Int
    mcols Rational
    mfrac Rational
    saspect Rational
    delta
    changeMasterGrid (SplitGrid o :: Orientation
    o mrows :: Int
    mrows _ mfrac :: Rational
    mfrac saspect :: Rational
    saspect delta :: Rational
    delta) (SetMasterCols mcols :: Int
    mcols) =
        Orientation
    -> Int -> Int -> Rational -> Rational -> Rational -> SplitGrid a
    forall a.
    Orientation
    -> Int -> Int -> Rational -> Rational -> Rational -> SplitGrid a
    SplitGrid Orientation
    o Int
    mrows (Int -> Int -> Int
    forall a. Ord a => a -> a -> a
    max 0 Int
    mcols) Rational
    mfrac Rational
    saspect Rational
    delta
    changeMasterGrid (SplitGrid o :: Orientation
    o mrows :: Int
    mrows mcols :: Int
    mcols _ saspect :: Rational
    saspect delta :: Rational
    delta) (SetMasterFraction mfrac :: Rational
    mfrac) =
        Orientation
    -> Int -> Int -> Rational -> Rational -> Rational -> SplitGrid a
    forall a.
    Orientation
    -> Int -> Int -> Rational -> Rational -> Rational -> SplitGrid a
    SplitGrid Orientation
    o Int
    mrows Int
    mcols Rational
    mfrac Rational
    saspect Rational
    delta

    changeSlaveGridAspect :: SplitGrid a -> ChangeGridGeom -> SplitGrid a
    changeSlaveGridAspect :: SplitGrid a -> ChangeGridGeom -> SplitGrid a
    changeSlaveGridAspect (SplitGrid o :: Orientation
    o mrows :: Int
    mrows mcols :: Int
    mcols mfrac :: Rational
    mfrac _ delta :: Rational
    delta) (SetGridAspect saspect :: Rational
    saspect) =
        Orientation
    -> Int -> Int -> Rational -> Rational -> Rational -> SplitGrid a
    forall a.
    Orientation
    -> Int -> Int -> Rational -> Rational -> Rational -> SplitGrid a
    SplitGrid Orientation
    o Int
    mrows Int
    mcols Rational
    mfrac Rational
    saspect Rational
    delta
    changeSlaveGridAspect (SplitGrid o :: Orientation
    o mrows :: Int
    mrows mcols :: Int
    mcols mfrac :: Rational
    mfrac saspect :: Rational
    saspect delta :: Rational
    delta) (ChangeGridAspect sdelta :: Rational
    sdelta) =
        Orientation
    -> Int -> Int -> Rational -> Rational -> Rational -> SplitGrid a
    forall a.
    Orientation
    -> Int -> Int -> Rational -> Rational -> Rational -> SplitGrid a
    SplitGrid Orientation
    o Int
    mrows Int
    mcols Rational
    mfrac (Rational -> Rational -> Rational
    forall a. Ord a => a -> a -> a
    max 0.00001 (Rational
    saspect Rational -> Rational -> Rational
    forall a. Num a => a -> a -> a
    + Rational
    sdelta)) Rational
    delta

    -- | TallGrid layout.  Parameters are
    --
    --   - number of master rows
    --   - number of master columns
    --   - portion of screen used for master grid
    --   - x:y aspect ratio of slave windows
    --   - increment for resize messages
    --
    --   This exists mostly because it was introduced in an earlier version.
    --   It's a fairly thin wrapper around "SplitGrid L".
    data TallGrid a = TallGrid !Int !Int !Rational !Rational !Rational
                      deriving (ReadPrec [TallGrid a]
    ReadPrec (TallGrid a)
    Int -> ReadS (TallGrid a)
    ReadS [TallGrid a]
    (Int -> ReadS (TallGrid a))
    -> ReadS [TallGrid a]
    -> ReadPrec (TallGrid a)
    -> ReadPrec [TallGrid a]
    -> Read (TallGrid a)
    forall a. ReadPrec [TallGrid a]
    forall a. ReadPrec (TallGrid a)
    forall a. Int -> ReadS (TallGrid a)
    forall a. ReadS [TallGrid a]
    forall a.
    (Int -> ReadS a)
    -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
    readListPrec :: ReadPrec [TallGrid a]
    $creadListPrec :: forall a. ReadPrec [TallGrid a]
    readPrec :: ReadPrec (TallGrid a)
    $creadPrec :: forall a. ReadPrec (TallGrid a)
    readList :: ReadS [TallGrid a]
    $creadList :: forall a. ReadS [TallGrid a]
    readsPrec :: Int -> ReadS (TallGrid a)
    $creadsPrec :: forall a. Int -> ReadS (TallGrid a)
    Read, Int -> TallGrid a -> ShowS
    [TallGrid a] -> ShowS
    TallGrid a -> String
    (Int -> TallGrid a -> ShowS)
    -> (TallGrid a -> String)
    -> ([TallGrid a] -> ShowS)
    -> Show (TallGrid a)
    forall a. Int -> TallGrid a -> ShowS
    forall a. [TallGrid a] -> ShowS
    forall a. TallGrid a -> String
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    showList :: [TallGrid a] -> ShowS
    $cshowList :: forall a. [TallGrid a] -> ShowS
    show :: TallGrid a -> String
    $cshow :: forall a. TallGrid a -> String
    showsPrec :: Int -> TallGrid a -> ShowS
    $cshowsPrec :: forall a. Int -> TallGrid a -> ShowS
    Show)

    instance LayoutClass TallGrid a where

        pureLayout :: TallGrid a -> Rectangle -> Stack a -> [(a, Rectangle)]
    pureLayout (TallGrid mrows :: Int
    mrows mcols :: Int
    mcols mfrac :: Rational
    mfrac saspect :: Rational
    saspect _) rect :: Rectangle
    rect st :: Stack a
    st = [a] -> [Rectangle] -> [(a, Rectangle)]
    forall a b. [a] -> [b] -> [(a, b)]
    zip [a]
    wins [Rectangle]
    rects
            where
              wins :: [a]
    wins  = Stack a -> [a]
    forall a. Stack a -> [a]
    W.integrate Stack a
    st
              nwins :: Int
    nwins = [a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [a]
    wins
              rects :: [Rectangle]
    rects = Rectangle
    -> Orientation
    -> Int
    -> Int
    -> Int
    -> Rational
    -> Rational
    -> [Rectangle]
    arrangeSplitGrid Rectangle
    rect Orientation
    L Int
    nwins Int
    mrows Int
    mcols Rational
    mfrac Rational
    saspect

        pureMessage :: TallGrid a -> SomeMessage -> Maybe (TallGrid a)
    pureMessage layout :: TallGrid a
    layout msg :: SomeMessage
    msg =
            [Maybe (TallGrid a)] -> Maybe (TallGrid a)
    forall (t :: * -> *) (m :: * -> *) a.
    (Foldable t, MonadPlus m) =>
    t (m a) -> m a
    msum [ (Resize -> TallGrid a) -> Maybe Resize -> Maybe (TallGrid a)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (((SplitGrid a -> Resize -> SplitGrid a)
    -> TallGrid a -> Resize -> TallGrid a
    forall a b.
    (SplitGrid a -> b -> SplitGrid a) -> TallGrid a -> b -> TallGrid a
    tallGridAdapter SplitGrid a -> Resize -> SplitGrid a
    forall a. SplitGrid a -> Resize -> SplitGrid a
    resizeMaster) TallGrid a
    layout) (SomeMessage -> Maybe Resize
    forall m. Message m => SomeMessage -> Maybe m
    fromMessage SomeMessage
    msg)
                 , (ChangeMasterGridGeom -> TallGrid a)
    -> Maybe ChangeMasterGridGeom -> Maybe (TallGrid a)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (((SplitGrid a -> ChangeMasterGridGeom -> SplitGrid a)
    -> TallGrid a -> ChangeMasterGridGeom -> TallGrid a
    forall a b.
    (SplitGrid a -> b -> SplitGrid a) -> TallGrid a -> b -> TallGrid a
    tallGridAdapter SplitGrid a -> ChangeMasterGridGeom -> SplitGrid a
    forall a. SplitGrid a -> ChangeMasterGridGeom -> SplitGrid a
    changeMasterGrid) TallGrid a
    layout) (SomeMessage -> Maybe ChangeMasterGridGeom
    forall m. Message m => SomeMessage -> Maybe m
    fromMessage SomeMessage
    msg) ]

        description :: TallGrid a -> String
    description _ = "TallGrid"

    tallGridAdapter :: (SplitGrid a -> b -> SplitGrid a) -> TallGrid a -> b -> TallGrid a
    tallGridAdapter :: (SplitGrid a -> b -> SplitGrid a) -> TallGrid a -> b -> TallGrid a
    tallGridAdapter f :: SplitGrid a -> b -> SplitGrid a
    f (TallGrid mrows :: Int
    mrows mcols :: Int
    mcols mfrac :: Rational
    mfrac saspect :: Rational
    saspect delta :: Rational
    delta) msg :: b
    msg =
        Int -> Int -> Rational -> Rational -> Rational -> TallGrid a
    forall a.
    Int -> Int -> Rational -> Rational -> Rational -> TallGrid a
    TallGrid Int
    mrows' Int
    mcols' Rational
    mfrac' Rational
    saspect' Rational
    delta'
        where
          SplitGrid _ mrows' :: Int
    mrows' mcols' :: Int
    mcols' mfrac' :: Rational
    mfrac' saspect' :: Rational
    saspect' delta' :: Rational
    delta' =
              SplitGrid a -> b -> SplitGrid a
    f (Orientation
    -> Int -> Int -> Rational -> Rational -> Rational -> SplitGrid a
    forall a.
    Orientation
    -> Int -> Int -> Rational -> Rational -> Rational -> SplitGrid a
    SplitGrid Orientation
    L Int
    mrows Int
    mcols Rational
    mfrac Rational
    saspect Rational
    delta) b
    msg