    {-# LANGUAGE MultiParamTypeClasses #-}
    {-# LANGUAGE PatternGuards, FlexibleContexts, FlexibleInstances #-}
    -----------------------------------------------------------------------------
    -- |
    -- Module      :  XMonad.Layout.BoringWindows
    -- Description :  Mark windows as boring.
    -- Copyright   :  (c) 2008  David Roundy <droundy@darcs.net>
    -- License     :  BSD3-style (see LICENSE)
    --
    -- Maintainer  :  Adam Vogt <vogt.adam@gmail.com>
    -- Stability   :  unstable
    -- Portability :  unportable
    --
    -- BoringWindows is an extension to allow windows to be marked boring
    --
    -----------------------------------------------------------------------------

    module XMonad.Layout.BoringWindows (
                                       -- * Usage
                                       -- $usage
                                       boringWindows, boringAuto,
                                       markBoring, markBoringEverywhere,
                                       clearBoring, focusUp, focusDown,
                                       focusMaster, swapUp, swapDown,
                                       siftUp, siftDown,

                                       UpdateBoring(UpdateBoring),
                                       BoringMessage(Replace,Merge),
                                       BoringWindows()

                                       -- * Tips
                                       -- ** variant of 'Full'
                                       -- $simplest
                                      ) where

    import XMonad.Layout.LayoutModifier(ModifiedLayout(..),
                                        LayoutModifier(handleMessOrMaybeModifyIt, redoLayout))
    import XMonad(LayoutClass, Message, X, fromMessage,
                  broadcastMessage, sendMessage, windows, withFocused, Window)
    import XMonad.Prelude
    import XMonad.Util.Stack (reverseS)
    import qualified Data.List.NonEmpty as NE
    import qualified Data.Map as M
    import qualified XMonad.StackSet as W

    -- $usage
    -- You can use this module with the following in your
    -- @xmonad.hs@:
    --
    -- > import XMonad.Layout.BoringWindows
    --
    -- Then edit your @layoutHook@ by adding the layout modifier:
    --
    -- > myLayout = boringWindows (Full ||| etc..)
    -- > main = xmonad def { layoutHook = myLayout }
    --
    -- Then to your keybindings, add:
    --
    -- > , ((modm, xK_j), focusUp)
    -- > , ((modm, xK_k), focusDown)
    -- > , ((modm, xK_m), focusMaster)
    --
    -- For more detailed instructions on editing the layoutHook see
    -- <https://xmonad.org/TUTORIAL.html#customizing-xmonad the tutorial> and
    -- "XMonad.Doc.Extending#Editing_the_layout_hook".

    data BoringMessage = FocusUp | FocusDown | FocusMaster | IsBoring Window | ClearBoring
                         | Replace String [Window]
                         | Merge String [Window]
                         | SwapUp
                         | SwapDown
                         | SiftUp
                         | SiftDown
                         deriving ( ReadPrec [BoringMessage]
    ReadPrec BoringMessage
    Int -> ReadS BoringMessage
    ReadS [BoringMessage]
    (Int -> ReadS BoringMessage)
    -> ReadS [BoringMessage]
    -> ReadPrec BoringMessage
    -> ReadPrec [BoringMessage]
    -> Read BoringMessage
    forall a.
    (Int -> ReadS a)
    -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
    $creadsPrec :: Int -> ReadS BoringMessage
    readsPrec :: Int -> ReadS BoringMessage
    $creadList :: ReadS [BoringMessage]
    readList :: ReadS [BoringMessage]
    $creadPrec :: ReadPrec BoringMessage
    readPrec :: ReadPrec BoringMessage
    $creadListPrec :: ReadPrec [BoringMessage]
    readListPrec :: ReadPrec [BoringMessage]
    Read, Int -> BoringMessage -> ShowS
    [BoringMessage] -> ShowS
    BoringMessage -> String
    (Int -> BoringMessage -> ShowS)
    -> (BoringMessage -> String)
    -> ([BoringMessage] -> ShowS)
    -> Show BoringMessage
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> BoringMessage -> ShowS
    showsPrec :: Int -> BoringMessage -> ShowS
    $cshow :: BoringMessage -> String
    show :: BoringMessage -> String
    $cshowList :: [BoringMessage] -> ShowS
    showList :: [BoringMessage] -> ShowS
    Show )

    instance Message BoringMessage

    -- | UpdateBoring is sent before attempting to view another boring window, so
    -- that layouts have a chance to mark boring windows.
    data UpdateBoring = UpdateBoring
    instance Message UpdateBoring

    markBoring, clearBoring, focusUp, focusDown, focusMaster, swapUp, swapDown, siftUp, siftDown :: X ()
    markBoring :: X ()
    markBoring = (Window -> X ()) -> X ()
    withFocused (BoringMessage -> X ()
    forall a. Message a => a -> X ()
    sendMessage (BoringMessage -> X ())
    -> (Window -> BoringMessage) -> Window -> X ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Window -> BoringMessage
    IsBoring)
    clearBoring :: X ()
    clearBoring = BoringMessage -> X ()
    forall a. Message a => a -> X ()
    sendMessage BoringMessage
    ClearBoring
    focusUp :: X ()
    focusUp = UpdateBoring -> X ()
    forall a. Message a => a -> X ()
    sendMessage UpdateBoring
    UpdateBoring X () -> X () -> X ()
    forall a b. X a -> X b -> X b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BoringMessage -> X ()
    forall a. Message a => a -> X ()
    sendMessage BoringMessage
    FocusUp
    focusDown :: X ()
    focusDown = UpdateBoring -> X ()
    forall a. Message a => a -> X ()
    sendMessage UpdateBoring
    UpdateBoring X () -> X () -> X ()
    forall a b. X a -> X b -> X b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BoringMessage -> X ()
    forall a. Message a => a -> X ()
    sendMessage BoringMessage
    FocusDown
    focusMaster :: X ()
    focusMaster = UpdateBoring -> X ()
    forall a. Message a => a -> X ()
    sendMessage UpdateBoring
    UpdateBoring X () -> X () -> X ()
    forall a b. X a -> X b -> X b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BoringMessage -> X ()
    forall a. Message a => a -> X ()
    sendMessage BoringMessage
    FocusMaster
    swapUp :: X ()
    swapUp = UpdateBoring -> X ()
    forall a. Message a => a -> X ()
    sendMessage UpdateBoring
    UpdateBoring X () -> X () -> X ()
    forall a b. X a -> X b -> X b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BoringMessage -> X ()
    forall a. Message a => a -> X ()
    sendMessage BoringMessage
    SwapUp
    swapDown :: X ()
    swapDown = UpdateBoring -> X ()
    forall a. Message a => a -> X ()
    sendMessage UpdateBoring
    UpdateBoring X () -> X () -> X ()
    forall a b. X a -> X b -> X b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BoringMessage -> X ()
    forall a. Message a => a -> X ()
    sendMessage BoringMessage
    SwapDown
    siftUp :: X ()
    siftUp = UpdateBoring -> X ()
    forall a. Message a => a -> X ()
    sendMessage UpdateBoring
    UpdateBoring X () -> X () -> X ()
    forall a b. X a -> X b -> X b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BoringMessage -> X ()
    forall a. Message a => a -> X ()
    sendMessage BoringMessage
    SiftUp
    siftDown :: X ()
    siftDown = UpdateBoring -> X ()
    forall a. Message a => a -> X ()
    sendMessage UpdateBoring
    UpdateBoring X () -> X () -> X ()
    forall a b. X a -> X b -> X b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> BoringMessage -> X ()
    forall a. Message a => a -> X ()
    sendMessage BoringMessage
    SiftDown

    -- | Mark current focused window boring for all layouts.
    -- This is useful in combination with the "XMonad.Actions.CopyWindow" module.
    markBoringEverywhere :: X ()
    markBoringEverywhere :: X ()
    markBoringEverywhere = (Window -> X ()) -> X ()
    withFocused (BoringMessage -> X ()
    forall a. Message a => a -> X ()
    broadcastMessage (BoringMessage -> X ())
    -> (Window -> BoringMessage) -> Window -> X ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Window -> BoringMessage
    IsBoring)

    data BoringWindows a = BoringWindows
        { forall a. BoringWindows a -> Map String [a]
    namedBoring :: M.Map String [a] -- ^ store borings with a specific source
        , forall a. BoringWindows a -> [a]
    chosenBoring :: [a]             -- ^ user-chosen borings
        , forall a. BoringWindows a -> Maybe [a]
    hiddenBoring :: Maybe [a]       -- ^ maybe mark hidden windows
        } deriving (Int -> BoringWindows a -> ShowS
    [BoringWindows a] -> ShowS
    BoringWindows a -> String
    (Int -> BoringWindows a -> ShowS)
    -> (BoringWindows a -> String)
    -> ([BoringWindows a] -> ShowS)
    -> Show (BoringWindows a)
    forall a. Show a => Int -> BoringWindows a -> ShowS
    forall a. Show a => [BoringWindows a] -> ShowS
    forall a. Show a => BoringWindows a -> String
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: forall a. Show a => Int -> BoringWindows a -> ShowS
    showsPrec :: Int -> BoringWindows a -> ShowS
    $cshow :: forall a. Show a => BoringWindows a -> String
    show :: BoringWindows a -> String
    $cshowList :: forall a. Show a => [BoringWindows a] -> ShowS
    showList :: [BoringWindows a] -> ShowS
    Show,ReadPrec [BoringWindows a]
    ReadPrec (BoringWindows a)
    Int -> ReadS (BoringWindows a)
    ReadS [BoringWindows a]
    (Int -> ReadS (BoringWindows a))
    -> ReadS [BoringWindows a]
    -> ReadPrec (BoringWindows a)
    -> ReadPrec [BoringWindows a]
    -> Read (BoringWindows a)
    forall a. Read a => ReadPrec [BoringWindows a]
    forall a. Read a => ReadPrec (BoringWindows a)
    forall a. Read a => Int -> ReadS (BoringWindows a)
    forall a. Read a => ReadS [BoringWindows a]
    forall a.
    (Int -> ReadS a)
    -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
    $creadsPrec :: forall a. Read a => Int -> ReadS (BoringWindows a)
    readsPrec :: Int -> ReadS (BoringWindows a)
    $creadList :: forall a. Read a => ReadS [BoringWindows a]
    readList :: ReadS [BoringWindows a]
    $creadPrec :: forall a. Read a => ReadPrec (BoringWindows a)
    readPrec :: ReadPrec (BoringWindows a)
    $creadListPrec :: forall a. Read a => ReadPrec [BoringWindows a]
    readListPrec :: ReadPrec [BoringWindows a]
    Read)

    boringWindows :: (LayoutClass l a, Eq a) => l a -> ModifiedLayout BoringWindows l a
    boringWindows :: forall (l :: * -> *) a.
    (LayoutClass l a, Eq a) =>
    l a -> ModifiedLayout BoringWindows l a
    boringWindows = BoringWindows a -> l a -> ModifiedLayout BoringWindows l a
    forall (m :: * -> *) (l :: * -> *) a.
    m a -> l a -> ModifiedLayout m l a
    ModifiedLayout (Map String [a] -> [a] -> Maybe [a] -> BoringWindows a
    forall a. Map String [a] -> [a] -> Maybe [a] -> BoringWindows a
    BoringWindows Map String [a]
    forall k a. Map k a
    M.empty [] Maybe [a]
    forall a. Maybe a
    Nothing)

    -- | Mark windows that are not given rectangles as boring
    boringAuto :: (LayoutClass l a, Eq a) => l a -> ModifiedLayout BoringWindows l a
    boringAuto :: forall (l :: * -> *) a.
    (LayoutClass l a, Eq a) =>
    l a -> ModifiedLayout BoringWindows l a
    boringAuto = BoringWindows a -> l a -> ModifiedLayout BoringWindows l a
    forall (m :: * -> *) (l :: * -> *) a.
    m a -> l a -> ModifiedLayout m l a
    ModifiedLayout (Map String [a] -> [a] -> Maybe [a] -> BoringWindows a
    forall a. Map String [a] -> [a] -> Maybe [a] -> BoringWindows a
    BoringWindows Map String [a]
    forall k a. Map k a
    M.empty [] ([a] -> Maybe [a]
    forall a. a -> Maybe a
    Just []))

    instance LayoutModifier BoringWindows Window where
        redoLayout :: BoringWindows Window
    -> Rectangle
    -> Maybe (Stack Window)
    -> [(Window, Rectangle)]
    -> X ([(Window, Rectangle)], Maybe (BoringWindows Window))
    redoLayout b :: BoringWindows Window
    b@BoringWindows{ hiddenBoring :: forall a. BoringWindows a -> Maybe [a]
    hiddenBoring = Maybe [Window]
    bs } Rectangle
    _r Maybe (Stack Window)
    mst [(Window, Rectangle)]
    arrs = do
            let bs' :: [Window]
    bs' = Maybe (Stack Window) -> [Window]
    forall a. Maybe (Stack a) -> [a]
    W.integrate' Maybe (Stack Window)
    mst [Window] -> [Window] -> [Window]
    forall a. Eq a => [a] -> [a] -> [a]
    \\ ((Window, Rectangle) -> Window)
    -> [(Window, Rectangle)] -> [Window]
    forall a b. (a -> b) -> [a] -> [b]
    map (Window, Rectangle) -> Window
    forall a b. (a, b) -> a
    fst [(Window, Rectangle)]
    arrs
            ([(Window, Rectangle)], Maybe (BoringWindows Window))
    -> X ([(Window, Rectangle)], Maybe (BoringWindows Window))
    forall a. a -> X a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ([(Window, Rectangle)]
    arrs, BoringWindows Window -> Maybe (BoringWindows Window)
    forall a. a -> Maybe a
    Just (BoringWindows Window -> Maybe (BoringWindows Window))
    -> BoringWindows Window -> Maybe (BoringWindows Window)
    forall a b. (a -> b) -> a -> b
    $ BoringWindows Window
    b { hiddenBoring = bs' <$ bs } )

        handleMessOrMaybeModifyIt :: BoringWindows Window
    -> SomeMessage
    -> X (Maybe (Either (BoringWindows Window) SomeMessage))
    handleMessOrMaybeModifyIt bst :: BoringWindows Window
    bst@(BoringWindows Map String [Window]
    nbs [Window]
    cbs Maybe [Window]
    lbs) SomeMessage
    m
            | Just (Replace String
    k [Window]
    ws) <- SomeMessage -> Maybe BoringMessage
    forall m. Message m => SomeMessage -> Maybe m
    fromMessage SomeMessage
    m
            , [Window] -> Maybe [Window]
    forall a. a -> Maybe a
    Just [Window]
    ws Maybe [Window] -> Maybe [Window] -> Bool
    forall a. Eq a => a -> a -> Bool
    /= String -> Map String [Window] -> Maybe [Window]
    forall k a. Ord k => k -> Map k a -> Maybe a
    M.lookup String
    k Map String [Window]
    nbs =
                let nnb :: Map String [Window]
    nnb = if [Window] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [Window]
    ws then String -> Map String [Window] -> Map String [Window]
    forall k a. Ord k => k -> Map k a -> Map k a
    M.delete String
    k Map String [Window]
    nbs
                              else String -> [Window] -> Map String [Window] -> Map String [Window]
    forall k a. Ord k => k -> a -> Map k a -> Map k a
    M.insert String
    k [Window]
    ws Map String [Window]
    nbs
                in BoringWindows Window
    -> X (Maybe (Either (BoringWindows Window) SomeMessage))
    forall {a} {b}. a -> X (Maybe (Either a b))
    rjl BoringWindows Window
    bst { namedBoring = nnb }
            | Just (Merge String
    k [Window]
    ws) <- SomeMessage -> Maybe BoringMessage
    forall m. Message m => SomeMessage -> Maybe m
    fromMessage SomeMessage
    m
            , Bool -> ([Window] -> Bool) -> Maybe [Window] -> Bool
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe Bool
    True (Bool -> Bool
    not (Bool -> Bool) -> ([Window] -> Bool) -> [Window] -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Window] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null ([Window] -> Bool) -> ([Window] -> [Window]) -> [Window] -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ([Window]
    ws [Window] -> [Window] -> [Window]
    forall a. Eq a => [a] -> [a] -> [a]
    \\)) (String -> Map String [Window] -> Maybe [Window]
    forall k a. Ord k => k -> Map k a -> Maybe a
    M.lookup String
    k Map String [Window]
    nbs) =
                BoringWindows Window
    -> X (Maybe (Either (BoringWindows Window) SomeMessage))
    forall {a} {b}. a -> X (Maybe (Either a b))
    rjl BoringWindows Window
    bst { namedBoring = M.insertWith union k ws nbs }
            | Just (IsBoring Window
    w) <- SomeMessage -> Maybe BoringMessage
    forall m. Message m => SomeMessage -> Maybe m
    fromMessage SomeMessage
    m , Window
    w Window -> [Window] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `notElem` [Window]
    cbs =
                BoringWindows Window
    -> X (Maybe (Either (BoringWindows Window) SomeMessage))
    forall {a} {b}. a -> X (Maybe (Either a b))
    rjl BoringWindows Window
    bst { chosenBoring = w:cbs }
            | Just BoringMessage
    ClearBoring <- SomeMessage -> Maybe BoringMessage
    forall m. Message m => SomeMessage -> Maybe m
    fromMessage SomeMessage
    m, Bool -> Bool
    not ([Window] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [Window]
    cbs) =
                BoringWindows Window
    -> X (Maybe (Either (BoringWindows Window) SomeMessage))
    forall {a} {b}. a -> X (Maybe (Either a b))
    rjl BoringWindows Window
    bst { namedBoring = M.empty, chosenBoring = []}
            | Just BoringMessage
    FocusUp <- SomeMessage -> Maybe BoringMessage
    forall m. Message m => SomeMessage -> Maybe m
    fromMessage SomeMessage
    m =
                                do (WindowSet -> WindowSet) -> X ()
    windows ((WindowSet -> WindowSet) -> X ())
    -> (WindowSet -> WindowSet) -> X ()
    forall a b. (a -> b) -> a -> b
    $ (Stack Window -> Stack Window) -> WindowSet -> WindowSet
    forall a i l s sd.
    (Stack a -> Stack a) -> StackSet i l a s sd -> StackSet i l a s sd
    W.modify' ((Stack Window -> Stack Window) -> WindowSet -> WindowSet)
    -> (Stack Window -> Stack Window) -> WindowSet -> WindowSet
    forall a b. (a -> b) -> a -> b
    $ (Stack Window -> Stack Window) -> Stack Window -> Stack Window
    skipBoring Stack Window -> Stack Window
    forall a. Stack a -> Stack a
    W.focusUp'
                                   Maybe (Either (BoringWindows Window) SomeMessage)
    -> X (Maybe (Either (BoringWindows Window) SomeMessage))
    forall a. a -> X a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe (Either (BoringWindows Window) SomeMessage)
    forall a. Maybe a
    Nothing
            | Just BoringMessage
    FocusDown <- SomeMessage -> Maybe BoringMessage
    forall m. Message m => SomeMessage -> Maybe m
    fromMessage SomeMessage
    m =
                                do (WindowSet -> WindowSet) -> X ()
    windows ((WindowSet -> WindowSet) -> X ())
    -> (WindowSet -> WindowSet) -> X ()
    forall a b. (a -> b) -> a -> b
    $ (Stack Window -> Stack Window) -> WindowSet -> WindowSet
    forall a i l s sd.
    (Stack a -> Stack a) -> StackSet i l a s sd -> StackSet i l a s sd
    W.modify' ((Stack Window -> Stack Window) -> WindowSet -> WindowSet)
    -> (Stack Window -> Stack Window) -> WindowSet -> WindowSet
    forall a b. (a -> b) -> a -> b
    $ (Stack Window -> Stack Window) -> Stack Window -> Stack Window
    skipBoring Stack Window -> Stack Window
    forall a. Stack a -> Stack a
    W.focusDown'
                                   Maybe (Either (BoringWindows Window) SomeMessage)
    -> X (Maybe (Either (BoringWindows Window) SomeMessage))
    forall a. a -> X a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe (Either (BoringWindows Window) SomeMessage)
    forall a. Maybe a
    Nothing
            | Just BoringMessage
    FocusMaster <- SomeMessage -> Maybe BoringMessage
    forall m. Message m => SomeMessage -> Maybe m
    fromMessage SomeMessage
    m =
                                do (WindowSet -> WindowSet) -> X ()
    windows ((WindowSet -> WindowSet) -> X ())
    -> (WindowSet -> WindowSet) -> X ()
    forall a b. (a -> b) -> a -> b
    $ (Stack Window -> Stack Window) -> WindowSet -> WindowSet
    forall a i l s sd.
    (Stack a -> Stack a) -> StackSet i l a s sd -> StackSet i l a s sd
    W.modify'
                                                ((Stack Window -> Stack Window) -> WindowSet -> WindowSet)
    -> (Stack Window -> Stack Window) -> WindowSet -> WindowSet
    forall a b. (a -> b) -> a -> b
    $ (Stack Window -> Stack Window) -> Stack Window -> Stack Window
    skipBoring Stack Window -> Stack Window
    forall a. Stack a -> Stack a
    W.focusDown' -- wiggle focus to make sure
                                                (Stack Window -> Stack Window)
    -> (Stack Window -> Stack Window) -> Stack Window -> Stack Window
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Stack Window -> Stack Window) -> Stack Window -> Stack Window
    skipBoring Stack Window -> Stack Window
    forall a. Stack a -> Stack a
    W.focusUp'   -- no boring window gets the focus
                                                (Stack Window -> Stack Window)
    -> (Stack Window -> Stack Window) -> Stack Window -> Stack Window
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Stack Window -> Stack Window
    forall a. Stack a -> Stack a
    focusMaster'
                                   Maybe (Either (BoringWindows Window) SomeMessage)
    -> X (Maybe (Either (BoringWindows Window) SomeMessage))
    forall a. a -> X a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe (Either (BoringWindows Window) SomeMessage)
    forall a. Maybe a
    Nothing
            | Just BoringMessage
    SwapUp <- SomeMessage -> Maybe BoringMessage
    forall m. Message m => SomeMessage -> Maybe m
    fromMessage SomeMessage
    m =
                                do (WindowSet -> WindowSet) -> X ()
    windows ((WindowSet -> WindowSet) -> X ())
    -> (WindowSet -> WindowSet) -> X ()
    forall a b. (a -> b) -> a -> b
    $ (Stack Window -> Stack Window) -> WindowSet -> WindowSet
    forall a i l s sd.
    (Stack a -> Stack a) -> StackSet i l a s sd -> StackSet i l a s sd
    W.modify' Stack Window -> Stack Window
    skipBoringSwapUp
                                   Maybe (Either (BoringWindows Window) SomeMessage)
    -> X (Maybe (Either (BoringWindows Window) SomeMessage))
    forall a. a -> X a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe (Either (BoringWindows Window) SomeMessage)
    forall a. Maybe a
    Nothing
            | Just BoringMessage
    SwapDown <- SomeMessage -> Maybe BoringMessage
    forall m. Message m => SomeMessage -> Maybe m
    fromMessage SomeMessage
    m =
                                do (WindowSet -> WindowSet) -> X ()
    windows ((WindowSet -> WindowSet) -> X ())
    -> (WindowSet -> WindowSet) -> X ()
    forall a b. (a -> b) -> a -> b
    $ (Stack Window -> Stack Window) -> WindowSet -> WindowSet
    forall a i l s sd.
    (Stack a -> Stack a) -> StackSet i l a s sd -> StackSet i l a s sd
    W.modify' (Stack Window -> Stack Window
    forall a. Stack a -> Stack a
    reverseS (Stack Window -> Stack Window)
    -> (Stack Window -> Stack Window) -> Stack Window -> Stack Window
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Stack Window -> Stack Window
    skipBoringSwapUp (Stack Window -> Stack Window)
    -> (Stack Window -> Stack Window) -> Stack Window -> Stack Window
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Stack Window -> Stack Window
    forall a. Stack a -> Stack a
    reverseS)
                                   Maybe (Either (BoringWindows Window) SomeMessage)
    -> X (Maybe (Either (BoringWindows Window) SomeMessage))
    forall a. a -> X a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe (Either (BoringWindows Window) SomeMessage)
    forall a. Maybe a
    Nothing
            | Just BoringMessage
    SiftUp <- SomeMessage -> Maybe BoringMessage
    forall m. Message m => SomeMessage -> Maybe m
    fromMessage SomeMessage
    m =
                                do (WindowSet -> WindowSet) -> X ()
    windows ((WindowSet -> WindowSet) -> X ())
    -> (WindowSet -> WindowSet) -> X ()
    forall a b. (a -> b) -> a -> b
    $ (Stack Window -> Stack Window) -> WindowSet -> WindowSet
    forall a i l s sd.
    (Stack a -> Stack a) -> StackSet i l a s sd -> StackSet i l a s sd
    W.modify' ([Window] -> Stack Window -> Stack Window
    forall a. Eq a => [a] -> Stack a -> Stack a
    siftUpSkipping [Window]
    bs)
                                   Maybe (Either (BoringWindows Window) SomeMessage)
    -> X (Maybe (Either (BoringWindows Window) SomeMessage))
    forall a. a -> X a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe (Either (BoringWindows Window) SomeMessage)
    forall a. Maybe a
    Nothing
            | Just BoringMessage
    SiftDown <- SomeMessage -> Maybe BoringMessage
    forall m. Message m => SomeMessage -> Maybe m
    fromMessage SomeMessage
    m =
                                do (WindowSet -> WindowSet) -> X ()
    windows ((WindowSet -> WindowSet) -> X ())
    -> (WindowSet -> WindowSet) -> X ()
    forall a b. (a -> b) -> a -> b
    $ (Stack Window -> Stack Window) -> WindowSet -> WindowSet
    forall a i l s sd.
    (Stack a -> Stack a) -> StackSet i l a s sd -> StackSet i l a s sd
    W.modify' (Stack Window -> Stack Window
    forall a. Stack a -> Stack a
    reverseS (Stack Window -> Stack Window)
    -> (Stack Window -> Stack Window) -> Stack Window -> Stack Window
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Window] -> Stack Window -> Stack Window
    forall a. Eq a => [a] -> Stack a -> Stack a
    siftUpSkipping [Window]
    bs (Stack Window -> Stack Window)
    -> (Stack Window -> Stack Window) -> Stack Window -> Stack Window
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Stack Window -> Stack Window
    forall a. Stack a -> Stack a
    reverseS)
                                   Maybe (Either (BoringWindows Window) SomeMessage)
    -> X (Maybe (Either (BoringWindows Window) SomeMessage))
    forall a. a -> X a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe (Either (BoringWindows Window) SomeMessage)
    forall a. Maybe a
    Nothing
            where skipBoring :: (Stack Window -> Stack Window) -> Stack Window -> Stack Window
    skipBoring = (Stack Window -> Bool)
    -> (Stack Window -> Stack Window) -> Stack Window -> Stack Window
    forall {a}.
    (Stack a -> Bool) -> (Stack a -> Stack a) -> Stack a -> Stack a
    skipBoring' ((Window -> [Window] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `notElem` [Window]
    bs) (Window -> Bool)
    -> (Stack Window -> Window) -> Stack Window -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Stack Window -> Window
    forall a. Stack a -> a
    W.focus)
                  skipBoringSwapUp :: Stack Window -> Stack Window
    skipBoringSwapUp = (Stack Window -> Bool)
    -> (Stack Window -> Stack Window) -> Stack Window -> Stack Window
    forall {a}.
    (Stack a -> Bool) -> (Stack a -> Stack a) -> Stack a -> Stack a
    skipBoring'
                                       (Bool -> (Window -> Bool) -> Maybe Window -> Bool
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe Bool
    True (Window -> [Window] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `notElem` [Window]
    bs) (Maybe Window -> Bool)
    -> (Stack Window -> Maybe Window) -> Stack Window -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Window] -> Maybe Window
    forall a. [a] -> Maybe a
    listToMaybe ([Window] -> Maybe Window)
    -> (Stack Window -> [Window]) -> Stack Window -> Maybe Window
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Stack Window -> [Window]
    forall a. Stack a -> [a]
    W.down)
                                       Stack Window -> Stack Window
    forall a. Stack a -> Stack a
    swapUp'
                  skipBoring' :: (Stack a -> Bool) -> (Stack a -> Stack a) -> Stack a -> Stack a
    skipBoring' Stack a -> Bool
    p Stack a -> Stack a
    f Stack a
    st = Stack a -> Maybe (Stack a) -> Stack a
    forall a. a -> Maybe a -> a
    fromMaybe Stack a
    st
                                       (Maybe (Stack a) -> Stack a) -> Maybe (Stack a) -> Stack a
    forall a b. (a -> b) -> a -> b
    $ (Stack a -> Bool) -> [Stack a] -> Maybe (Stack a)
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
    find Stack a -> Bool
    p
                                       ([Stack a] -> Maybe (Stack a)) -> [Stack a] -> Maybe (Stack a)
    forall a b. (a -> b) -> a -> b
    $ Int -> [Stack a] -> [Stack a]
    forall a. Int -> [a] -> [a]
    drop Int
    1
                                       ([Stack a] -> [Stack a]) -> [Stack a] -> [Stack a]
    forall a b. (a -> b) -> a -> b
    $ Int -> [Stack a] -> [Stack a]
    forall a. Int -> [a] -> [a]
    take ([a] -> Int
    forall a. [a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length ([a] -> Int) -> [a] -> Int
    forall a b. (a -> b) -> a -> b
    $ Stack a -> [a]
    forall a. Stack a -> [a]
    W.integrate Stack a
    st)
                                       ([Stack a] -> [Stack a]) -> [Stack a] -> [Stack a]
    forall a b. (a -> b) -> a -> b
    $ (Stack a -> Stack a) -> Stack a -> [Stack a]
    forall a. (a -> a) -> a -> [a]
    iterate Stack a -> Stack a
    f Stack a
    st
                  bs :: [Window]
    bs = [[Window]] -> [Window]
    forall (t :: * -> *) a. Foldable t => t [a] -> [a]
    concat ([[Window]] -> [Window]) -> [[Window]] -> [Window]
    forall a b. (a -> b) -> a -> b
    $ [Window]
    cbs[Window] -> [[Window]] -> [[Window]]
    forall a. a -> [a] -> [a]
    :Maybe [Window] -> [[Window]]
    forall a. Maybe a -> [a]
    maybeToList Maybe [Window]
    lbs [[Window]] -> [[Window]] -> [[Window]]
    forall a. [a] -> [a] -> [a]
    ++ Map String [Window] -> [[Window]]
    forall k a. Map k a -> [a]
    M.elems Map String [Window]
    nbs
                  rjl :: a -> X (Maybe (Either a b))
    rjl = Maybe (Either a b) -> X (Maybe (Either a b))
    forall a. a -> X a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Maybe (Either a b) -> X (Maybe (Either a b)))
    -> (a -> Maybe (Either a b)) -> a -> X (Maybe (Either a b))
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Either a b -> Maybe (Either a b)
    forall a. a -> Maybe a
    Just (Either a b -> Maybe (Either a b))
    -> (a -> Either a b) -> a -> Maybe (Either a b)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> Either a b
    forall a b. a -> Either a b
    Left
        handleMessOrMaybeModifyIt BoringWindows Window
    _ SomeMessage
    _ = Maybe (Either (BoringWindows Window) SomeMessage)
    -> X (Maybe (Either (BoringWindows Window) SomeMessage))
    forall a. a -> X a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe (Either (BoringWindows Window) SomeMessage)
    forall a. Maybe a
    Nothing

    -- | Variant of 'focusMaster' that works on a
    -- 'Stack' rather than an entire 'StackSet'.
    focusMaster' :: W.Stack a -> W.Stack a
    focusMaster' :: forall a. Stack a -> Stack a
    focusMaster' c :: Stack a
    c@(W.Stack a
    _ [] [a]
    _) = Stack a
    c
    focusMaster' (W.Stack a
    t (a
    l:[a]
    ls) [a]
    rs) = a -> [a] -> [a] -> Stack a
    forall a. a -> [a] -> [a] -> Stack a
    W.Stack a
    x [] ([a]
    xs [a] -> [a] -> [a]
    forall a. [a] -> [a] -> [a]
    ++ a
    t a -> [a] -> [a]
    forall a. a -> [a] -> [a]
    : [a]
    rs) where (a
    x :| [a]
    xs) = NonEmpty a -> NonEmpty a
    forall a. NonEmpty a -> NonEmpty a
    NE.reverse (a
    l a -> [a] -> NonEmpty a
    forall a. a -> [a] -> NonEmpty a
    :| [a]
    ls)

    swapUp' :: W.Stack a -> W.Stack a
    swapUp' :: forall a. Stack a -> Stack a
    swapUp' (W.Stack a
    t (a
    l:[a]
    ls) [a]
    rs) = a -> [a] -> [a] -> Stack a
    forall a. a -> [a] -> [a] -> Stack a
    W.Stack a
    t [a]
    ls (a
    la -> [a] -> [a]
    forall a. a -> [a] -> [a]
    :[a]
    rs)
    swapUp' (W.Stack a
    t []     [a]
    rs) = a -> [a] -> [a] -> Stack a
    forall a. a -> [a] -> [a] -> Stack a
    W.Stack a
    t ([a] -> [a]
    forall a. [a] -> [a]
    reverse [a]
    rs) []

    siftUpSkipping :: Eq a => [a] -> W.Stack a -> W.Stack a
    siftUpSkipping :: forall a. Eq a => [a] -> Stack a -> Stack a
    siftUpSkipping [a]
    bs (W.Stack a
    t [a]
    ls [a]
    rs)
      | ([a]
    skips, a
    l:[a]
    ls') <- ([a], [a])
    spanLeft  = a -> [a] -> [a] -> Stack a
    forall a. a -> [a] -> [a] -> Stack a
    W.Stack a
    t [a]
    ls' ([a] -> [a]
    forall a. [a] -> [a]
    reverse [a]
    skips [a] -> [a] -> [a]
    forall a. [a] -> [a] -> [a]
    ++ a
    l a -> [a] -> [a]
    forall a. a -> [a] -> [a]
    : [a]
    rs)
      | ([a]
    skips, a
    r:[a]
    rs') <- ([a], [a])
    spanRight = a -> [a] -> [a] -> Stack a
    forall a. a -> [a] -> [a] -> Stack a
    W.Stack a
    t ([a]
    rs' [a] -> [a] -> [a]
    forall a. [a] -> [a] -> [a]
    ++ a
    r a -> [a] -> [a]
    forall a. a -> [a] -> [a]
    : [a]
    ls) ([a] -> [a]
    forall a. [a] -> [a]
    reverse [a]
    skips)
      | Bool
    otherwise                   = a -> [a] -> [a] -> Stack a
    forall a. a -> [a] -> [a] -> Stack a
    W.Stack a
    t [a]
    ls [a]
    rs
      where
        spanLeft :: ([a], [a])
    spanLeft  = (a -> Bool) -> [a] -> ([a], [a])
    forall a. (a -> Bool) -> [a] -> ([a], [a])
    span (a -> [a] -> Bool
    forall a. Eq a => a -> [a] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` [a]
    bs) [a]
    ls
        spanRight :: ([a], [a])
    spanRight = (a -> Bool) -> [a] -> ([a], [a])
    forall a. (a -> Bool) -> [a] -> ([a], [a])
    span (a -> [a] -> Bool
    forall a. Eq a => a -> [a] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` [a]
    bs) ([a] -> [a]
    forall a. [a] -> [a]
    reverse [a]
    rs)

    {- $simplest

    An alternative to 'Full' is "XMonad.Layout.Simplest".  Less windows are
    ignored by 'focusUp' and 'focusDown'. This may be helpful when you want windows
    to be uninteresting by some other layout modifier (ex.
    "XMonad.Layout.Minimize")

    -}