    {-# LANGUAGE TypeSynonymInstances, MultiParamTypeClasses, TupleSections #-}

    -----------------------------------------------------------------------------
    -- |
    -- Module      :  XMonad.Layout.HintedGrid
    -- Description :  A layout that puts all windows in a square grid while obeying their size hints.
    -- Copyright   :  (c) Lukas Mai
    -- License     :  BSD-style (see LICENSE)
    --
    -- Maintainer  :  <l.mai@web.de>
    -- Stability   :  unstable
    -- Portability :  unportable
    --
    -- A not so simple layout that attempts to put all windows in a square grid
    -- while obeying their size hints.
    --
    -----------------------------------------------------------------------------

    module XMonad.Layout.HintedGrid (
        -- * Usage
        -- $usage
        Grid(..), arrange, defaultRatio
    ) where

    import Prelude hiding ((.))

    import XMonad
    import XMonad.Prelude (replicateM, sortBy, sortOn)
    import XMonad.StackSet

    import Control.Monad.State (runState)
    import Data.Ord

    infixr 9 .
    (.) :: (Functor f) => (a -> b) -> f a -> f b
    . :: forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    (.) = (a -> b) -> f a -> f b
    forall a b. (a -> b) -> f a -> f b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap

    -- $usage
    -- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@:
    --
    -- > import XMonad.Layout.HintedGrid
    --
    -- Then edit your @layoutHook@ by adding the 'Grid' layout:
    --
    -- > myLayout = Grid False ||| Full ||| etc..
    -- > main = xmonad def { layoutHook = myLayout }
    --
    -- You can also specify an aspect ratio for Grid to strive for with the
    -- GridRatio constructor:
    --
    -- > myLayout = GridRatio (4/3) False ||| etc.
    --
    -- For more detailed instructions on editing the layoutHook see
    -- "XMonad.Doc.Extending#Editing_the_layout_hook".

    -- | Automatic mirroring of hinted layouts doesn't work very well, so this
    -- 'Grid' comes with built-in mirroring. @Grid False@ is the normal layout,
    -- @Grid True@ is the mirrored variant (rotated by 90 degrees).
    data Grid a = Grid Bool | GridRatio Double Bool 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
    $creadsPrec :: forall a. Int -> ReadS (Grid a)
    readsPrec :: Int -> ReadS (Grid a)
    $creadList :: forall a. ReadS [Grid a]
    readList :: ReadS [Grid a]
    $creadPrec :: forall a. ReadPrec (Grid a)
    readPrec :: ReadPrec (Grid a)
    $creadListPrec :: forall a. ReadPrec [Grid a]
    readListPrec :: ReadPrec [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
    $cshowsPrec :: forall a. Int -> Grid a -> ShowS
    showsPrec :: Int -> Grid a -> ShowS
    $cshow :: forall a. Grid a -> String
    show :: Grid a -> String
    $cshowList :: forall a. [Grid a] -> ShowS
    showList :: [Grid a] -> ShowS
    Show)

    defaultRatio :: Double
    defaultRatio :: Double
    defaultRatio = Double
    16Double -> Double -> Double
    forall a. Fractional a => a -> a -> a
    /Double
    9

    instance LayoutClass Grid Window where
        doLayout :: Grid Window
    -> Rectangle
    -> Stack Window
    -> X ([(Window, Rectangle)], Maybe (Grid Window))
    doLayout (Grid Bool
    m)        Rectangle
    r Stack Window
    w = Grid Window
    -> Rectangle
    -> Stack Window
    -> X ([(Window, Rectangle)], Maybe (Grid Window))
    forall (layout :: * -> *) a.
    LayoutClass layout a =>
    layout a
    -> Rectangle -> Stack a -> X ([(a, Rectangle)], Maybe (layout a))
    doLayout (Double -> Bool -> Grid Window
    forall a. Double -> Bool -> Grid a
    GridRatio Double
    defaultRatio Bool
    m) Rectangle
    r Stack Window
    w
        doLayout (GridRatio Double
    d Bool
    m) Rectangle
    r Stack Window
    w = (, Maybe (Grid Window)
    forall a. Maybe a
    Nothing) ([(Window, Rectangle)]
     -> ([(Window, Rectangle)], Maybe (Grid Window)))
    -> X [(Window, Rectangle)]
    -> X ([(Window, Rectangle)], Maybe (Grid Window))
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    . Double -> Bool -> Rectangle -> [Window] -> X [(Window, Rectangle)]
    arrange Double
    d Bool
    m Rectangle
    r (Stack Window -> [Window]
    forall a. Stack a -> [a]
    integrate Stack Window
    w)

    replicateS :: Int -> (a -> (b, a)) -> a -> ([b], a)
    replicateS :: forall a b. Int -> (a -> (b, a)) -> a -> ([b], a)
    replicateS Int
    n a -> (b, a)
    f = State a [b] -> a -> ([b], a)
    forall s a. State s a -> s -> (a, s)
    runState (State a [b] -> a -> ([b], a))
    -> (StateT a Identity b -> State a [b])
    -> StateT a Identity b
    -> a
    -> ([b], a)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    . Int -> StateT a Identity b -> State a [b]
    forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
    replicateM Int
    n (StateT a Identity b -> a -> ([b], a))
    -> StateT a Identity b -> a -> ([b], a)
    forall a b. (a -> b) -> a -> b
    $ do (b
    a,a
    s) <- (a -> (b, a)) -> StateT a Identity (b, a)
    forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
    gets a -> (b, a)
    f; a -> StateT a Identity ()
    forall s (m :: * -> *). MonadState s m => s -> m ()
    put a
    s; b -> StateT a Identity b
    forall a. a -> StateT a Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return b
    a

    doColumn :: Dimension -> Dimension -> Dimension -> [D -> D] -> [D]
    doColumn :: Dimension
    -> Dimension
    -> Dimension
    -> [(Dimension, Dimension) -> (Dimension, Dimension)]
    -> [(Dimension, Dimension)]
    doColumn Dimension
    width Dimension
    height Dimension
    k [(Dimension, Dimension) -> (Dimension, Dimension)]
    adjs =
        let
            ([Int]
    ind, [(Dimension, Dimension) -> (Dimension, Dimension)]
    fs) = [(Int, (Dimension, Dimension) -> (Dimension, Dimension))]
    -> ([Int], [(Dimension, Dimension) -> (Dimension, Dimension)])
    forall a b. [(a, b)] -> ([a], [b])
    unzip ([(Int, (Dimension, Dimension) -> (Dimension, Dimension))]
     -> ([Int], [(Dimension, Dimension) -> (Dimension, Dimension)]))
    -> ([(Dimension, Dimension) -> (Dimension, Dimension)]
        -> [(Int, (Dimension, Dimension) -> (Dimension, Dimension))])
    -> [(Dimension, Dimension) -> (Dimension, Dimension)]
    -> ([Int], [(Dimension, Dimension) -> (Dimension, Dimension)])
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    . ((Int, (Dimension, Dimension) -> (Dimension, Dimension))
     -> Dimension)
    -> [(Int, (Dimension, Dimension) -> (Dimension, Dimension))]
    -> [(Int, (Dimension, Dimension) -> (Dimension, Dimension))]
    forall b a. Ord b => (a -> b) -> [a] -> [a]
    sortOn ((Dimension, Dimension) -> Dimension
    forall a b. (a, b) -> b
    snd ((Dimension, Dimension) -> Dimension)
    -> ((Int, (Dimension, Dimension) -> (Dimension, Dimension))
        -> (Dimension, Dimension))
    -> (Int, (Dimension, Dimension) -> (Dimension, Dimension))
    -> Dimension
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    . (((Dimension, Dimension) -> (Dimension, Dimension))
    -> (Dimension, Dimension) -> (Dimension, Dimension)
    forall a b. (a -> b) -> a -> b
    $ (Dimension
    width, Dimension
    height)) (((Dimension, Dimension) -> (Dimension, Dimension))
     -> (Dimension, Dimension))
    -> ((Int, (Dimension, Dimension) -> (Dimension, Dimension))
        -> (Dimension, Dimension) -> (Dimension, Dimension))
    -> (Int, (Dimension, Dimension) -> (Dimension, Dimension))
    -> (Dimension, Dimension)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    . (Int, (Dimension, Dimension) -> (Dimension, Dimension))
    -> (Dimension, Dimension) -> (Dimension, Dimension)
    forall a b. (a, b) -> b
    snd) ([(Int, (Dimension, Dimension) -> (Dimension, Dimension))]
     -> [(Int, (Dimension, Dimension) -> (Dimension, Dimension))])
    -> ([(Dimension, Dimension) -> (Dimension, Dimension)]
        -> [(Int, (Dimension, Dimension) -> (Dimension, Dimension))])
    -> [(Dimension, Dimension) -> (Dimension, Dimension)]
    -> [(Int, (Dimension, Dimension) -> (Dimension, Dimension))]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    . [Int]
    -> [(Dimension, Dimension) -> (Dimension, Dimension)]
    -> [(Int, (Dimension, Dimension) -> (Dimension, Dimension))]
    forall a b. [a] -> [b] -> [(a, b)]
    zip [Int
    0 :: Int ..] ([(Dimension, Dimension) -> (Dimension, Dimension)]
     -> ([Int], [(Dimension, Dimension) -> (Dimension, Dimension)]))
    -> [(Dimension, Dimension) -> (Dimension, Dimension)]
    -> ([Int], [(Dimension, Dimension) -> (Dimension, Dimension)])
    forall a b. (a -> b) -> a -> b
    $ [(Dimension, Dimension) -> (Dimension, Dimension)]
    adjs
            (Dimension
    _, [(Dimension, Dimension)]
    ds) = Dimension
    -> Dimension
    -> [(Dimension, Dimension) -> (Dimension, Dimension)]
    -> (Dimension, [(Dimension, Dimension)])
    forall {t} {a}.
    Integral t =>
    t -> t -> [(Dimension, t) -> (a, t)] -> (t, [(a, t)])
    doC Dimension
    height Dimension
    k [(Dimension, Dimension) -> (Dimension, Dimension)]
    fs
        in
        ((Int, (Dimension, Dimension)) -> (Dimension, Dimension))
    -> [(Int, (Dimension, Dimension))] -> [(Dimension, Dimension)]
    forall a b. (a -> b) -> [a] -> [b]
    map (Int, (Dimension, Dimension)) -> (Dimension, Dimension)
    forall a b. (a, b) -> b
    snd ([(Int, (Dimension, Dimension))] -> [(Dimension, Dimension)])
    -> ([(Dimension, Dimension)] -> [(Int, (Dimension, Dimension))])
    -> [(Dimension, Dimension)]
    -> [(Dimension, Dimension)]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    . ((Int, (Dimension, Dimension))
     -> (Int, (Dimension, Dimension)) -> Ordering)
    -> [(Int, (Dimension, Dimension))]
    -> [(Int, (Dimension, Dimension))]
    forall a. (a -> a -> Ordering) -> [a] -> [a]
    sortBy (((Int, (Dimension, Dimension)) -> Int)
    -> (Int, (Dimension, Dimension))
    -> (Int, (Dimension, Dimension))
    -> Ordering
    forall a b. Ord a => (b -> a) -> b -> b -> Ordering
    comparing (Int, (Dimension, Dimension)) -> Int
    forall a b. (a, b) -> a
    fst) ([(Int, (Dimension, Dimension))]
     -> [(Int, (Dimension, Dimension))])
    -> ([(Dimension, Dimension)] -> [(Int, (Dimension, Dimension))])
    -> [(Dimension, Dimension)]
    -> [(Int, (Dimension, Dimension))]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    . [Int]
    -> [(Dimension, Dimension)] -> [(Int, (Dimension, Dimension))]
    forall a b. [a] -> [b] -> [(a, b)]
    zip [Int]
    ind ([(Dimension, Dimension)] -> [(Dimension, Dimension)])
    -> [(Dimension, Dimension)] -> [(Dimension, Dimension)]
    forall a b. (a -> b) -> a -> b
    $ [(Dimension, Dimension)]
    ds
        where
        doC :: t -> t -> [(Dimension, t) -> (a, t)] -> (t, [(a, t)])
    doC t
    h t
    _ [] = (t
    h, [])
        doC t
    h t
    n ((Dimension, t) -> (a, t)
    f : [(Dimension, t) -> (a, t)]
    fs) = ((a, t)
    adj (a, t) -> [(a, t)] -> [(a, t)]
    forall a. a -> [a] -> [a]
    :) ([(a, t)] -> [(a, t)]) -> (t, [(a, t)]) -> (t, [(a, t)])
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    . t -> t -> [(Dimension, t) -> (a, t)] -> (t, [(a, t)])
    doC (t
    h t -> t -> t
    forall a. Num a => a -> a -> a
    - t
    h') (t
    n t -> t -> t
    forall a. Num a => a -> a -> a
    - t
    1) [(Dimension, t) -> (a, t)]
    fs
            where
            adj :: (a, t)
    adj@(a
    _, t
    h') = (Dimension, t) -> (a, t)
    f (Dimension
    width, t
    h t -> t -> t
    forall a. Integral a => a -> a -> a
    `div` t
    n)

    doRect :: Dimension -> Dimension -> Dimension -> [[D -> D]] -> [Rectangle]
    doRect :: Dimension
    -> Dimension
    -> Dimension
    -> [[(Dimension, Dimension) -> (Dimension, Dimension)]]
    -> [Rectangle]
    doRect Dimension
    height = Dimension
    -> Dimension
    -> [[(Dimension, Dimension) -> (Dimension, Dimension)]]
    -> [Rectangle]
    doR
        where
        doR :: Dimension
    -> Dimension
    -> [[(Dimension, Dimension) -> (Dimension, Dimension)]]
    -> [Rectangle]
    doR Dimension
    _ Dimension
    _ [] = []
        doR Dimension
    width Dimension
    n ([(Dimension, Dimension) -> (Dimension, Dimension)]
    c : [[(Dimension, Dimension) -> (Dimension, Dimension)]]
    cs) =
            let
                v :: Dimension
    v = Int -> Dimension
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Int -> Dimension) -> Int -> Dimension
    forall a b. (a -> b) -> a -> b
    $ [(Dimension, Dimension) -> (Dimension, Dimension)] -> Int
    forall a. [a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [(Dimension, Dimension) -> (Dimension, Dimension)]
    c
                c' :: [(Dimension, Dimension)]
    c' = Dimension
    -> Dimension
    -> Dimension
    -> [(Dimension, Dimension) -> (Dimension, Dimension)]
    -> [(Dimension, Dimension)]
    doColumn (Dimension
    width Dimension -> Dimension -> Dimension
    forall a. Integral a => a -> a -> a
    `div` Dimension
    n) Dimension
    height Dimension
    v [(Dimension, Dimension) -> (Dimension, Dimension)]
    c
                ([Dimension]
    ws, [Dimension]
    hs) = [(Dimension, Dimension)] -> ([Dimension], [Dimension])
    forall a b. [(a, b)] -> ([a], [b])
    unzip [(Dimension, Dimension)]
    c'
                maxw :: Dimension
    maxw = [Dimension] -> Dimension
    forall a. Ord a => [a] -> a
    forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
    maximum [Dimension]
    ws
                height' :: Dimension
    height' = [Dimension] -> Dimension
    forall a. Num a => [a] -> a
    forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
    sum [Dimension]
    hs
                hbonus :: Dimension
    hbonus = Dimension
    height Dimension -> Dimension -> Dimension
    forall a. Num a => a -> a -> a
    - Dimension
    height'
                hsingle :: Dimension
    hsingle = Dimension
    hbonus Dimension -> Dimension -> Dimension
    forall a. Integral a => a -> a -> a
    `div` Dimension
    v
                hoffset :: Dimension
    hoffset = Dimension
    hsingle Dimension -> Dimension -> Dimension
    forall a. Integral a => a -> a -> a
    `div` Dimension
    2
                width' :: Dimension
    width' = Dimension
    width Dimension -> Dimension -> Dimension
    forall a. Num a => a -> a -> a
    - Dimension
    maxw
                ys :: [Dimension]
    ys = (Dimension -> Dimension) -> [Dimension] -> [Dimension]
    forall a b. (a -> b) -> [a] -> [b]
    map ((Dimension
    height Dimension -> Dimension -> Dimension
    forall a. Num a => a -> a -> a
    -) (Dimension -> Dimension)
    -> (Dimension -> Dimension) -> Dimension -> Dimension
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    . Dimension -> Dimension -> Dimension
    forall a. Num a => a -> a -> a
    subtract Dimension
    hoffset) ([Dimension] -> [Dimension])
    -> ([Dimension] -> [Dimension]) -> [Dimension] -> [Dimension]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    . (Dimension -> Dimension -> Dimension) -> [Dimension] -> [Dimension]
    forall a. (a -> a -> a) -> [a] -> [a]
    scanl1 Dimension -> Dimension -> Dimension
    forall a. Num a => a -> a -> a
    (+) ([Dimension] -> [Dimension])
    -> ([Dimension] -> [Dimension]) -> [Dimension] -> [Dimension]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    . (Dimension -> Dimension) -> [Dimension] -> [Dimension]
    forall a b. (a -> b) -> [a] -> [b]
    map (Dimension
    hsingle Dimension -> Dimension -> Dimension
    forall a. Num a => a -> a -> a
    +) ([Dimension] -> [Dimension]) -> [Dimension] -> [Dimension]
    forall a b. (a -> b) -> a -> b
    $ [Dimension]
    hs
                xs :: [Dimension]
    xs = (Dimension -> Dimension) -> [Dimension] -> [Dimension]
    forall a b. (a -> b) -> [a] -> [b]
    map ((Dimension
    width' Dimension -> Dimension -> Dimension
    forall a. Num a => a -> a -> a
    +) (Dimension -> Dimension)
    -> (Dimension -> Dimension) -> Dimension -> Dimension
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    . (Dimension -> Dimension -> Dimension
    forall a. Integral a => a -> a -> a
    `div` Dimension
    2) (Dimension -> Dimension)
    -> (Dimension -> Dimension) -> Dimension -> Dimension
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    . (Dimension
    maxw Dimension -> Dimension -> Dimension
    forall a. Num a => a -> a -> a
    -)) [Dimension]
    ws
            in
            (Dimension -> Dimension -> (Dimension, Dimension) -> Rectangle)
    -> [Dimension]
    -> [Dimension]
    -> [(Dimension, Dimension)]
    -> [Rectangle]
    forall a b c d. (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d]
    zipWith3 (\Dimension
    x Dimension
    y (Dimension
    w, Dimension
    h) -> Position -> Position -> Dimension -> Dimension -> Rectangle
    Rectangle (Dimension -> Position
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Dimension
    x) (Dimension -> Position
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Dimension
    y) Dimension
    w Dimension
    h) [Dimension]
    xs [Dimension]
    ys [(Dimension, Dimension)]
    c' [Rectangle] -> [Rectangle] -> [Rectangle]
    forall a. [a] -> [a] -> [a]
    ++ Dimension
    -> Dimension
    -> [[(Dimension, Dimension) -> (Dimension, Dimension)]]
    -> [Rectangle]
    doR Dimension
    width' (Dimension
    n Dimension -> Dimension -> Dimension
    forall a. Num a => a -> a -> a
    - Dimension
    1) [[(Dimension, Dimension) -> (Dimension, Dimension)]]
    cs

    -- | The internal function for computing the grid layout.
    arrange :: Double -> Bool -> Rectangle -> [Window] -> X [(Window, Rectangle)]
    arrange :: Double -> Bool -> Rectangle -> [Window] -> X [(Window, Rectangle)]
    arrange Double
    aspectRatio Bool
    mirror (Rectangle Position
    rx Position
    ry Dimension
    rw Dimension
    rh) [Window]
    wins = do
        [(Dimension, Dimension) -> (Dimension, Dimension)]
    proto <- (Window -> X ((Dimension, Dimension) -> (Dimension, Dimension)))
    -> [Window] -> X [(Dimension, Dimension) -> (Dimension, Dimension)]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
    mapM Window -> X ((Dimension, Dimension) -> (Dimension, Dimension))
    mkAdjust [Window]
    wins
        let
            adjs :: [(Dimension, Dimension) -> (Dimension, Dimension)]
    adjs = (((Dimension, Dimension) -> (Dimension, Dimension))
     -> (Dimension, Dimension) -> (Dimension, Dimension))
    -> [(Dimension, Dimension) -> (Dimension, Dimension)]
    -> [(Dimension, Dimension) -> (Dimension, Dimension)]
    forall a b. (a -> b) -> [a] -> [b]
    map (\(Dimension, Dimension) -> (Dimension, Dimension)
    f -> (Dimension, Dimension) -> (Dimension, Dimension)
    forall {a}. (a, a) -> (a, a)
    twist ((Dimension, Dimension) -> (Dimension, Dimension))
    -> ((Dimension, Dimension) -> (Dimension, Dimension))
    -> (Dimension, Dimension)
    -> (Dimension, Dimension)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    . (Dimension, Dimension) -> (Dimension, Dimension)
    f ((Dimension, Dimension) -> (Dimension, Dimension))
    -> ((Dimension, Dimension) -> (Dimension, Dimension))
    -> (Dimension, Dimension)
    -> (Dimension, Dimension)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    . (Dimension, Dimension) -> (Dimension, Dimension)
    forall {a}. (a, a) -> (a, a)
    twist) [(Dimension, Dimension) -> (Dimension, Dimension)]
    proto
            rs :: [Rectangle]
    rs = Double
    -> (Dimension, Dimension)
    -> [(Dimension, Dimension) -> (Dimension, Dimension)]
    -> [Rectangle]
    arrange' Double
    aspectRatio ((Dimension, Dimension) -> (Dimension, Dimension)
    forall {a}. (a, a) -> (a, a)
    twist (Dimension
    rw, Dimension
    rh)) [(Dimension, Dimension) -> (Dimension, Dimension)]
    adjs
            rs' :: [Rectangle]
    rs' = (Rectangle -> Rectangle) -> [Rectangle] -> [Rectangle]
    forall a b. (a -> b) -> [a] -> [b]
    map (\(Rectangle Position
    x Position
    y Dimension
    w Dimension
    h) -> (Dimension -> Dimension -> Rectangle)
    -> (Dimension, Dimension) -> Rectangle
    forall a b c. (a -> b -> c) -> (a, b) -> c
    uncurry ((Position -> Position -> Dimension -> Dimension -> Rectangle)
    -> (Position, Position) -> Dimension -> Dimension -> Rectangle
    forall a b c. (a -> b -> c) -> (a, b) -> c
    uncurry Position -> Position -> Dimension -> Dimension -> Rectangle
    Rectangle ((Position, Position) -> (Position, Position)
    forall {a}. (a, a) -> (a, a)
    twist (Position
    x, Position
    y))) ((Dimension, Dimension) -> (Dimension, Dimension)
    forall {a}. (a, a) -> (a, a)
    twist (Dimension
    w, Dimension
    h))) [Rectangle]
    rs
        [(Window, Rectangle)] -> X [(Window, Rectangle)]
    forall a. a -> X a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ([(Window, Rectangle)] -> X [(Window, Rectangle)])
    -> ([Rectangle] -> [(Window, Rectangle)])
    -> [Rectangle]
    -> X [(Window, Rectangle)]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    . [Window] -> [Rectangle] -> [(Window, Rectangle)]
    forall a b. [a] -> [b] -> [(a, b)]
    zip [Window]
    wins ([Rectangle] -> [(Window, Rectangle)])
    -> ([Rectangle] -> [Rectangle])
    -> [Rectangle]
    -> [(Window, Rectangle)]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    . (Rectangle -> Rectangle) -> [Rectangle] -> [Rectangle]
    forall a b. (a -> b) -> [a] -> [b]
    map (\Rectangle
    r -> Rectangle
    r{ rect_x :: Position
    rect_x = Rectangle -> Position
    rect_x Rectangle
    r Position -> Position -> Position
    forall a. Num a => a -> a -> a
    + Position
    rx, rect_y :: Position
    rect_y = Rectangle -> Position
    rect_y Rectangle
    r Position -> Position -> Position
    forall a. Num a => a -> a -> a
    + Position
    ry }) ([Rectangle] -> X [(Window, Rectangle)])
    -> [Rectangle] -> X [(Window, Rectangle)]
    forall a b. (a -> b) -> a -> b
    $ [Rectangle]
    rs'
        where
        twist :: (a, a) -> (a, a)
    twist
            | Bool
    mirror = \(a
    a, a
    b) -> (a
    b, a
    a)
            | Bool
    otherwise = (a, a) -> (a, a)
    forall a. a -> a
    id

    arrange' :: Double -> D -> [D -> D] -> [Rectangle]
    arrange' :: Double
    -> (Dimension, Dimension)
    -> [(Dimension, Dimension) -> (Dimension, Dimension)]
    -> [Rectangle]
    arrange' Double
    aspectRatio (Dimension
    rw, Dimension
    rh) [(Dimension, Dimension) -> (Dimension, Dimension)]
    adjs = [Rectangle] -> [Rectangle]
    forall a. [a] -> [a]
    reverse ([Rectangle] -> [Rectangle]) -> [Rectangle] -> [Rectangle]
    forall a b. (a -> b) -> a -> b
    $ Dimension
    -> Dimension
    -> Dimension
    -> [[(Dimension, Dimension) -> (Dimension, Dimension)]]
    -> [Rectangle]
    doRect Dimension
    rh Dimension
    rw (Int -> Dimension
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    ncolumns) ([[(Dimension, Dimension) -> (Dimension, Dimension)]]
    ecols [[(Dimension, Dimension) -> (Dimension, Dimension)]]
    -> [[(Dimension, Dimension) -> (Dimension, Dimension)]]
    -> [[(Dimension, Dimension) -> (Dimension, Dimension)]]
    forall a. [a] -> [a] -> [a]
    ++ [[(Dimension, Dimension) -> (Dimension, Dimension)]]
    cols)
        where
        nwindows :: Int
    nwindows = [(Dimension, Dimension) -> (Dimension, Dimension)] -> Int
    forall a. [a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [(Dimension, Dimension) -> (Dimension, Dimension)]
    adjs
        ncolumns :: Int
    ncolumns = Int -> Int -> Int
    forall a. Ord a => a -> a -> a
    max Int
    1 (Int -> Int) -> (Double -> Int) -> Double -> Int
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    . Double -> Int
    forall b. Integral b => Double -> b
    forall a b. (RealFrac a, Integral b) => a -> b
    round (Double -> Int) -> (Double -> Double) -> Double -> Int
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    . Double -> Double
    forall a. Floating a => a -> a
    sqrt (Double -> Int) -> Double -> Int
    forall a b. (a -> b) -> a -> b
    $ Int -> Double
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    nwindows Double -> Double -> Double
    forall a. Num a => a -> a -> a
    * Dimension -> Double
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Dimension
    rw Double -> Double -> Double
    forall a. Fractional a => a -> a -> a
    / (Dimension -> Double
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Dimension
    rh Double -> Double -> Double
    forall a. Num a => a -> a -> a
    * Double
    aspectRatio)
        nrows :: Int
    nrows = Int
    nwindows Int -> Int -> Int
    forall a. Integral a => a -> a -> a
    `div` Int
    ncolumns
        nextras :: Int
    nextras = Int
    nwindows Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    ncolumns Int -> Int -> Int
    forall a. Num a => a -> a -> a
    * Int
    nrows
        ([[(Dimension, Dimension) -> (Dimension, Dimension)]]
    ecols, [(Dimension, Dimension) -> (Dimension, Dimension)]
    adjs') = Int
    -> ([(Dimension, Dimension) -> (Dimension, Dimension)]
        -> ([(Dimension, Dimension) -> (Dimension, Dimension)],
            [(Dimension, Dimension) -> (Dimension, Dimension)]))
    -> [(Dimension, Dimension) -> (Dimension, Dimension)]
    -> ([[(Dimension, Dimension) -> (Dimension, Dimension)]],
        [(Dimension, Dimension) -> (Dimension, Dimension)])
    forall a b. Int -> (a -> (b, a)) -> a -> ([b], a)
    replicateS Int
    nextras (Int
    -> [(Dimension, Dimension) -> (Dimension, Dimension)]
    -> ([(Dimension, Dimension) -> (Dimension, Dimension)],
        [(Dimension, Dimension) -> (Dimension, Dimension)])
    forall a. Int -> [a] -> ([a], [a])
    splitAt (Int
    nrows Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    1)) ([(Dimension, Dimension) -> (Dimension, Dimension)]
     -> ([[(Dimension, Dimension) -> (Dimension, Dimension)]],
         [(Dimension, Dimension) -> (Dimension, Dimension)]))
    -> [(Dimension, Dimension) -> (Dimension, Dimension)]
    -> ([[(Dimension, Dimension) -> (Dimension, Dimension)]],
        [(Dimension, Dimension) -> (Dimension, Dimension)])
    forall a b. (a -> b) -> a -> b
    $ [(Dimension, Dimension) -> (Dimension, Dimension)]
    -> [(Dimension, Dimension) -> (Dimension, Dimension)]
    forall a. [a] -> [a]
    reverse [(Dimension, Dimension) -> (Dimension, Dimension)]
    adjs
        ([[(Dimension, Dimension) -> (Dimension, Dimension)]]
    cols, [(Dimension, Dimension) -> (Dimension, Dimension)]
    _) = Int
    -> ([(Dimension, Dimension) -> (Dimension, Dimension)]
        -> ([(Dimension, Dimension) -> (Dimension, Dimension)],
            [(Dimension, Dimension) -> (Dimension, Dimension)]))
    -> [(Dimension, Dimension) -> (Dimension, Dimension)]
    -> ([[(Dimension, Dimension) -> (Dimension, Dimension)]],
        [(Dimension, Dimension) -> (Dimension, Dimension)])
    forall a b. Int -> (a -> (b, a)) -> a -> ([b], a)
    replicateS (Int
    ncolumns Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    nextras) (Int
    -> [(Dimension, Dimension) -> (Dimension, Dimension)]
    -> ([(Dimension, Dimension) -> (Dimension, Dimension)],
        [(Dimension, Dimension) -> (Dimension, Dimension)])
    forall a. Int -> [a] -> ([a], [a])
    splitAt Int
    nrows) [(Dimension, Dimension) -> (Dimension, Dimension)]
    adjs'