    {-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-}

    -----------------------------------------------------------------------------
    -- |
    -- Module      :  XMonad.Layout.Square
    -- Copyright   :  (c) David Roundy <droundy@darcs.net>
    -- License     :  BSD3-style (see LICENSE)
    --
    -- Maintainer  :  none
    -- Stability   :  unstable
    -- Portability :  unportable
    --
    -- A layout that splits the screen into a square area and the rest of the
    -- screen.
    -- This is probably only ever useful in combination with
    -- "XMonad.Layout.Combo".
    -- It sticks one window in a square region, and makes the rest
    -- of the windows live with what's left (in a full-screen sense).
    --
    -----------------------------------------------------------------------------

    module XMonad.Layout.Square (
                                 -- * Usage
                                 -- $usage
                                 Square(..) ) where

    import XMonad
    import XMonad.StackSet ( integrate )

    -- $usage
    -- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@ file:
    --
    -- >   import XMonad.Layout.Square
    --
    -- An example layout using square together with "XMonad.Layout.Combo"
    -- to make the very last area square:
    --
    -- > , combo (combo (mirror $ twoPane 0.03 0.85),1)] (twoPane 0.03 0.5) )
    -- >                [(twoPane 0.03 0.2,1),(combo [(twoPane 0.03 0.8,1),(square,1)]
    -- >         [(tabbed,3),(tabbed,30),(tabbed,1),(tabbed,1)]

    -- For detailed instructions on editing your key bindings, see
    -- "XMonad.Doc.Extending#Editing_key_bindings".

    data Square a = Square deriving ( ReadPrec [Square a]
    ReadPrec (Square a)
    Int -> ReadS (Square a)
    ReadS [Square a]
    (Int -> ReadS (Square a))
    -> ReadS [Square a]
    -> ReadPrec (Square a)
    -> ReadPrec [Square a]
    -> Read (Square a)
    forall a. ReadPrec [Square a]
    forall a. ReadPrec (Square a)
    forall a. Int -> ReadS (Square a)
    forall a. ReadS [Square a]
    forall a.
    (Int -> ReadS a)
    -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
    readListPrec :: ReadPrec [Square a]
    $creadListPrec :: forall a. ReadPrec [Square a]
    readPrec :: ReadPrec (Square a)
    $creadPrec :: forall a. ReadPrec (Square a)
    readList :: ReadS [Square a]
    $creadList :: forall a. ReadS [Square a]
    readsPrec :: Int -> ReadS (Square a)
    $creadsPrec :: forall a. Int -> ReadS (Square a)
    Read, Int -> Square a -> ShowS
    [Square a] -> ShowS
    Square a -> String
    (Int -> Square a -> ShowS)
    -> (Square a -> String) -> ([Square a] -> ShowS) -> Show (Square a)
    forall a. Int -> Square a -> ShowS
    forall a. [Square a] -> ShowS
    forall a. Square a -> String
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    showList :: [Square a] -> ShowS
    $cshowList :: forall a. [Square a] -> ShowS
    show :: Square a -> String
    $cshow :: forall a. Square a -> String
    showsPrec :: Int -> Square a -> ShowS
    $cshowsPrec :: forall a. Int -> Square a -> ShowS
    Show )

    instance LayoutClass Square a where
        pureLayout :: Square a -> Rectangle -> Stack a -> [(a, Rectangle)]
    pureLayout Square r :: Rectangle
    r s :: Stack a
    s = [a] -> [(a, Rectangle)]
    forall a. [a] -> [(a, Rectangle)]
    arrange (Stack a -> [a]
    forall a. Stack a -> [a]
    integrate Stack a
    s)
            where arrange :: [a] -> [(a, Rectangle)]
    arrange ws :: [a]
    ws@(_:_) = (a -> (a, Rectangle)) -> [a] -> [(a, Rectangle)]
    forall a b. (a -> b) -> [a] -> [b]
    map (\w :: a
    w->(a
    w,Rectangle
    rest)) ([a] -> [a]
    forall a. [a] -> [a]
    init [a]
    ws) [(a, Rectangle)] -> [(a, Rectangle)] -> [(a, Rectangle)]
    forall a. [a] -> [a] -> [a]
    ++ [([a] -> a
    forall a. [a] -> a
    last [a]
    ws,Rectangle
    sq)]
                  arrange [] = [] -- actually, this is an impossible case
                  (rest :: Rectangle
    rest, sq :: Rectangle
    sq) = Rectangle -> (Rectangle, Rectangle)
    splitSquare Rectangle
    r

    splitSquare :: Rectangle -> (Rectangle, Rectangle)
    splitSquare :: Rectangle -> (Rectangle, Rectangle)
    splitSquare (Rectangle x :: Position
    x y :: Position
    y w :: Dimension
    w h :: Dimension
    h)
        | Dimension
    w Dimension -> Dimension -> Bool
    forall a. Ord a => a -> a -> Bool
    > Dimension
    h = (Position -> Position -> Dimension -> Dimension -> Rectangle
    Rectangle Position
    x Position
    y (Dimension
    w Dimension -> Dimension -> Dimension
    forall a. Num a => a -> a -> a
    - Dimension
    h) Dimension
    h, Position -> Position -> Dimension -> Dimension -> Rectangle
    Rectangle (Position
    xPosition -> Position -> Position
    forall a. Num a => a -> a -> a
    +Dimension -> Position
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Dimension
    wDimension -> Dimension -> Dimension
    forall a. Num a => a -> a -> a
    -Dimension
    h)) Position
    y Dimension
    h Dimension
    h)
        | Bool
    otherwise = (Position -> Position -> Dimension -> Dimension -> Rectangle
    Rectangle Position
    x Position
    y Dimension
    w (Dimension
    hDimension -> Dimension -> Dimension
    forall a. Num a => a -> a -> a
    -Dimension
    w), Position -> Position -> Dimension -> Dimension -> Rectangle
    Rectangle Position
    x (Position
    yPosition -> Position -> Position
    forall a. Num a => a -> a -> a
    +Dimension -> Position
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Dimension
    hDimension -> Dimension -> Dimension
    forall a. Num a => a -> a -> a
    -Dimension
    w)) Dimension
    w Dimension
    w)