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

    -----------------------------------------------------------------------------
    -- |
    -- Module      :  XMonad.Layout.Maximize
    -- Copyright   :  (c) 2007 James Webb
    -- License     :  BSD3-style (see LICENSE)
    --
    -- Maintainer  :  xmonad#jwebb,sygneca,com
    -- Stability   :  unstable
    -- Portability :  unportable
    --
    -- Temporarily yanks the focused window out of the layout to mostly fill
    -- the screen.
    --
    -----------------------------------------------------------------------------

    module XMonad.Layout.Maximize (
            -- * Usage
            -- $usage
            maximize,
            maximizeWithPadding,
            maximizeRestore,
            Maximize, MaximizeRestore,
        ) where

    import XMonad
    import qualified XMonad.StackSet as S
    import XMonad.Layout.LayoutModifier
    import Data.List ( partition )

    -- $usage
    -- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@:
    --
    -- > import XMonad.Layout.Maximize
    --
    -- Then edit your @layoutHook@ by adding the Maximize layout modifier:
    --
    -- > myLayout = maximize (Tall 1 (3/100) (1/2)) ||| Full ||| etc..)
    -- > main = xmonad def { layoutHook = myLayout }
    --
    -- Or, if you want to control the amount of padding placed around the
    -- maximized window:
    --
    -- > myLayout = maximizeWithPadding 10 (Tall 1 (3/100) (1/2)) ||| Full ||| etc..)
    -- > main = xmonad def { layoutHook = myLayout }
    --
    -- For more detailed instructions on editing the layoutHook see:
    --
    -- "XMonad.Doc.Extending#Editing_the_layout_hook"
    --
    -- In the key-bindings, do something like:
    --
    -- >        , ((modm, xK_backslash), withFocused (sendMessage . maximizeRestore))
    -- >        ...
    --
    -- For detailed instruction on editing the key binding see:
    --
    -- "XMonad.Doc.Extending#Editing_key_bindings".

    data Maximize a = Maximize Dimension (Maybe Window) deriving ( ReadPrec [Maximize a]
    ReadPrec (Maximize a)
    Int -> ReadS (Maximize a)
    ReadS [Maximize a]
    (Int -> ReadS (Maximize a))
    -> ReadS [Maximize a]
    -> ReadPrec (Maximize a)
    -> ReadPrec [Maximize a]
    -> Read (Maximize a)
    forall a. ReadPrec [Maximize a]
    forall a. ReadPrec (Maximize a)
    forall a. Int -> ReadS (Maximize a)
    forall a. ReadS [Maximize a]
    forall a.
    (Int -> ReadS a)
    -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
    readListPrec :: ReadPrec [Maximize a]
    $creadListPrec :: forall a. ReadPrec [Maximize a]
    readPrec :: ReadPrec (Maximize a)
    $creadPrec :: forall a. ReadPrec (Maximize a)
    readList :: ReadS [Maximize a]
    $creadList :: forall a. ReadS [Maximize a]
    readsPrec :: Int -> ReadS (Maximize a)
    $creadsPrec :: forall a. Int -> ReadS (Maximize a)
    Read, Int -> Maximize a -> ShowS
    [Maximize a] -> ShowS
    Maximize a -> String
    (Int -> Maximize a -> ShowS)
    -> (Maximize a -> String)
    -> ([Maximize a] -> ShowS)
    -> Show (Maximize a)
    forall a. Int -> Maximize a -> ShowS
    forall a. [Maximize a] -> ShowS
    forall a. Maximize a -> String
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    showList :: [Maximize a] -> ShowS
    $cshowList :: forall a. [Maximize a] -> ShowS
    show :: Maximize a -> String
    $cshow :: forall a. Maximize a -> String
    showsPrec :: Int -> Maximize a -> ShowS
    $cshowsPrec :: forall a. Int -> Maximize a -> ShowS
    Show )
    maximize :: LayoutClass l Window => l Window -> ModifiedLayout Maximize l Window
    maximize :: l Window -> ModifiedLayout Maximize l Window
    maximize = Maximize Window -> l Window -> ModifiedLayout Maximize l Window
    forall (m :: * -> *) (l :: * -> *) a.
    m a -> l a -> ModifiedLayout m l a
    ModifiedLayout (Maximize Window -> l Window -> ModifiedLayout Maximize l Window)
    -> Maximize Window -> l Window -> ModifiedLayout Maximize l Window
    forall a b. (a -> b) -> a -> b
    $ Dimension -> Maybe Window -> Maximize Window
    forall a. Dimension -> Maybe Window -> Maximize a
    Maximize 25 Maybe Window
    forall a. Maybe a
    Nothing

    -- | Like 'maximize', but allows you to specify the amount of padding
    -- placed around the maximized window.
    maximizeWithPadding :: LayoutClass l Window => Dimension -> l Window -> ModifiedLayout Maximize l Window
    maximizeWithPadding :: Dimension -> l Window -> ModifiedLayout Maximize l Window
    maximizeWithPadding padding :: Dimension
    padding = Maximize Window -> l Window -> ModifiedLayout Maximize l Window
    forall (m :: * -> *) (l :: * -> *) a.
    m a -> l a -> ModifiedLayout m l a
    ModifiedLayout (Maximize Window -> l Window -> ModifiedLayout Maximize l Window)
    -> Maximize Window -> l Window -> ModifiedLayout Maximize l Window
    forall a b. (a -> b) -> a -> b
    $ Dimension -> Maybe Window -> Maximize Window
    forall a. Dimension -> Maybe Window -> Maximize a
    Maximize Dimension
    padding Maybe Window
    forall a. Maybe a
    Nothing

    data MaximizeRestore = MaximizeRestore Window deriving ( Typeable, MaximizeRestore -> MaximizeRestore -> Bool
    (MaximizeRestore -> MaximizeRestore -> Bool)
    -> (MaximizeRestore -> MaximizeRestore -> Bool)
    -> Eq MaximizeRestore
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    /= :: MaximizeRestore -> MaximizeRestore -> Bool
    $c/= :: MaximizeRestore -> MaximizeRestore -> Bool
    == :: MaximizeRestore -> MaximizeRestore -> Bool
    $c== :: MaximizeRestore -> MaximizeRestore -> Bool
    Eq )
    instance Message MaximizeRestore
    maximizeRestore :: Window -> MaximizeRestore
    maximizeRestore :: Window -> MaximizeRestore
    maximizeRestore = Window -> MaximizeRestore
    MaximizeRestore

    instance LayoutModifier Maximize Window where
        modifierDescription :: Maximize Window -> String
    modifierDescription (Maximize _ _) = "Maximize"
        pureModifier :: Maximize Window
    -> Rectangle
    -> Maybe (Stack Window)
    -> [(Window, Rectangle)]
    -> ([(Window, Rectangle)], Maybe (Maximize Window))
    pureModifier (Maximize padding :: Dimension
    padding (Just target :: Window
    target)) rect :: Rectangle
    rect (Just (S.Stack focused :: Window
    focused _ _)) wrs :: [(Window, Rectangle)]
    wrs =
                if Window
    focused Window -> Window -> Bool
    forall a. Eq a => a -> a -> Bool
    == Window
    target
                    then ([(Window, Rectangle)]
    maxed [(Window, Rectangle)]
    -> [(Window, Rectangle)] -> [(Window, Rectangle)]
    forall a. [a] -> [a] -> [a]
    ++ [(Window, Rectangle)]
    rest, Maybe (Maximize Window)
    forall a. Maybe a
    Nothing)
                    else ([(Window, Rectangle)]
    rest [(Window, Rectangle)]
    -> [(Window, Rectangle)] -> [(Window, Rectangle)]
    forall a. [a] -> [a] -> [a]
    ++ [(Window, Rectangle)]
    maxed, Maybe (Maximize Window)
    forall a. Maybe (Maximize a)
    lay)
            where
                (toMax :: [(Window, Rectangle)]
    toMax, rest :: [(Window, Rectangle)]
    rest) = ((Window, Rectangle) -> Bool)
    -> [(Window, Rectangle)]
    -> ([(Window, Rectangle)], [(Window, Rectangle)])
    forall a. (a -> Bool) -> [a] -> ([a], [a])
    partition (\(w :: Window
    w, _) -> Window
    w Window -> Window -> Bool
    forall a. Eq a => a -> a -> Bool
    == Window
    target) [(Window, Rectangle)]
    wrs
                maxed :: [(Window, Rectangle)]
    maxed = ((Window, Rectangle) -> (Window, Rectangle))
    -> [(Window, Rectangle)] -> [(Window, Rectangle)]
    forall a b. (a -> b) -> [a] -> [b]
    map (\(w :: Window
    w, _) -> (Window
    w, Rectangle
    maxRect)) [(Window, Rectangle)]
    toMax
                maxRect :: Rectangle
    maxRect = Position -> Position -> Dimension -> Dimension -> Rectangle
    Rectangle (Rectangle -> Position
    rect_x Rectangle
    rect Position -> Position -> Position
    forall a. Num a => a -> a -> a
    + Dimension -> Position
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Dimension
    padding)
                                    (Rectangle -> Position
    rect_y Rectangle
    rect Position -> Position -> Position
    forall a. Num a => a -> a -> a
    + Dimension -> Position
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Dimension
    padding)
                                    (Rectangle -> Dimension
    rect_width Rectangle
    rect  Dimension -> Dimension -> Dimension
    forall a. Num a => a -> a -> a
    - Dimension
    padding Dimension -> Dimension -> Dimension
    forall a. Num a => a -> a -> a
    * 2)
                                    (Rectangle -> Dimension
    rect_height Rectangle
    rect Dimension -> Dimension -> Dimension
    forall a. Num a => a -> a -> a
    - Dimension
    padding Dimension -> Dimension -> Dimension
    forall a. Num a => a -> a -> a
    * 2)
                lay :: Maybe (Maximize a)
    lay | [(Window, Rectangle)] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [(Window, Rectangle)]
    maxed = Maximize a -> Maybe (Maximize a)
    forall a. a -> Maybe a
    Just (Dimension -> Maybe Window -> Maximize a
    forall a. Dimension -> Maybe Window -> Maximize a
    Maximize Dimension
    padding Maybe Window
    forall a. Maybe a
    Nothing)
                    | Bool
    otherwise  = Maybe (Maximize a)
    forall a. Maybe a
    Nothing
        pureModifier _ _ _ wrs :: [(Window, Rectangle)]
    wrs = ([(Window, Rectangle)]
    wrs, Maybe (Maximize Window)
    forall a. Maybe a
    Nothing)

        pureMess :: Maximize Window -> SomeMessage -> Maybe (Maximize Window)
    pureMess (Maximize padding :: Dimension
    padding mw :: Maybe Window
    mw) m :: SomeMessage
    m = case SomeMessage -> Maybe MaximizeRestore
    forall m. Message m => SomeMessage -> Maybe m
    fromMessage SomeMessage
    m of
            Just (MaximizeRestore w :: Window
    w) -> case Maybe Window
    mw of
                Just w' :: Window
    w' -> if (Window
    w Window -> Window -> Bool
    forall a. Eq a => a -> a -> Bool
    == Window
    w')
                            then Maximize Window -> Maybe (Maximize Window)
    forall a. a -> Maybe a
    Just (Maximize Window -> Maybe (Maximize Window))
    -> Maximize Window -> Maybe (Maximize Window)
    forall a b. (a -> b) -> a -> b
    $ Dimension -> Maybe Window -> Maximize Window
    forall a. Dimension -> Maybe Window -> Maximize a
    Maximize Dimension
    padding Maybe Window
    forall a. Maybe a
    Nothing   -- restore window
                            else Maximize Window -> Maybe (Maximize Window)
    forall a. a -> Maybe a
    Just (Maximize Window -> Maybe (Maximize Window))
    -> Maximize Window -> Maybe (Maximize Window)
    forall a b. (a -> b) -> a -> b
    $ Dimension -> Maybe Window -> Maximize Window
    forall a. Dimension -> Maybe Window -> Maximize a
    Maximize Dimension
    padding (Maybe Window -> Maximize Window)
    -> Maybe Window -> Maximize Window
    forall a b. (a -> b) -> a -> b
    $ Window -> Maybe Window
    forall a. a -> Maybe a
    Just Window
    w  -- maximize different window
                Nothing -> Maximize Window -> Maybe (Maximize Window)
    forall a. a -> Maybe a
    Just (Maximize Window -> Maybe (Maximize Window))
    -> Maximize Window -> Maybe (Maximize Window)
    forall a b. (a -> b) -> a -> b
    $ Dimension -> Maybe Window -> Maximize Window
    forall a. Dimension -> Maybe Window -> Maximize a
    Maximize Dimension
    padding (Maybe Window -> Maximize Window)
    -> Maybe Window -> Maximize Window
    forall a b. (a -> b) -> a -> b
    $ Window -> Maybe Window
    forall a. a -> Maybe a
    Just Window
    w        -- maximize window
            _ -> Maybe (Maximize Window)
    forall a. Maybe a
    Nothing

    -- vim: sw=4:et