    -----------------------------------------------------------------------------
    -- |
    -- Module       : XMonad.Hooks.ManageHelpers
    -- Copyright    : (c) Lukas Mai
    -- License      : BSD
    --
    -- Maintainer   : Lukas Mai <l.mai@web.de>
    -- Stability    : unstable
    -- Portability  : unportable
    --
    -- This module provides helper functions to be used in @manageHook@. Here's
    -- how you might use this:
    --
    -- > import XMonad.Hooks.ManageHelpers
    -- > main =
    -- >     xmonad def{
    -- >         ...
    -- >         manageHook = composeOne [
    -- >             isKDETrayWindow -?> doIgnore,
    -- >             transience,
    -- >             isFullscreen -?> doFullFloat,
    -- >             resource =? "stalonetray" -?> doIgnore
    -- >         ],
    -- >         ...
    -- >     }

    module XMonad.Hooks.ManageHelpers (
        Side(..),
        composeOne,
        (-?>), (/=?), (<==?), (</=?), (-->>), (-?>>),
        currentWs,
        isInProperty,
        isKDETrayWindow,
        isFullscreen,
        isDialog,
        pid,
        transientTo,
        maybeToDefinite,
        MaybeManageHook,
        transience,
        transience',
        doRectFloat,
        doFullFloat,
        doCenterFloat,
        doSideFloat,
        doFloatAt,
        doFloatDep,
        doHideIgnore,
        Match,
    ) where

    import XMonad
    import qualified XMonad.StackSet as W
    import XMonad.Util.WindowProperties (getProp32s)

    import Data.Maybe
    import Data.Monoid

    import System.Posix (ProcessID)

    -- | Denotes a side of a screen. @S@ stands for South, @NE@ for Northeast
    -- etc. @C@ stands for Center.
    data Side = SC | NC | CE | CW | SE | SW | NE | NW | C
        deriving (ReadPrec [Side]
    ReadPrec Side
    Int -> ReadS Side
    ReadS [Side]
    (Int -> ReadS Side)
    -> ReadS [Side] -> ReadPrec Side -> ReadPrec [Side] -> Read Side
    forall a.
    (Int -> ReadS a)
    -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
    readListPrec :: ReadPrec [Side]
    $creadListPrec :: ReadPrec [Side]
    readPrec :: ReadPrec Side
    $creadPrec :: ReadPrec Side
    readList :: ReadS [Side]
    $creadList :: ReadS [Side]
    readsPrec :: Int -> ReadS Side
    $creadsPrec :: Int -> ReadS Side
    Read, Int -> Side -> ShowS
    [Side] -> ShowS
    Side -> String
    (Int -> Side -> ShowS)
    -> (Side -> String) -> ([Side] -> ShowS) -> Show Side
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    showList :: [Side] -> ShowS
    $cshowList :: [Side] -> ShowS
    show :: Side -> String
    $cshow :: Side -> String
    showsPrec :: Int -> Side -> ShowS
    $cshowsPrec :: Int -> Side -> ShowS
    Show, Side -> Side -> Bool
    (Side -> Side -> Bool) -> (Side -> Side -> Bool) -> Eq Side
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    /= :: Side -> Side -> Bool
    $c/= :: Side -> Side -> Bool
    == :: Side -> Side -> Bool
    $c== :: Side -> Side -> Bool
    Eq)

    -- | A ManageHook that may or may not have been executed; the outcome is embedded in the Maybe
    type MaybeManageHook = Query (Maybe (Endo WindowSet))
    -- | A grouping type, which can hold the outcome of a predicate Query.
    -- This is analogous to group types in regular expressions.
    -- TODO: create a better API for aggregating multiple Matches logically
    data Match a = Match Bool a

    -- | An alternative 'ManageHook' composer. Unlike 'composeAll' it stops as soon as
    -- a candidate returns a 'Just' value, effectively running only the first match
    -- (whereas 'composeAll' continues and executes all matching rules).
    composeOne :: [MaybeManageHook] -> ManageHook
    composeOne :: [MaybeManageHook] -> ManageHook
    composeOne = (MaybeManageHook -> ManageHook -> ManageHook)
    -> ManageHook -> [MaybeManageHook] -> ManageHook
    forall (t :: * -> *) a b.
    Foldable t =>
    (a -> b -> b) -> b -> t a -> b
    foldr MaybeManageHook -> ManageHook -> ManageHook
    forall (m :: * -> *) b. Monad m => m (Maybe b) -> m b -> m b
    try ManageHook
    forall m. Monoid m => m
    idHook
        where
        try :: m (Maybe b) -> m b -> m b
    try q :: m (Maybe b)
    q z :: m b
    z = do
            Maybe b
    x <- m (Maybe b)
    q
            case Maybe b
    x of
                Just h :: b
    h -> b -> m b
    forall (m :: * -> *) a. Monad m => a -> m a
    return b
    h
                Nothing -> m b
    z

    infixr 0 -?>, -->>, -?>>

    -- | q \/=? x. if the result of q equals x, return False
    (/=?) :: Eq a => Query a -> a -> Query Bool
    q :: Query a
    q /=? :: Query a -> a -> Query Bool
    /=? x :: a
    x = (a -> Bool) -> Query a -> Query Bool
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (a -> a -> Bool
    forall a. Eq a => a -> a -> Bool
    /= a
    x) Query a
    q

    -- | q <==? x. if the result of q equals x, return True grouped with q
    (<==?) :: Eq a => Query a -> a -> Query (Match a)
    q :: Query a
    q <==? :: Query a -> a -> Query (Match a)
    <==? x :: a
    x = (a -> Match a) -> Query a -> Query (Match a)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (a -> a -> Match a
    forall a. Eq a => a -> a -> Match a
    `eq` a
    x) Query a
    q
        where
        eq :: a -> a -> Match a
    eq q' :: a
    q' x' :: a
    x' = Bool -> a -> Match a
    forall a. Bool -> a -> Match a
    Match (a
    q' a -> a -> Bool
    forall a. Eq a => a -> a -> Bool
    == a
    x') a
    q'

    -- | q <\/=? x. if the result of q notequals x, return True grouped with q
    (</=?) :: Eq a => Query a -> a -> Query (Match a)
    q :: Query a
    q </=? :: Query a -> a -> Query (Match a)
    </=? x :: a
    x = (a -> Match a) -> Query a -> Query (Match a)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (a -> a -> Match a
    forall a. Eq a => a -> a -> Match a
    `neq` a
    x) Query a
    q
        where
        neq :: a -> a -> Match a
    neq q' :: a
    q' x' :: a
    x' = Bool -> a -> Match a
    forall a. Bool -> a -> Match a
    Match (a
    q' a -> a -> Bool
    forall a. Eq a => a -> a -> Bool
    /= a
    x') a
    q'

    -- | A helper operator for use in 'composeOne'. It takes a condition and an action;
    -- if the condition fails, it returns 'Nothing' from the 'Query' so 'composeOne' will
    -- go on and try the next rule.
    (-?>) :: Query Bool -> ManageHook -> MaybeManageHook
    p :: Query Bool
    p -?> :: Query Bool -> ManageHook -> MaybeManageHook
    -?> f :: ManageHook
    f = do
        Bool
    x <- Query Bool
    p
        if Bool
    x then (Endo WindowSet -> Maybe (Endo WindowSet))
    -> ManageHook -> MaybeManageHook
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap Endo WindowSet -> Maybe (Endo WindowSet)
    forall a. a -> Maybe a
    Just ManageHook
    f else Maybe (Endo WindowSet) -> MaybeManageHook
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe (Endo WindowSet)
    forall a. Maybe a
    Nothing

    -- | A helper operator for use in 'composeAll'. It takes a condition and a function taking a grouped datum to action.  If 'p' is true, it executes the resulting action.
    (-->>) :: Query (Match a) -> (a -> ManageHook) -> ManageHook
    p :: Query (Match a)
    p -->> :: Query (Match a) -> (a -> ManageHook) -> ManageHook
    -->> f :: a -> ManageHook
    f = do
        Match b :: Bool
    b m :: a
    m <- Query (Match a)
    p
        if Bool
    b then (a -> ManageHook
    f a
    m) else ManageHook
    forall m. Monoid m => m
    mempty

    -- | A helper operator for use in 'composeOne'.  It takes a condition and a function taking a groupdatum to action.  If 'p' is true, it executes the resulting action.  If it fails, it returns 'Nothing' from the 'Query' so 'composeOne' will go on and try the next rule.
    (-?>>) :: Query (Match a) -> (a -> ManageHook) -> MaybeManageHook
    p :: Query (Match a)
    p -?>> :: Query (Match a) -> (a -> ManageHook) -> MaybeManageHook
    -?>> f :: a -> ManageHook
    f = do
        Match b :: Bool
    b m :: a
    m <- Query (Match a)
    p
        if Bool
    b then (Endo WindowSet -> Maybe (Endo WindowSet))
    -> ManageHook -> MaybeManageHook
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap  Endo WindowSet -> Maybe (Endo WindowSet)
    forall a. a -> Maybe a
    Just (a -> ManageHook
    f a
    m) else Maybe (Endo WindowSet) -> MaybeManageHook
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe (Endo WindowSet)
    forall a. Maybe a
    Nothing

    -- | Return the current workspace
    currentWs :: Query WorkspaceId
    currentWs :: Query String
    currentWs = X String -> Query String
    forall a. X a -> Query a
    liftX ((WindowSet -> X String) -> X String
    forall a. (WindowSet -> X a) -> X a
    withWindowSet ((WindowSet -> X String) -> X String)
    -> (WindowSet -> X String) -> X String
    forall a b. (a -> b) -> a -> b
    $ String -> X String
    forall (m :: * -> *) a. Monad m => a -> m a
    return (String -> X String)
    -> (WindowSet -> String) -> WindowSet -> X String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . WindowSet -> String
    forall i l a s sd. StackSet i l a s sd -> i
    W.currentTag)

    -- | A predicate to check whether a window is a KDE system tray icon.
    isKDETrayWindow :: Query Bool
    isKDETrayWindow :: Query Bool
    isKDETrayWindow = Query Window
    forall r (m :: * -> *). MonadReader r m => m r
    ask Query Window -> (Window -> Query Bool) -> Query Bool
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= \w :: Window
    w -> X Bool -> Query Bool
    forall a. X a -> Query a
    liftX (X Bool -> Query Bool) -> X Bool -> Query Bool
    forall a b. (a -> b) -> a -> b
    $ do
        Maybe [CLong]
    r <- String -> Window -> X (Maybe [CLong])
    getProp32s "_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR" Window
    w
        Bool -> X Bool
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Bool -> X Bool) -> Bool -> X Bool
    forall a b. (a -> b) -> a -> b
    $ case Maybe [CLong]
    r of
            Just [_] -> Bool
    True
            _ -> Bool
    False

    -- | Helper to check if a window property contains certain value.
    isInProperty :: String -> String -> Query Bool
    isInProperty :: String -> String -> Query Bool
    isInProperty p :: String
    p v :: String
    v = Query Window
    forall r (m :: * -> *). MonadReader r m => m r
    ask Query Window -> (Window -> Query Bool) -> Query Bool
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= \w :: Window
    w -> X Bool -> Query Bool
    forall a. X a -> Query a
    liftX (X Bool -> Query Bool) -> X Bool -> Query Bool
    forall a b. (a -> b) -> a -> b
    $ do
        Window
    va <- String -> X Window
    getAtom String
    v
        Maybe [CLong]
    r <- String -> Window -> X (Maybe [CLong])
    getProp32s String
    p Window
    w
        Bool -> X Bool
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Bool -> X Bool) -> Bool -> X Bool
    forall a b. (a -> b) -> a -> b
    $ case Maybe [CLong]
    r of
            Just xs :: [CLong]
    xs -> Window -> CLong
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Window
    va CLong -> [CLong] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` [CLong]
    xs
            _ -> Bool
    False

    -- | A predicate to check whether a window wants to fill the whole screen.
    -- See also 'doFullFloat'.
    isFullscreen :: Query Bool
    isFullscreen :: Query Bool
    isFullscreen = String -> String -> Query Bool
    isInProperty "_NET_WM_STATE" "_NET_WM_STATE_FULLSCREEN"

    -- | A predicate to check whether a window is a dialog.
    isDialog :: Query Bool
    isDialog :: Query Bool
    isDialog = String -> String -> Query Bool
    isInProperty "_NET_WM_WINDOW_TYPE" "_NET_WM_WINDOW_TYPE_DIALOG"

    pid :: Query (Maybe ProcessID)
    pid :: Query (Maybe ProcessID)
    pid = Query Window
    forall r (m :: * -> *). MonadReader r m => m r
    ask Query Window
    -> (Window -> Query (Maybe ProcessID)) -> Query (Maybe ProcessID)
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= \w :: Window
    w -> X (Maybe ProcessID) -> Query (Maybe ProcessID)
    forall a. X a -> Query a
    liftX (X (Maybe ProcessID) -> Query (Maybe ProcessID))
    -> X (Maybe ProcessID) -> Query (Maybe ProcessID)
    forall a b. (a -> b) -> a -> b
    $ do
        Maybe [CLong]
    p <- String -> Window -> X (Maybe [CLong])
    getProp32s "_NET_WM_PID" Window
    w
        Maybe ProcessID -> X (Maybe ProcessID)
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Maybe ProcessID -> X (Maybe ProcessID))
    -> Maybe ProcessID -> X (Maybe ProcessID)
    forall a b. (a -> b) -> a -> b
    $ case Maybe [CLong]
    p of
            Just [x :: CLong
    x] -> ProcessID -> Maybe ProcessID
    forall a. a -> Maybe a
    Just (CLong -> ProcessID
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral CLong
    x)
            _        -> Maybe ProcessID
    forall a. Maybe a
    Nothing

    -- | A predicate to check whether a window is Transient.
    -- It holds the result which might be the window it is transient to
    -- or it might be 'Nothing'.
    transientTo :: Query (Maybe Window)
    transientTo :: Query (Maybe Window)
    transientTo = do
        Window
    w <- Query Window
    forall r (m :: * -> *). MonadReader r m => m r
    ask
        Display
    d <- (X Display -> Query Display
    forall a. X a -> Query a
    liftX (X Display -> Query Display)
    -> ((XConf -> Display) -> X Display)
    -> (XConf -> Display)
    -> Query Display
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (XConf -> Display) -> X Display
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    asks) XConf -> Display
    display
        IO (Maybe Window) -> Query (Maybe Window)
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO (Maybe Window) -> Query (Maybe Window))
    -> IO (Maybe Window) -> Query (Maybe Window)
    forall a b. (a -> b) -> a -> b
    $ Display -> Window -> IO (Maybe Window)
    getTransientForHint Display
    d Window
    w

    -- | A convenience 'MaybeManageHook' that will check to see if a window
    -- is transient, and then move it to its parent.
    transience :: MaybeManageHook
    transience :: MaybeManageHook
    transience = Query (Maybe Window)
    transientTo Query (Maybe Window)
    -> Maybe Window -> Query (Match (Maybe Window))
    forall a. Eq a => Query a -> a -> Query (Match a)
    </=? Maybe Window
    forall a. Maybe a
    Nothing Query (Match (Maybe Window))
    -> (Maybe Window -> ManageHook) -> MaybeManageHook
    forall a. Query (Match a) -> (a -> ManageHook) -> MaybeManageHook
    -?>> Maybe Window -> ManageHook
    forall a s i l sd.
    (Ord a, Eq s, Eq i) =>
    Maybe a -> Query (Endo (StackSet i l a s sd))
    move
        where
        move :: Maybe a -> Query (Endo (StackSet i l a s sd))
    move mw :: Maybe a
    mw = Query (Endo (StackSet i l a s sd))
    -> (a -> Query (Endo (StackSet i l a s sd)))
    -> Maybe a
    -> Query (Endo (StackSet i l a s sd))
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe Query (Endo (StackSet i l a s sd))
    forall m. Monoid m => m
    idHook ((StackSet i l a s sd -> StackSet i l a s sd)
    -> Query (Endo (StackSet i l a s sd))
    forall s. (s -> s) -> Query (Endo s)
    doF ((StackSet i l a s sd -> StackSet i l a s sd)
     -> Query (Endo (StackSet i l a s sd)))
    -> (a -> StackSet i l a s sd -> StackSet i l a s sd)
    -> a
    -> Query (Endo (StackSet i l a s sd))
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> StackSet i l a s sd -> StackSet i l a s sd
    forall a s i l sd.
    (Ord a, Eq s, Eq i) =>
    a -> StackSet i l a s sd -> StackSet i l a s sd
    move') Maybe a
    mw
        move' :: a -> StackSet i l a s sd -> StackSet i l a s sd
    move' w :: a
    w s :: StackSet i l a s sd
    s = StackSet i l a s sd
    -> (i -> StackSet i l a s sd) -> Maybe i -> StackSet i l a s sd
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe StackSet i l a s sd
    s (i -> StackSet i l a s sd -> StackSet i l a s sd
    forall a s i l sd.
    (Ord a, Eq s, Eq i) =>
    i -> StackSet i l a s sd -> StackSet i l a s sd
    `W.shift` StackSet i l a s sd
    s) (a -> StackSet i l a s sd -> Maybe i
    forall a i l s sd. Eq a => a -> StackSet i l a s sd -> Maybe i
    W.findTag a
    w StackSet i l a s sd
    s)

    -- | 'transience' set to a 'ManageHook'
    transience' :: ManageHook
    transience' :: ManageHook
    transience' = MaybeManageHook -> ManageHook
    maybeToDefinite MaybeManageHook
    transience

    -- | converts 'MaybeManageHook's to 'ManageHook's
    maybeToDefinite :: MaybeManageHook -> ManageHook
    maybeToDefinite :: MaybeManageHook -> ManageHook
    maybeToDefinite = (Maybe (Endo WindowSet) -> Endo WindowSet)
    -> MaybeManageHook -> ManageHook
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (Endo WindowSet -> Maybe (Endo WindowSet) -> Endo WindowSet
    forall a. a -> Maybe a -> a
    fromMaybe Endo WindowSet
    forall m. Monoid m => m
    mempty)

    -- | Floats the new window in the given rectangle.
    doRectFloat :: W.RationalRect  -- ^ The rectangle to float the window in. 0 to 1; x, y, w, h.
                -> ManageHook
    doRectFloat :: RationalRect -> ManageHook
    doRectFloat r :: RationalRect
    r = Query Window
    forall r (m :: * -> *). MonadReader r m => m r
    ask Query Window -> (Window -> ManageHook) -> ManageHook
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= \w :: Window
    w -> (WindowSet -> WindowSet) -> ManageHook
    forall s. (s -> s) -> Query (Endo s)
    doF (Window -> RationalRect -> WindowSet -> WindowSet
    forall a i l s sd.
    Ord a =>
    a -> RationalRect -> StackSet i l a s sd -> StackSet i l a s sd
    W.float Window
    w RationalRect
    r)

    -- | Floats the window and makes it use the whole screen. Equivalent to
    -- @'doRectFloat' $ 'W.RationalRect' 0 0 1 1@.
    doFullFloat :: ManageHook
    doFullFloat :: ManageHook
    doFullFloat = RationalRect -> ManageHook
    doRectFloat (RationalRect -> ManageHook) -> RationalRect -> ManageHook
    forall a b. (a -> b) -> a -> b
    $ Rational -> Rational -> Rational -> Rational -> RationalRect
    W.RationalRect 0 0 1 1

    -- | Floats a new window using a rectangle computed as a function of
    --   the rectangle that it would have used by default.
    doFloatDep :: (W.RationalRect -> W.RationalRect) -> ManageHook
    doFloatDep :: (RationalRect -> RationalRect) -> ManageHook
    doFloatDep move :: RationalRect -> RationalRect
    move = Query Window
    forall r (m :: * -> *). MonadReader r m => m r
    ask Query Window -> (Window -> ManageHook) -> ManageHook
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= \w :: Window
    w -> (WindowSet -> WindowSet) -> ManageHook
    forall s. (s -> s) -> Query (Endo s)
    doF ((WindowSet -> WindowSet) -> ManageHook)
    -> ((ScreenId, RationalRect) -> WindowSet -> WindowSet)
    -> (ScreenId, RationalRect)
    -> ManageHook
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Window -> RationalRect -> WindowSet -> WindowSet
    forall a i l s sd.
    Ord a =>
    a -> RationalRect -> StackSet i l a s sd -> StackSet i l a s sd
    W.float Window
    w (RationalRect -> WindowSet -> WindowSet)
    -> ((ScreenId, RationalRect) -> RationalRect)
    -> (ScreenId, RationalRect)
    -> WindowSet
    -> WindowSet
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . RationalRect -> RationalRect
    move (RationalRect -> RationalRect)
    -> ((ScreenId, RationalRect) -> RationalRect)
    -> (ScreenId, RationalRect)
    -> RationalRect
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (ScreenId, RationalRect) -> RationalRect
    forall a b. (a, b) -> b
    snd ((ScreenId, RationalRect) -> ManageHook)
    -> Query (ScreenId, RationalRect) -> ManageHook
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
    =<< X (ScreenId, RationalRect) -> Query (ScreenId, RationalRect)
    forall a. X a -> Query a
    liftX (Window -> X (ScreenId, RationalRect)
    floatLocation Window
    w)

    -- | Floats a new window with its original size, and its top left
    --   corner at a specific point on the screen (both coordinates should
    --   be in the range 0 to 1).
    doFloatAt :: Rational -> Rational -> ManageHook
    doFloatAt :: Rational -> Rational -> ManageHook
    doFloatAt x :: Rational
    x y :: Rational
    y = (RationalRect -> RationalRect) -> ManageHook
    doFloatDep RationalRect -> RationalRect
    move
      where
        move :: RationalRect -> RationalRect
    move (W.RationalRect _ _ w :: Rational
    w h :: Rational
    h) = Rational -> Rational -> Rational -> Rational -> RationalRect
    W.RationalRect Rational
    x Rational
    y Rational
    w Rational
    h

    -- | Floats a new window with its original size on the specified side of a
    -- screen
    doSideFloat :: Side -> ManageHook
    doSideFloat :: Side -> ManageHook
    doSideFloat side :: Side
    side = (RationalRect -> RationalRect) -> ManageHook
    doFloatDep RationalRect -> RationalRect
    move
      where
        move :: RationalRect -> RationalRect
    move (W.RationalRect _ _ w :: Rational
    w h :: Rational
    h) = Rational -> Rational -> Rational -> Rational -> RationalRect
    W.RationalRect Rational
    cx Rational
    cy Rational
    w Rational
    h
          where cx :: Rational
    cx =      if Side
    side Side -> [Side] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` [Side
    SC,Side
    C ,Side
    NC] then (1Rational -> Rational -> Rational
    forall a. Num a => a -> a -> a
    -Rational
    w)Rational -> Rational -> Rational
    forall a. Fractional a => a -> a -> a
    /2
                     else if Side
    side Side -> [Side] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` [Side
    SW,Side
    CW,Side
    NW] then 0
                     else {- side `elem` [SE,CE,NE] -}   1Rational -> Rational -> Rational
    forall a. Num a => a -> a -> a
    -Rational
    w
                cy :: Rational
    cy =      if Side
    side Side -> [Side] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` [Side
    CE,Side
    C ,Side
    CW] then (1Rational -> Rational -> Rational
    forall a. Num a => a -> a -> a
    -Rational
    h)Rational -> Rational -> Rational
    forall a. Fractional a => a -> a -> a
    /2
                     else if Side
    side Side -> [Side] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` [Side
    NE,Side
    NC,Side
    NW] then 0
                     else {- side `elem` [SE,SC,SW] -}   1Rational -> Rational -> Rational
    forall a. Num a => a -> a -> a
    -Rational
    h

    -- | Floats a new window with its original size, but centered.
    doCenterFloat :: ManageHook
    doCenterFloat :: ManageHook
    doCenterFloat = Side -> ManageHook
    doSideFloat Side
    C

    -- | Hides window and ignores it.
    doHideIgnore :: ManageHook
    doHideIgnore :: ManageHook
    doHideIgnore = Query Window
    forall r (m :: * -> *). MonadReader r m => m r
    ask Query Window -> (Window -> ManageHook) -> ManageHook
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= \w :: Window
    w -> X () -> Query ()
    forall a. X a -> Query a
    liftX (Window -> X ()
    hide Window
    w) Query () -> ManageHook -> ManageHook
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> (WindowSet -> WindowSet) -> ManageHook
    forall s. (s -> s) -> Query (Endo s)
    doF (Window -> WindowSet -> WindowSet
    forall a i l s sd.
    Ord a =>
    a -> StackSet i l a s sd -> StackSet i l a s sd
    W.delete Window
    w)