    {-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-}

    -----------------------------------------------------------------------------
    -- |
    -- Module      :  XMonad.Layout.Circle
    -- Description :  An elliptical, overlapping layout.
    -- Copyright   :  (c) Peter De Wachter
    -- License     :  BSD-style (see LICENSE)
    --
    -- Maintainer  :  Peter De Wachter <pdewacht@gmail.com>
    -- Stability   :  unstable
    -- Portability :  unportable
    --
    -- Circle is an elliptical, overlapping layout, by Peter De Wachter
    --
    -----------------------------------------------------------------------------

    module XMonad.Layout.Circle (
                                 -- * Usage
                                 -- $usage
                                 Circle (..)
                                ) where -- actually it's an ellipse

    import XMonad.Prelude
    import XMonad
    import XMonad.StackSet (integrate, peek)

    -- $usage
    -- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@:
    --
    -- > import XMonad.Layout.Circle
    --
    -- Then edit your @layoutHook@ by adding the Circle layout:
    --
    -- > myLayout = Circle ||| Full ||| etc..
    -- > main = xmonad def { layoutHook = myLayout }
    --
    -- For more detailed instructions on editing the layoutHook see:
    --
    -- "XMonad.Doc.Extending#Editing_the_layout_hook"

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

    instance LayoutClass Circle Window where
        doLayout :: Circle Window
    -> Rectangle
    -> Stack Window
    -> X ([(Window, Rectangle)], Maybe (Circle Window))
    doLayout Circle Window
    Circle Rectangle
    r Stack Window
    s = do [(Window, Rectangle)]
    layout <- [(Window, Rectangle)] -> X [(Window, Rectangle)]
    raiseFocus ([(Window, Rectangle)] -> X [(Window, Rectangle)])
    -> [(Window, Rectangle)] -> X [(Window, Rectangle)]
    forall a b. (a -> b) -> a -> b
    $ Rectangle -> [Window] -> [(Window, Rectangle)]
    forall a. Rectangle -> [a] -> [(a, Rectangle)]
    circleLayout Rectangle
    r ([Window] -> [(Window, Rectangle)])
    -> [Window] -> [(Window, Rectangle)]
    forall a b. (a -> b) -> a -> b
    $ Stack Window -> [Window]
    forall a. Stack a -> [a]
    integrate Stack Window
    s
                                 ([(Window, Rectangle)], Maybe (Circle Window))
    -> X ([(Window, Rectangle)], Maybe (Circle Window))
    forall a. a -> X a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ([(Window, Rectangle)]
    layout, Maybe (Circle Window)
    forall a. Maybe a
    Nothing)

    circleLayout :: Rectangle -> [a] -> [(a, Rectangle)]
    circleLayout :: forall a. Rectangle -> [a] -> [(a, Rectangle)]
    circleLayout Rectangle
    _ []     = []
    circleLayout Rectangle
    r (a
    w:[a]
    ws) = (a, Rectangle)
    master (a, Rectangle) -> [(a, Rectangle)] -> [(a, Rectangle)]
    forall a. a -> [a] -> [a]
    : [(a, Rectangle)]
    rest
        where master :: (a, Rectangle)
    master = (a
    w, Rectangle -> Rectangle
    center Rectangle
    r)
              rest :: [(a, Rectangle)]
    rest   = [a] -> [Rectangle] -> [(a, Rectangle)]
    forall a b. [a] -> [b] -> [(a, b)]
    zip [a]
    ws ([Rectangle] -> [(a, Rectangle)])
    -> [Rectangle] -> [(a, Rectangle)]
    forall a b. (a -> b) -> a -> b
    $ (Double -> Rectangle) -> [Double] -> [Rectangle]
    forall a b. (a -> b) -> [a] -> [b]
    map (Rectangle -> Double -> Rectangle
    satellite Rectangle
    r) [Double
    0, Double
    forall a. Floating a => a
    pi Double -> Double -> Double
    forall a. Num a => a -> a -> a
    * Double
    2 Double -> Double -> Double
    forall a. Fractional a => a -> a -> a
    / Int -> Double
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral ([a] -> Int
    forall a. [a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [a]
    ws) ..]

    raiseFocus :: [(Window, Rectangle)] -> X [(Window, Rectangle)]
    raiseFocus :: [(Window, Rectangle)] -> X [(Window, Rectangle)]
    raiseFocus [(Window, Rectangle)]
    xs = do Maybe Window
    focused <- (WindowSet -> X (Maybe Window)) -> X (Maybe Window)
    forall a. (WindowSet -> X a) -> X a
    withWindowSet (Maybe Window -> X (Maybe Window)
    forall a. a -> X a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Maybe Window -> X (Maybe Window))
    -> (WindowSet -> Maybe Window) -> WindowSet -> X (Maybe Window)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . WindowSet -> Maybe Window
    forall i l a s sd. StackSet i l a s sd -> Maybe a
    peek)
                       [(Window, Rectangle)] -> X [(Window, Rectangle)]
    forall a. a -> X a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ([(Window, Rectangle)] -> X [(Window, Rectangle)])
    -> [(Window, Rectangle)] -> X [(Window, Rectangle)]
    forall a b. (a -> b) -> a -> b
    $ case ((Window, Rectangle) -> Bool)
    -> [(Window, Rectangle)] -> Maybe (Window, Rectangle)
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
    find ((Maybe Window -> Maybe Window -> Bool
    forall a. Eq a => a -> a -> Bool
    == Maybe Window
    focused) (Maybe Window -> Bool)
    -> ((Window, Rectangle) -> Maybe Window)
    -> (Window, Rectangle)
    -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Window -> Maybe Window
    forall a. a -> Maybe a
    Just (Window -> Maybe Window)
    -> ((Window, Rectangle) -> Window)
    -> (Window, Rectangle)
    -> Maybe Window
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Window, Rectangle) -> Window
    forall a b. (a, b) -> a
    fst) [(Window, Rectangle)]
    xs of
                                  Just (Window, Rectangle)
    x  -> (Window, Rectangle)
    x (Window, Rectangle)
    -> [(Window, Rectangle)] -> [(Window, Rectangle)]
    forall a. a -> [a] -> [a]
    : (Window, Rectangle)
    -> [(Window, Rectangle)] -> [(Window, Rectangle)]
    forall a. Eq a => a -> [a] -> [a]
    delete (Window, Rectangle)
    x [(Window, Rectangle)]
    xs
                                  Maybe (Window, Rectangle)
    Nothing -> [(Window, Rectangle)]
    xs

    center :: Rectangle -> Rectangle
    center :: Rectangle -> Rectangle
    center (Rectangle Position
    sx Position
    sy Dimension
    sw Dimension
    sh) = Position -> Position -> Dimension -> Dimension -> Rectangle
    Rectangle Position
    x Position
    y Dimension
    w Dimension
    h
        where s :: Double
    s = Double -> Double
    forall a. Floating a => a -> a
    sqrt Double
    2 :: Double
              w :: Dimension
    w = Double -> Dimension
    forall b. Integral b => Double -> b
    forall a b. (RealFrac a, Integral b) => a -> b
    round (Dimension -> Double
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Dimension
    sw Double -> Double -> Double
    forall a. Fractional a => a -> a -> a
    / Double
    s)
              h :: Dimension
    h = Double -> Dimension
    forall b. Integral b => Double -> b
    forall a b. (RealFrac a, Integral b) => a -> b
    round (Dimension -> Double
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Dimension
    sh Double -> Double -> Double
    forall a. Fractional a => a -> a -> a
    / Double
    s)
              x :: Position
    x = Position
    sx Position -> Position -> Position
    forall a. Num a => a -> a -> a
    + Dimension -> Position
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Dimension
    sw Dimension -> Dimension -> Dimension
    forall a. Num a => a -> a -> a
    - Dimension
    w) Position -> Position -> Position
    forall a. Integral a => a -> a -> a
    `div` Position
    2
              y :: Position
    y = Position
    sy Position -> Position -> Position
    forall a. Num a => a -> a -> a
    + Dimension -> Position
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Dimension
    sh Dimension -> Dimension -> Dimension
    forall a. Num a => a -> a -> a
    - Dimension
    h) Position -> Position -> Position
    forall a. Integral a => a -> a -> a
    `div` Position
    2

    satellite :: Rectangle -> Double -> Rectangle
    satellite :: Rectangle -> Double -> Rectangle
    satellite (Rectangle Position
    sx Position
    sy Dimension
    sw Dimension
    sh) Double
    a = Position -> Position -> Dimension -> Dimension -> Rectangle
    Rectangle (Position
    sx Position -> Position -> Position
    forall a. Num a => a -> a -> a
    + Double -> Position
    forall b. Integral b => Double -> b
    forall a b. (RealFrac a, Integral b) => a -> b
    round (Double
    rx Double -> Double -> Double
    forall a. Num a => a -> a -> a
    + Double
    rx Double -> Double -> Double
    forall a. Num a => a -> a -> a
    * Double -> Double
    forall a. Floating a => a -> a
    cos Double
    a))
                                                    (Position
    sy Position -> Position -> Position
    forall a. Num a => a -> a -> a
    + Double -> Position
    forall b. Integral b => Double -> b
    forall a b. (RealFrac a, Integral b) => a -> b
    round (Double
    ry Double -> Double -> Double
    forall a. Num a => a -> a -> a
    + Double
    ry Double -> Double -> Double
    forall a. Num a => a -> a -> a
    * Double -> Double
    forall a. Floating a => a -> a
    sin Double
    a))
                                                    Dimension
    w Dimension
    h
        where rx :: Double
    rx = Dimension -> Double
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Dimension
    sw Dimension -> Dimension -> Dimension
    forall a. Num a => a -> a -> a
    - Dimension
    w) Double -> Double -> Double
    forall a. Fractional a => a -> a -> a
    / Double
    2
              ry :: Double
    ry = Dimension -> Double
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Dimension
    sh Dimension -> Dimension -> Dimension
    forall a. Num a => a -> a -> a
    - Dimension
    h) Double -> Double -> Double
    forall a. Fractional a => a -> a -> a
    / Double
    2
              w :: Dimension
    w = Dimension
    sw Dimension -> Dimension -> Dimension
    forall a. Num a => a -> a -> a
    * Dimension
    10 Dimension -> Dimension -> Dimension
    forall a. Integral a => a -> a -> a
    `div` Dimension
    25
              h :: Dimension
    h = Dimension
    sh Dimension -> Dimension -> Dimension
    forall a. Num a => a -> a -> a
    * Dimension
    10 Dimension -> Dimension -> Dimension
    forall a. Integral a => a -> a -> a
    `div` Dimension
    25