    {-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, PatternGuards #-}

    -----------------------------------------------------------------------------
    -- |
    -- Module      :  XMonad.Layout.Gaps
    -- Description :  Create manually-sized gaps along edges of the screen.
    -- Copyright   :  (c) 2008 Brent Yorgey
    -- License     :  BSD3
    --
    -- Maintainer  :  <byorgey@gmail.com>
    -- Stability   :  unstable
    -- Portability :  unportable
    --
    -- Create manually-sized gaps along edges of the screen which will not
    -- be used for tiling, along with support for toggling gaps on and
    -- off.
    --
    -- Note 1: For gaps\/space around /windows/ see "XMonad.Layout.Spacing".
    --
    -- Note 2: "XMonad.Hooks.ManageDocks" is the preferred solution for
    -- leaving space for your dock-type applications (status bars,
    -- toolbars, docks, etc.), since it automatically sets up appropriate
    -- gaps, allows them to be toggled, etc.  However, this module may
    -- still be useful in some situations where the automated approach of
    -- ManageDocks does not work; for example, to work with a dock-type
    -- application that does not properly set the STRUTS property, or to
    -- leave part of the screen blank which is truncated by a projector,
    -- and so on.
    -----------------------------------------------------------------------------

    module XMonad.Layout.Gaps (
                                   -- * Usage
                                   -- $usage
                              Direction2D(..), Gaps,
                              GapSpec, gaps, gaps', GapMessage(..),
                              weakModifyGaps, modifyGap, setGaps, setGap
                              ) where

    import XMonad.Prelude (delete, fi)
    import XMonad.Core
    import Graphics.X11 (Rectangle(..))

    import XMonad.Layout.LayoutModifier
    import XMonad.Util.Types (Direction2D(..))

    -- $usage
    -- You can use this module by importing it into your @xmonad.hs@ file:
    --
    -- > import XMonad.Layout.Gaps
    --
    -- and applying the 'gaps' modifier to your layouts as follows (for
    -- example):
    --
    -- > layoutHook = gaps [(U,18), (R,23)] $ Tall 1 (3/100) (1/2) ||| Full  -- leave gaps at the top and right
    --
    -- You can additionally add some keybindings to toggle or modify the gaps,
    -- for example:
    --
    -- > , ((modm .|. controlMask, xK_g), sendMessage $ ToggleGaps)               -- toggle all gaps
    -- > , ((modm .|. controlMask, xK_t), sendMessage $ ToggleGap U)              -- toggle the top gap
    -- > , ((modm .|. controlMask, xK_w), sendMessage $ IncGap 5 R)               -- increment the right-hand gap
    -- > , ((modm .|. controlMask, xK_q), sendMessage $ DecGap 5 R)               -- decrement the right-hand gap
    -- > , ((modm .|. controlMask, xK_r), sendMessage $ ModifyGaps rotateGaps)    -- rotate gaps 90 degrees clockwise
    -- > , ((modm .|. controlMask, xK_h), sendMessage $ weakModifyGaps halveHor)  -- halve the left and right-hand gaps
    -- > , ((modm .|. controlMask, xK_d), sendMessage $ modifyGap (*2) L)         -- double the left-hand gap
    -- > , ((modm .|. controlMask, xK_s), sendMessage $ setGaps [(U,18), (R,23)]) -- reset the GapSpec
    -- > , ((modm .|. controlMask, xK_b), sendMessage $ setGap 30 D)              -- set the bottom gap to 30
    -- > ]
    -- >   where rotateGaps gs = zip (map (rotate . fst) gs) (map snd gs)
    -- >         rotate U = R
    -- >         rotate R = D
    -- >         rotate D = L
    -- >         rotate L = U
    -- >         halveHor d i | d `elem` [L, R] = i `div` 2
    -- >                      | otherwise       = i
    --
    -- If you want complete control over all gaps, you could include
    -- something like this in your keybindings, assuming in this case you
    -- are using 'XMonad.Util.EZConfig.mkKeymap' or
    -- 'XMonad.Util.EZConfig.additionalKeysP' from "XMonad.Util.EZConfig"
    -- for string keybinding specifications:
    --
    -- > ++
    -- > [ ("M-g " ++ f ++ " " ++ k, sendMessage $ m d)
    -- >     | (k, d) <- [("a",L), ("s",D), ("w",U), ("d",R)]
    -- >     , (f, m) <- [("v", ToggleGap), ("h", IncGap 10), ("f", DecGap 10)]
    -- > ]
    --
    -- Given the above keybinding definition, for example, you could type
    -- @M-g, v, a@ to toggle the top gap.
    --
    -- To configure gaps differently per-screen, use
    -- "XMonad.Layout.PerScreen" (coming soon).
    --
    -- __Warning__: If you also use the 'avoidStruts' layout modifier, it
    -- must come /before/ any of these modifiers. See the documentation of
    -- 'avoidStruts' for details.

    -- | A manual gap configuration.  Each side of the screen on which a
    --   gap is enabled is paired with a size in pixels.
    type GapSpec = [(Direction2D,Int)]

    -- | The gap state.  The first component is the configuration (which
    --   gaps are allowed, and their current size), the second is the gaps
    --   which are currently active.
    data Gaps a = Gaps GapSpec [Direction2D]
      deriving (Int -> Gaps a -> ShowS
    [Gaps a] -> ShowS
    Gaps a -> String
    (Int -> Gaps a -> ShowS)
    -> (Gaps a -> String) -> ([Gaps a] -> ShowS) -> Show (Gaps a)
    forall a. Int -> Gaps a -> ShowS
    forall a. [Gaps a] -> ShowS
    forall a. Gaps a -> String
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: forall a. Int -> Gaps a -> ShowS
    showsPrec :: Int -> Gaps a -> ShowS
    $cshow :: forall a. Gaps a -> String
    show :: Gaps a -> String
    $cshowList :: forall a. [Gaps a] -> ShowS
    showList :: [Gaps a] -> ShowS
    Show, ReadPrec [Gaps a]
    ReadPrec (Gaps a)
    Int -> ReadS (Gaps a)
    ReadS [Gaps a]
    (Int -> ReadS (Gaps a))
    -> ReadS [Gaps a]
    -> ReadPrec (Gaps a)
    -> ReadPrec [Gaps a]
    -> Read (Gaps a)
    forall a. ReadPrec [Gaps a]
    forall a. ReadPrec (Gaps a)
    forall a. Int -> ReadS (Gaps a)
    forall a. ReadS [Gaps a]
    forall a.
    (Int -> ReadS a)
    -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
    $creadsPrec :: forall a. Int -> ReadS (Gaps a)
    readsPrec :: Int -> ReadS (Gaps a)
    $creadList :: forall a. ReadS [Gaps a]
    readList :: ReadS [Gaps a]
    $creadPrec :: forall a. ReadPrec (Gaps a)
    readPrec :: ReadPrec (Gaps a)
    $creadListPrec :: forall a. ReadPrec [Gaps a]
    readListPrec :: ReadPrec [Gaps a]
    Read)

    -- | Messages which can be sent to a gap modifier.
    data GapMessage = ToggleGaps              -- ^ Toggle all gaps.
                    | ToggleGap  !Direction2D    -- ^ Toggle a single gap.
                    | IncGap !Int !Direction2D    -- ^ Increase a gap by a certain number of pixels.
                    | DecGap !Int !Direction2D    -- ^ Decrease a gap.
                    | ModifyGaps (GapSpec -> GapSpec) -- ^ Modify arbitrarily.

    instance Message GapMessage

    instance LayoutModifier Gaps a where
        modifyLayout :: forall (l :: * -> *).
    LayoutClass l a =>
    Gaps a
    -> Workspace String (l a) a
    -> Rectangle
    -> X ([(a, Rectangle)], Maybe (l a))
    modifyLayout Gaps a
    g Workspace String (l a) a
    w Rectangle
    r = Workspace String (l a) a
    -> Rectangle -> X ([(a, Rectangle)], Maybe (l a))
    forall (layout :: * -> *) a.
    LayoutClass layout a =>
    Workspace String (layout a) a
    -> Rectangle -> X ([(a, Rectangle)], Maybe (layout a))
    runLayout Workspace String (l a) a
    w (Gaps a -> Rectangle -> Rectangle
    forall a. Gaps a -> Rectangle -> Rectangle
    applyGaps Gaps a
    g Rectangle
    r)

        pureMess :: Gaps a -> SomeMessage -> Maybe (Gaps a)
    pureMess (Gaps GapSpec
    conf [Direction2D]
    cur) SomeMessage
    m
          | Just GapMessage
    ToggleGaps    <- SomeMessage -> Maybe GapMessage
    forall m. Message m => SomeMessage -> Maybe m
    fromMessage SomeMessage
    m
            = Gaps a -> Maybe (Gaps a)
    forall a. a -> Maybe a
    Just (Gaps a -> Maybe (Gaps a)) -> Gaps a -> Maybe (Gaps a)
    forall a b. (a -> b) -> a -> b
    $ GapSpec -> [Direction2D] -> Gaps a
    forall a. GapSpec -> [Direction2D] -> Gaps a
    Gaps GapSpec
    conf (GapSpec -> [Direction2D] -> [Direction2D]
    toggleGaps GapSpec
    conf [Direction2D]
    cur)
          | Just (ToggleGap Direction2D
    d) <- SomeMessage -> Maybe GapMessage
    forall m. Message m => SomeMessage -> Maybe m
    fromMessage SomeMessage
    m
            = Gaps a -> Maybe (Gaps a)
    forall a. a -> Maybe a
    Just (Gaps a -> Maybe (Gaps a)) -> Gaps a -> Maybe (Gaps a)
    forall a b. (a -> b) -> a -> b
    $ GapSpec -> [Direction2D] -> Gaps a
    forall a. GapSpec -> [Direction2D] -> Gaps a
    Gaps GapSpec
    conf (GapSpec -> [Direction2D] -> Direction2D -> [Direction2D]
    toggleGap GapSpec
    conf [Direction2D]
    cur Direction2D
    d)
          | Just (IncGap Int
    i Direction2D
    d)  <- SomeMessage -> Maybe GapMessage
    forall m. Message m => SomeMessage -> Maybe m
    fromMessage SomeMessage
    m
            = Gaps a -> Maybe (Gaps a)
    forall a. a -> Maybe a
    Just (Gaps a -> Maybe (Gaps a)) -> Gaps a -> Maybe (Gaps a)
    forall a b. (a -> b) -> a -> b
    $ GapSpec -> [Direction2D] -> Gaps a
    forall a. GapSpec -> [Direction2D] -> Gaps a
    Gaps (GapSpec -> GapSpec
    limit (GapSpec -> GapSpec) -> (GapSpec -> GapSpec) -> GapSpec -> GapSpec
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Int -> Int) -> Direction2D -> GapSpec -> GapSpec
    continuation (Int -> Int -> Int
    forall a. Num a => a -> a -> a
    +  Int
    i ) Direction2D
    d (GapSpec -> GapSpec) -> GapSpec -> GapSpec
    forall a b. (a -> b) -> a -> b
    $ GapSpec
    conf) [Direction2D]
    cur
          | Just (DecGap Int
    i Direction2D
    d)  <- SomeMessage -> Maybe GapMessage
    forall m. Message m => SomeMessage -> Maybe m
    fromMessage SomeMessage
    m
            = Gaps a -> Maybe (Gaps a)
    forall a. a -> Maybe a
    Just (Gaps a -> Maybe (Gaps a)) -> Gaps a -> Maybe (Gaps a)
    forall a b. (a -> b) -> a -> b
    $ GapSpec -> [Direction2D] -> Gaps a
    forall a. GapSpec -> [Direction2D] -> Gaps a
    Gaps (GapSpec -> GapSpec
    limit (GapSpec -> GapSpec) -> (GapSpec -> GapSpec) -> GapSpec -> GapSpec
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Int -> Int) -> Direction2D -> GapSpec -> GapSpec
    continuation (Int -> Int -> Int
    forall a. Num a => a -> a -> a
    +(-Int
    i)) Direction2D
    d (GapSpec -> GapSpec) -> GapSpec -> GapSpec
    forall a b. (a -> b) -> a -> b
    $ GapSpec
    conf) [Direction2D]
    cur
          | Just (ModifyGaps GapSpec -> GapSpec
    f) <- SomeMessage -> Maybe GapMessage
    forall m. Message m => SomeMessage -> Maybe m
    fromMessage SomeMessage
    m
            = Gaps a -> Maybe (Gaps a)
    forall a. a -> Maybe a
    Just (Gaps a -> Maybe (Gaps a)) -> Gaps a -> Maybe (Gaps a)
    forall a b. (a -> b) -> a -> b
    $ GapSpec -> [Direction2D] -> Gaps a
    forall a. GapSpec -> [Direction2D] -> Gaps a
    Gaps (GapSpec -> GapSpec
    limit (GapSpec -> GapSpec) -> (GapSpec -> GapSpec) -> GapSpec -> GapSpec
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . GapSpec -> GapSpec
    f (GapSpec -> GapSpec) -> GapSpec -> GapSpec
    forall a b. (a -> b) -> a -> b
    $ GapSpec
    conf) [Direction2D]
    cur
          | Bool
    otherwise = Maybe (Gaps a)
    forall a. Maybe a
    Nothing

    -- | Modifies gaps weakly, for convenience.
    weakModifyGaps :: (Direction2D -> Int -> Int) -> GapMessage
    weakModifyGaps :: (Direction2D -> Int -> Int) -> GapMessage
    weakModifyGaps = (GapSpec -> GapSpec) -> GapMessage
    ModifyGaps ((GapSpec -> GapSpec) -> GapMessage)
    -> ((Direction2D -> Int -> Int) -> GapSpec -> GapSpec)
    -> (Direction2D -> Int -> Int)
    -> GapMessage
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Direction2D -> Int -> Int) -> GapSpec -> GapSpec
    weakToStrong

    -- | Arbitrarily modify a single gap with the given function.
    modifyGap :: (Int -> Int) -> Direction2D -> GapMessage
    modifyGap :: (Int -> Int) -> Direction2D -> GapMessage
    modifyGap Int -> Int
    f Direction2D
    d = (GapSpec -> GapSpec) -> GapMessage
    ModifyGaps ((GapSpec -> GapSpec) -> GapMessage)
    -> (GapSpec -> GapSpec) -> GapMessage
    forall a b. (a -> b) -> a -> b
    $ (Int -> Int) -> Direction2D -> GapSpec -> GapSpec
    continuation Int -> Int
    f Direction2D
    d

    -- | Set the GapSpec.
    setGaps :: GapSpec -> GapMessage
    setGaps :: GapSpec -> GapMessage
    setGaps = (GapSpec -> GapSpec) -> GapMessage
    ModifyGaps ((GapSpec -> GapSpec) -> GapMessage)
    -> (GapSpec -> GapSpec -> GapSpec) -> GapSpec -> GapMessage
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . GapSpec -> GapSpec -> GapSpec
    forall a b. a -> b -> a
    const

    -- | Set a gap to the given value.
    setGap :: Int -> Direction2D -> GapMessage
    setGap :: Int -> Direction2D -> GapMessage
    setGap = (Int -> Int) -> Direction2D -> GapMessage
    modifyGap ((Int -> Int) -> Direction2D -> GapMessage)
    -> (Int -> Int -> Int) -> Int -> Direction2D -> GapMessage
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Int -> Int -> Int
    forall a b. a -> b -> a
    const

    -- | Imposes limits upon a GapSpec, ensuring gaps are at least 0. Not exposed.
    limit :: GapSpec -> GapSpec
    limit :: GapSpec -> GapSpec
    limit = (Direction2D -> Int -> Int) -> GapSpec -> GapSpec
    weakToStrong ((Direction2D -> Int -> Int) -> GapSpec -> GapSpec)
    -> (Direction2D -> Int -> Int) -> GapSpec -> GapSpec
    forall a b. (a -> b) -> a -> b
    $ \Direction2D
    _ -> Int -> Int -> Int
    forall a. Ord a => a -> a -> a
    max Int
    0

    -- | Takes a weak gaps-modifying function f and returns a GapSpec modifying
    -- function. Not exposed.
    weakToStrong :: (Direction2D -> Int -> Int) -> GapSpec -> GapSpec
    weakToStrong :: (Direction2D -> Int -> Int) -> GapSpec -> GapSpec
    weakToStrong Direction2D -> Int -> Int
    f GapSpec
    gs = [Direction2D] -> [Int] -> GapSpec
    forall a b. [a] -> [b] -> [(a, b)]
    zip (((Direction2D, Int) -> Direction2D) -> GapSpec -> [Direction2D]
    forall a b. (a -> b) -> [a] -> [b]
    map (Direction2D, Int) -> Direction2D
    forall a b. (a, b) -> a
    fst GapSpec
    gs) (((Direction2D, Int) -> Int) -> GapSpec -> [Int]
    forall a b. (a -> b) -> [a] -> [b]
    map ((Direction2D -> Int -> Int) -> (Direction2D, Int) -> Int
    forall a b c. (a -> b -> c) -> (a, b) -> c
    uncurry Direction2D -> Int -> Int
    f) GapSpec
    gs)

    -- | Given f as a definition for the behaviour of a gaps modifying function in
    -- one direction d, produces a continuation of the function to the other
    -- directions using the identity. Not exposed.
    continuation :: (Int -> Int) -> Direction2D -> GapSpec -> GapSpec
    continuation :: (Int -> Int) -> Direction2D -> GapSpec -> GapSpec
    continuation Int -> Int
    f Direction2D
    d1 = (Direction2D -> Int -> Int) -> GapSpec -> GapSpec
    weakToStrong Direction2D -> Int -> Int
    h
      where h :: Direction2D -> Int -> Int
    h Direction2D
    d2 | Direction2D
    d2 Direction2D -> Direction2D -> Bool
    forall a. Eq a => a -> a -> Bool
    == Direction2D
    d1  = Int -> Int
    f
                 | Bool
    otherwise = Int -> Int
    forall a. a -> a
    id

    applyGaps :: Gaps a -> Rectangle -> Rectangle
    applyGaps :: forall a. Gaps a -> Rectangle -> Rectangle
    applyGaps Gaps a
    gs Rectangle
    r = ((Direction2D, Int) -> Rectangle -> Rectangle)
    -> Rectangle -> GapSpec -> Rectangle
    forall a b. (a -> b -> b) -> b -> [a] -> b
    forall (t :: * -> *) a b.
    Foldable t =>
    (a -> b -> b) -> b -> t a -> b
    foldr (Direction2D, Int) -> Rectangle -> Rectangle
    forall {a}.
    Integral a =>
    (Direction2D, a) -> Rectangle -> Rectangle
    applyGap Rectangle
    r (Gaps a -> GapSpec
    forall a. Gaps a -> GapSpec
    activeGaps Gaps a
    gs)
      where
        applyGap :: (Direction2D, a) -> Rectangle -> Rectangle
    applyGap (Direction2D
    U,a
    z) (Rectangle Position
    x Position
    y Dimension
    w Dimension
    h) = Position -> Position -> Dimension -> Dimension -> Rectangle
    Rectangle Position
    x (Position
    y Position -> Position -> Position
    forall a. Num a => a -> a -> a
    + a -> Position
    forall a b. (Integral a, Num b) => a -> b
    fi a
    z) Dimension
    w (Dimension
    h Dimension -> Dimension -> Dimension
    forall a. Num a => a -> a -> a
    - a -> Dimension
    forall a b. (Integral a, Num b) => a -> b
    fi a
    z)
        applyGap (Direction2D
    D,a
    z) (Rectangle Position
    x Position
    y Dimension
    w Dimension
    h) = Position -> Position -> Dimension -> Dimension -> Rectangle
    Rectangle Position
    x Position
    y Dimension
    w (Dimension
    h Dimension -> Dimension -> Dimension
    forall a. Num a => a -> a -> a
    - a -> Dimension
    forall a b. (Integral a, Num b) => a -> b
    fi a
    z)
        applyGap (Direction2D
    L,a
    z) (Rectangle Position
    x Position
    y Dimension
    w Dimension
    h) = Position -> Position -> Dimension -> Dimension -> Rectangle
    Rectangle (Position
    x Position -> Position -> Position
    forall a. Num a => a -> a -> a
    + a -> Position
    forall a b. (Integral a, Num b) => a -> b
    fi a
    z) Position
    y (Dimension
    w Dimension -> Dimension -> Dimension
    forall a. Num a => a -> a -> a
    - a -> Dimension
    forall a b. (Integral a, Num b) => a -> b
    fi a
    z) Dimension
    h
        applyGap (Direction2D
    R,a
    z) (Rectangle Position
    x Position
    y Dimension
    w Dimension
    h) = Position -> Position -> Dimension -> Dimension -> Rectangle
    Rectangle Position
    x Position
    y (Dimension
    w Dimension -> Dimension -> Dimension
    forall a. Num a => a -> a -> a
    - a -> Dimension
    forall a b. (Integral a, Num b) => a -> b
    fi a
    z) Dimension
    h

    activeGaps :: Gaps a -> GapSpec
    activeGaps :: forall a. Gaps a -> GapSpec
    activeGaps (Gaps GapSpec
    conf [Direction2D]
    cur) = ((Direction2D, Int) -> Bool) -> GapSpec -> GapSpec
    forall a. (a -> Bool) -> [a] -> [a]
    filter ((Direction2D -> [Direction2D] -> Bool
    forall a. Eq a => a -> [a] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` [Direction2D]
    cur) (Direction2D -> Bool)
    -> ((Direction2D, Int) -> Direction2D)
    -> (Direction2D, Int)
    -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Direction2D, Int) -> Direction2D
    forall a b. (a, b) -> a
    fst) GapSpec
    conf

    toggleGaps :: GapSpec -> [Direction2D] -> [Direction2D]
    toggleGaps :: GapSpec -> [Direction2D] -> [Direction2D]
    toggleGaps GapSpec
    conf [] = ((Direction2D, Int) -> Direction2D) -> GapSpec -> [Direction2D]
    forall a b. (a -> b) -> [a] -> [b]
    map (Direction2D, Int) -> Direction2D
    forall a b. (a, b) -> a
    fst GapSpec
    conf
    toggleGaps GapSpec
    _    [Direction2D]
    _  = []

    toggleGap :: GapSpec -> [Direction2D] -> Direction2D -> [Direction2D]
    toggleGap :: GapSpec -> [Direction2D] -> Direction2D -> [Direction2D]
    toggleGap GapSpec
    conf [Direction2D]
    cur Direction2D
    d | Direction2D
    d Direction2D -> [Direction2D] -> Bool
    forall a. Eq a => a -> [a] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` [Direction2D]
    cur            = Direction2D -> [Direction2D] -> [Direction2D]
    forall a. Eq a => a -> [a] -> [a]
    delete Direction2D
    d [Direction2D]
    cur
                         | Direction2D
    d Direction2D -> [Direction2D] -> Bool
    forall a. Eq a => a -> [a] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` ((Direction2D, Int) -> Direction2D) -> GapSpec -> [Direction2D]
    forall a b. (a -> b) -> [a] -> [b]
    map (Direction2D, Int) -> Direction2D
    forall a b. (a, b) -> a
    fst GapSpec
    conf = Direction2D
    dDirection2D -> [Direction2D] -> [Direction2D]
    forall a. a -> [a] -> [a]
    :[Direction2D]
    cur
                         | Bool
    otherwise               = [Direction2D]
    cur

    -- | Add togglable manual gaps to a layout.
    gaps :: GapSpec   -- ^ The gaps to allow, paired with their initial sizes.
         -> l a       -- ^ The layout to modify.
         -> ModifiedLayout Gaps l a
    gaps :: forall (l :: * -> *) a. GapSpec -> l a -> ModifiedLayout Gaps l a
    gaps GapSpec
    g = Gaps a -> l a -> ModifiedLayout Gaps l a
    forall (m :: * -> *) (l :: * -> *) a.
    m a -> l a -> ModifiedLayout m l a
    ModifiedLayout (GapSpec -> [Direction2D] -> Gaps a
    forall a. GapSpec -> [Direction2D] -> Gaps a
    Gaps GapSpec
    g (((Direction2D, Int) -> Direction2D) -> GapSpec -> [Direction2D]
    forall a b. (a -> b) -> [a] -> [b]
    map (Direction2D, Int) -> Direction2D
    forall a b. (a, b) -> a
    fst GapSpec
    g))

    -- | Add togglable manual gaps to a layout, explicitly specifying the initial states.
    gaps' :: [((Direction2D,Int),Bool)] -- ^ The gaps to allow and their initial states.
          -> l a                        -- ^ The layout to modify.
          -> ModifiedLayout Gaps l a
    gaps' :: forall (l :: * -> *) a.
    [((Direction2D, Int), Bool)] -> l a -> ModifiedLayout Gaps l a
    gaps' [((Direction2D, Int), Bool)]
    g = Gaps a -> l a -> ModifiedLayout Gaps l a
    forall (m :: * -> *) (l :: * -> *) a.
    m a -> l a -> ModifiedLayout m l a
    ModifiedLayout (GapSpec -> [Direction2D] -> Gaps a
    forall a. GapSpec -> [Direction2D] -> Gaps a
    Gaps ((((Direction2D, Int), Bool) -> (Direction2D, Int))
    -> [((Direction2D, Int), Bool)] -> GapSpec
    forall a b. (a -> b) -> [a] -> [b]
    map ((Direction2D, Int), Bool) -> (Direction2D, Int)
    forall a b. (a, b) -> a
    fst [((Direction2D, Int), Bool)]
    g) [Direction2D
    d | ((Direction2D
    d,Int
    _),Bool
    v) <- [((Direction2D, Int), Bool)]
    g, Bool
    v])