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

    -----------------------------------------------------------------------------
    -- |
    -- Module      :  XMonad.Layout.Combo
    -- Description :  A layout that combines multiple layouts.
    -- Copyright   :  (c) David Roundy <droundy@darcs.net>
    -- License     :  BSD-style (see LICENSE)
    --
    -- Maintainer  :  none
    -- Stability   :  unstable
    -- Portability :  unportable
    --
    -- A layout that combines multiple layouts.
    --
    -----------------------------------------------------------------------------

    module XMonad.Layout.Combo (
                                -- * Usage
                                -- $usage
                                combineTwo,
                                CombineTwo
                               ) where

    import XMonad hiding (focus)
    import XMonad.Prelude (delete, fromMaybe, intersect, isJust, (\\))
    import XMonad.StackSet ( integrate', Workspace (..), Stack(..) )
    import XMonad.Layout.WindowNavigation ( MoveWindowToWindow(..) )
    import qualified XMonad.StackSet as W ( differentiate )

    -- $usage
    -- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@:
    --
    -- > import XMonad.Layout.Combo
    --
    -- and add something like
    --
    -- > combineTwo (TwoPane 0.03 0.5) (tabbed shrinkText def) (tabbed shrinkText def)
    --
    -- to your layouts.
    --
    -- For more detailed instructions on editing the layoutHook see:
    --
    -- "XMonad.Doc.Extending#Editing_the_layout_hook"
    --
    -- combineTwo is a new simple layout combinator. It allows the
    -- combination of two layouts using a third to split the screen
    -- between the two, but has the advantage of allowing you to
    -- dynamically adjust the layout, in terms of the number of windows in
    -- each sublayout. To do this, use "XMonad.Layout.WindowNavigation",
    -- and add the following key bindings (or something similar):
    --
    -- >    , ((modm .|. controlMask .|. shiftMask, xK_Right), sendMessage $ Move R)
    -- >    , ((modm .|. controlMask .|. shiftMask, xK_Left ), sendMessage $ Move L)
    -- >    , ((modm .|. controlMask .|. shiftMask, xK_Up   ), sendMessage $ Move U)
    -- >    , ((modm .|. controlMask .|. shiftMask, xK_Down ), sendMessage $ Move D)
    --
    -- For detailed instruction on editing the key binding see
    -- "XMonad.Doc.Extending#Editing_key_bindings".
    --
    -- These bindings will move a window into the sublayout that is
    -- up\/down\/left\/right of its current position.  Note that there is some
    -- weirdness in combineTwo, in that the mod-tab focus order is not very closely
    -- related to the layout order. This is because we're forced to keep track of
    -- the window positions separately, and this is ugly.  If you don't like this,
    -- lobby for hierarchical stacks in core xmonad or go reimplement the core of
    -- xmonad yourself.

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

    combineTwo :: (Read a, Eq a, LayoutClass super (), LayoutClass l1 a, LayoutClass l2 a) =>
                  super () -> l1 a -> l2 a -> CombineTwo (super ()) l1 l2 a
    combineTwo :: forall a (super :: * -> *) (l1 :: * -> *) (l2 :: * -> *).
    (Read a, Eq a, LayoutClass super (), LayoutClass l1 a,
     LayoutClass l2 a) =>
    super () -> l1 a -> l2 a -> CombineTwo (super ()) l1 l2 a
    combineTwo = [a]
    -> [a] -> super () -> l1 a -> l2 a -> CombineTwo (super ()) l1 l2 a
    forall l (l1 :: * -> *) (l2 :: * -> *) a.
    [a] -> [a] -> l -> l1 a -> l2 a -> CombineTwo l l1 l2 a
    C2 [] []

    instance (LayoutClass l (), LayoutClass l1 a, LayoutClass l2 a, Read a, Show a, Eq a, Typeable a)
        => LayoutClass (CombineTwo (l ()) l1 l2) a where
        runLayout :: Workspace String (CombineTwo (l ()) l1 l2 a) a
    -> Rectangle
    -> X ([(a, Rectangle)], Maybe (CombineTwo (l ()) l1 l2 a))
    runLayout (Workspace String
    _ (C2 [a]
    f [a]
    w2 l ()
    super l1 a
    l1 l2 a
    l2) Maybe (Stack a)
    s) Rectangle
    rinput = [a] -> X ([(a, Rectangle)], Maybe (CombineTwo (l ()) l1 l2 a))
    arrange (Maybe (Stack a) -> [a]
    forall a. Maybe (Stack a) -> [a]
    integrate' Maybe (Stack a)
    s)
            where arrange :: [a] -> X ([(a, Rectangle)], Maybe (CombineTwo (l ()) l1 l2 a))
    arrange [] = do l1 a
    l1' <- l1 a -> Maybe (l1 a) -> l1 a
    forall a. a -> Maybe a -> a
    fromMaybe l1 a
    l1 (Maybe (l1 a) -> l1 a) -> X (Maybe (l1 a)) -> X (l1 a)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> l1 a -> SomeMessage -> X (Maybe (l1 a))
    forall (layout :: * -> *) a.
    LayoutClass layout a =>
    layout a -> SomeMessage -> X (Maybe (layout a))
    handleMessage l1 a
    l1 (LayoutMessages -> SomeMessage
    forall a. Message a => a -> SomeMessage
    SomeMessage LayoutMessages
    ReleaseResources)
                                  l2 a
    l2' <- l2 a -> Maybe (l2 a) -> l2 a
    forall a. a -> Maybe a -> a
    fromMaybe l2 a
    l2 (Maybe (l2 a) -> l2 a) -> X (Maybe (l2 a)) -> X (l2 a)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> l2 a -> SomeMessage -> X (Maybe (l2 a))
    forall (layout :: * -> *) a.
    LayoutClass layout a =>
    layout a -> SomeMessage -> X (Maybe (layout a))
    handleMessage l2 a
    l2 (LayoutMessages -> SomeMessage
    forall a. Message a => a -> SomeMessage
    SomeMessage LayoutMessages
    ReleaseResources)
                                  l ()
    super' <- l () -> Maybe (l ()) -> l ()
    forall a. a -> Maybe a -> a
    fromMaybe l ()
    super (Maybe (l ()) -> l ()) -> X (Maybe (l ())) -> X (l ())
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$>
                                            l () -> SomeMessage -> X (Maybe (l ()))
    forall (layout :: * -> *) a.
    LayoutClass layout a =>
    layout a -> SomeMessage -> X (Maybe (layout a))
    handleMessage l ()
    super (LayoutMessages -> SomeMessage
    forall a. Message a => a -> SomeMessage
    SomeMessage LayoutMessages
    ReleaseResources)
                                  ([(a, Rectangle)], Maybe (CombineTwo (l ()) l1 l2 a))
    -> X ([(a, Rectangle)], Maybe (CombineTwo (l ()) l1 l2 a))
    forall a. a -> X a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ([], CombineTwo (l ()) l1 l2 a -> Maybe (CombineTwo (l ()) l1 l2 a)
    forall a. a -> Maybe a
    Just (CombineTwo (l ()) l1 l2 a -> Maybe (CombineTwo (l ()) l1 l2 a))
    -> CombineTwo (l ()) l1 l2 a -> Maybe (CombineTwo (l ()) l1 l2 a)
    forall a b. (a -> b) -> a -> b
    $ [a] -> [a] -> l () -> l1 a -> l2 a -> CombineTwo (l ()) l1 l2 a
    forall l (l1 :: * -> *) (l2 :: * -> *) a.
    [a] -> [a] -> l -> l1 a -> l2 a -> CombineTwo l l1 l2 a
    C2 [] [] l ()
    super' l1 a
    l1' l2 a
    l2')
                  arrange [a
    w] = do l1 a
    l1' <- l1 a -> Maybe (l1 a) -> l1 a
    forall a. a -> Maybe a -> a
    fromMaybe l1 a
    l1 (Maybe (l1 a) -> l1 a) -> X (Maybe (l1 a)) -> X (l1 a)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> l1 a -> SomeMessage -> X (Maybe (l1 a))
    forall (layout :: * -> *) a.
    LayoutClass layout a =>
    layout a -> SomeMessage -> X (Maybe (layout a))
    handleMessage l1 a
    l1 (LayoutMessages -> SomeMessage
    forall a. Message a => a -> SomeMessage
    SomeMessage LayoutMessages
    ReleaseResources)
                                   l2 a
    l2' <- l2 a -> Maybe (l2 a) -> l2 a
    forall a. a -> Maybe a -> a
    fromMaybe l2 a
    l2 (Maybe (l2 a) -> l2 a) -> X (Maybe (l2 a)) -> X (l2 a)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> l2 a -> SomeMessage -> X (Maybe (l2 a))
    forall (layout :: * -> *) a.
    LayoutClass layout a =>
    layout a -> SomeMessage -> X (Maybe (layout a))
    handleMessage l2 a
    l2 (LayoutMessages -> SomeMessage
    forall a. Message a => a -> SomeMessage
    SomeMessage LayoutMessages
    ReleaseResources)
                                   l ()
    super' <- l () -> Maybe (l ()) -> l ()
    forall a. a -> Maybe a -> a
    fromMaybe l ()
    super (Maybe (l ()) -> l ()) -> X (Maybe (l ())) -> X (l ())
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$>
                                             l () -> SomeMessage -> X (Maybe (l ()))
    forall (layout :: * -> *) a.
    LayoutClass layout a =>
    layout a -> SomeMessage -> X (Maybe (layout a))
    handleMessage l ()
    super (LayoutMessages -> SomeMessage
    forall a. Message a => a -> SomeMessage
    SomeMessage LayoutMessages
    ReleaseResources)
                                   ([(a, Rectangle)], Maybe (CombineTwo (l ()) l1 l2 a))
    -> X ([(a, Rectangle)], Maybe (CombineTwo (l ()) l1 l2 a))
    forall a. a -> X a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ([(a
    w,Rectangle
    rinput)], CombineTwo (l ()) l1 l2 a -> Maybe (CombineTwo (l ()) l1 l2 a)
    forall a. a -> Maybe a
    Just (CombineTwo (l ()) l1 l2 a -> Maybe (CombineTwo (l ()) l1 l2 a))
    -> CombineTwo (l ()) l1 l2 a -> Maybe (CombineTwo (l ()) l1 l2 a)
    forall a b. (a -> b) -> a -> b
    $ [a] -> [a] -> l () -> l1 a -> l2 a -> CombineTwo (l ()) l1 l2 a
    forall l (l1 :: * -> *) (l2 :: * -> *) a.
    [a] -> [a] -> l -> l1 a -> l2 a -> CombineTwo l l1 l2 a
    C2 [a
    w] [a
    w] l ()
    super' l1 a
    l1' l2 a
    l2')
                  arrange [a]
    origws =
                      do let w2' :: [a]
    w2' = case [a]
    origws [a] -> [a] -> [a]
    forall a. Eq a => [a] -> [a] -> [a]
    `intersect` [a]
    w2 of [] -> [[a] -> a
    forall a. HasCallStack => [a] -> a
    head [a]
    origws]
                                                                 [a
    x] -> [a
    x]
                                                                 [a]
    x -> case [a]
    origws [a] -> [a] -> [a]
    forall a. Eq a => [a] -> [a] -> [a]
    \\ [a]
    x of
                                                                      [] -> [a] -> [a]
    forall a. HasCallStack => [a] -> [a]
    init [a]
    x
                                                                      [a]
    _ -> [a]
    x
                             superstack :: Stack ()
    superstack = Stack { focus :: ()
    focus=(), up :: [()]
    up=[], down :: [()]
    down=[()] }
                             s1 :: Maybe (Stack a)
    s1 = [a] -> [a] -> Maybe (Stack a)
    forall q. Eq q => [q] -> [q] -> Maybe (Stack q)
    differentiate [a]
    f' ([a]
    origws [a] -> [a] -> [a]
    forall a. Eq a => [a] -> [a] -> [a]
    \\ [a]
    w2')
                             s2 :: Maybe (Stack a)
    s2 = [a] -> [a] -> Maybe (Stack a)
    forall q. Eq q => [q] -> [q] -> Maybe (Stack q)
    differentiate [a]
    f' [a]
    w2'
                             f' :: [a]
    f' = case Maybe (Stack a)
    s of (Just Stack a
    s') -> Stack a -> a
    forall a. Stack a -> a
    focus Stack a
    s'a -> [a] -> [a]
    forall a. a -> [a] -> [a]
    :a -> [a] -> [a]
    forall a. Eq a => a -> [a] -> [a]
    delete (Stack a -> a
    forall a. Stack a -> a
    focus Stack a
    s') [a]
    f
                                            Maybe (Stack a)
    Nothing -> [a]
    f
                         ([((),Rectangle
    r1),((),Rectangle
    r2)], Maybe (l ())
    msuper') <- Workspace String (l ()) ()
    -> Rectangle -> X ([((), Rectangle)], Maybe (l ()))
    forall (layout :: * -> *) a.
    LayoutClass layout a =>
    Workspace String (layout a) a
    -> Rectangle -> X ([(a, Rectangle)], Maybe (layout a))
    runLayout (String -> l () -> Maybe (Stack ()) -> Workspace String (l ()) ()
    forall i l a. i -> l -> Maybe (Stack a) -> Workspace i l a
    Workspace String
    "" l ()
    super (Stack () -> Maybe (Stack ())
    forall a. a -> Maybe a
    Just Stack ()
    superstack)) Rectangle
    rinput
                         ([(a, Rectangle)]
    wrs1, Maybe (l1 a)
    ml1') <- Workspace String (l1 a) a
    -> Rectangle -> X ([(a, Rectangle)], Maybe (l1 a))
    forall (layout :: * -> *) a.
    LayoutClass layout a =>
    Workspace String (layout a) a
    -> Rectangle -> X ([(a, Rectangle)], Maybe (layout a))
    runLayout (String -> l1 a -> Maybe (Stack a) -> Workspace String (l1 a) a
    forall i l a. i -> l -> Maybe (Stack a) -> Workspace i l a
    Workspace String
    "" l1 a
    l1 Maybe (Stack a)
    s1) Rectangle
    r1
                         ([(a, Rectangle)]
    wrs2, Maybe (l2 a)
    ml2') <- Workspace String (l2 a) a
    -> Rectangle -> X ([(a, Rectangle)], Maybe (l2 a))
    forall (layout :: * -> *) a.
    LayoutClass layout a =>
    Workspace String (layout a) a
    -> Rectangle -> X ([(a, Rectangle)], Maybe (layout a))
    runLayout (String -> l2 a -> Maybe (Stack a) -> Workspace String (l2 a) a
    forall i l a. i -> l -> Maybe (Stack a) -> Workspace i l a
    Workspace String
    "" l2 a
    l2 Maybe (Stack a)
    s2) Rectangle
    r2
                         ([(a, Rectangle)], Maybe (CombineTwo (l ()) l1 l2 a))
    -> X ([(a, Rectangle)], Maybe (CombineTwo (l ()) l1 l2 a))
    forall a. a -> X a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ([(a, Rectangle)]
    wrs1[(a, Rectangle)] -> [(a, Rectangle)] -> [(a, Rectangle)]
    forall a. [a] -> [a] -> [a]
    ++[(a, Rectangle)]
    wrs2, CombineTwo (l ()) l1 l2 a -> Maybe (CombineTwo (l ()) l1 l2 a)
    forall a. a -> Maybe a
    Just (CombineTwo (l ()) l1 l2 a -> Maybe (CombineTwo (l ()) l1 l2 a))
    -> CombineTwo (l ()) l1 l2 a -> Maybe (CombineTwo (l ()) l1 l2 a)
    forall a b. (a -> b) -> a -> b
    $ [a] -> [a] -> l () -> l1 a -> l2 a -> CombineTwo (l ()) l1 l2 a
    forall l (l1 :: * -> *) (l2 :: * -> *) a.
    [a] -> [a] -> l -> l1 a -> l2 a -> CombineTwo l l1 l2 a
    C2 [a]
    f' [a]
    w2'
                                         (l () -> Maybe (l ()) -> l ()
    forall a. a -> Maybe a -> a
    fromMaybe l ()
    super Maybe (l ())
    msuper') (l1 a -> Maybe (l1 a) -> l1 a
    forall a. a -> Maybe a -> a
    fromMaybe l1 a
    l1 Maybe (l1 a)
    ml1') (l2 a -> Maybe (l2 a) -> l2 a
    forall a. a -> Maybe a -> a
    fromMaybe l2 a
    l2 Maybe (l2 a)
    ml2'))
        handleMessage :: CombineTwo (l ()) l1 l2 a
    -> SomeMessage -> X (Maybe (CombineTwo (l ()) l1 l2 a))
    handleMessage (C2 [a]
    f [a]
    ws2 l ()
    super l1 a
    l1 l2 a
    l2) SomeMessage
    m
            | Just (MoveWindowToWindow a
    w1 a
    w2) <- SomeMessage -> Maybe (MoveWindowToWindow a)
    forall m. Message m => SomeMessage -> Maybe m
    fromMessage SomeMessage
    m,
              a
    w1 a -> [a] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `notElem` [a]
    ws2,
              a
    w2 a -> [a] -> Bool
    forall a. Eq a => a -> [a] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` [a]
    ws2 = do l1 a
    l1' <- l1 a -> Maybe (l1 a) -> l1 a
    forall a. a -> Maybe a -> a
    fromMaybe l1 a
    l1 (Maybe (l1 a) -> l1 a) -> X (Maybe (l1 a)) -> X (l1 a)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> l1 a -> SomeMessage -> X (Maybe (l1 a))
    forall (layout :: * -> *) a.
    LayoutClass layout a =>
    layout a -> SomeMessage -> X (Maybe (layout a))
    handleMessage l1 a
    l1 SomeMessage
    m
                                 l2 a
    l2' <- l2 a -> Maybe (l2 a) -> l2 a
    forall a. a -> Maybe a -> a
    fromMaybe l2 a
    l2 (Maybe (l2 a) -> l2 a) -> X (Maybe (l2 a)) -> X (l2 a)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> l2 a -> SomeMessage -> X (Maybe (l2 a))
    forall (layout :: * -> *) a.
    LayoutClass layout a =>
    layout a -> SomeMessage -> X (Maybe (layout a))
    handleMessage l2 a
    l2 SomeMessage
    m
                                 Maybe (CombineTwo (l ()) l1 l2 a)
    -> X (Maybe (CombineTwo (l ()) l1 l2 a))
    forall a. a -> X a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Maybe (CombineTwo (l ()) l1 l2 a)
     -> X (Maybe (CombineTwo (l ()) l1 l2 a)))
    -> Maybe (CombineTwo (l ()) l1 l2 a)
    -> X (Maybe (CombineTwo (l ()) l1 l2 a))
    forall a b. (a -> b) -> a -> b
    $ CombineTwo (l ()) l1 l2 a -> Maybe (CombineTwo (l ()) l1 l2 a)
    forall a. a -> Maybe a
    Just (CombineTwo (l ()) l1 l2 a -> Maybe (CombineTwo (l ()) l1 l2 a))
    -> CombineTwo (l ()) l1 l2 a -> Maybe (CombineTwo (l ()) l1 l2 a)
    forall a b. (a -> b) -> a -> b
    $ [a] -> [a] -> l () -> l1 a -> l2 a -> CombineTwo (l ()) l1 l2 a
    forall l (l1 :: * -> *) (l2 :: * -> *) a.
    [a] -> [a] -> l -> l1 a -> l2 a -> CombineTwo l l1 l2 a
    C2 [a]
    f (a
    w1a -> [a] -> [a]
    forall a. a -> [a] -> [a]
    :[a]
    ws2) l ()
    super l1 a
    l1' l2 a
    l2'
            | Just (MoveWindowToWindow a
    w1 a
    w2) <- SomeMessage -> Maybe (MoveWindowToWindow a)
    forall m. Message m => SomeMessage -> Maybe m
    fromMessage SomeMessage
    m,
              a
    w1 a -> [a] -> Bool
    forall a. Eq a => a -> [a] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` [a]
    ws2,
              a
    w2 a -> [a] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `notElem` [a]
    ws2 = do l1 a
    l1' <- l1 a -> Maybe (l1 a) -> l1 a
    forall a. a -> Maybe a -> a
    fromMaybe l1 a
    l1 (Maybe (l1 a) -> l1 a) -> X (Maybe (l1 a)) -> X (l1 a)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> l1 a -> SomeMessage -> X (Maybe (l1 a))
    forall (layout :: * -> *) a.
    LayoutClass layout a =>
    layout a -> SomeMessage -> X (Maybe (layout a))
    handleMessage l1 a
    l1 SomeMessage
    m
                                    l2 a
    l2' <- l2 a -> Maybe (l2 a) -> l2 a
    forall a. a -> Maybe a -> a
    fromMaybe l2 a
    l2 (Maybe (l2 a) -> l2 a) -> X (Maybe (l2 a)) -> X (l2 a)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> l2 a -> SomeMessage -> X (Maybe (l2 a))
    forall (layout :: * -> *) a.
    LayoutClass layout a =>
    layout a -> SomeMessage -> X (Maybe (layout a))
    handleMessage l2 a
    l2 SomeMessage
    m
                                    let ws2' :: [a]
    ws2' = case a -> [a] -> [a]
    forall a. Eq a => a -> [a] -> [a]
    delete a
    w1 [a]
    ws2 of [] -> [a
    w2]
                                                                     [a]
    x -> [a]
    x
                                    Maybe (CombineTwo (l ()) l1 l2 a)
    -> X (Maybe (CombineTwo (l ()) l1 l2 a))
    forall a. a -> X a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Maybe (CombineTwo (l ()) l1 l2 a)
     -> X (Maybe (CombineTwo (l ()) l1 l2 a)))
    -> Maybe (CombineTwo (l ()) l1 l2 a)
    -> X (Maybe (CombineTwo (l ()) l1 l2 a))
    forall a b. (a -> b) -> a -> b
    $ CombineTwo (l ()) l1 l2 a -> Maybe (CombineTwo (l ()) l1 l2 a)
    forall a. a -> Maybe a
    Just (CombineTwo (l ()) l1 l2 a -> Maybe (CombineTwo (l ()) l1 l2 a))
    -> CombineTwo (l ()) l1 l2 a -> Maybe (CombineTwo (l ()) l1 l2 a)
    forall a b. (a -> b) -> a -> b
    $ [a] -> [a] -> l () -> l1 a -> l2 a -> CombineTwo (l ()) l1 l2 a
    forall l (l1 :: * -> *) (l2 :: * -> *) a.
    [a] -> [a] -> l -> l1 a -> l2 a -> CombineTwo l l1 l2 a
    C2 [a]
    f [a]
    ws2' l ()
    super l1 a
    l1' l2 a
    l2'
            | Bool
    otherwise = do Maybe [l1 a]
    ml1' <- SomeMessage -> [l1 a] -> X (Maybe [l1 a])
    forall (l :: * -> *) b.
    LayoutClass l b =>
    SomeMessage -> [l b] -> X (Maybe [l b])
    broadcastPrivate SomeMessage
    m [l1 a
    l1]
                             Maybe [l2 a]
    ml2' <- SomeMessage -> [l2 a] -> X (Maybe [l2 a])
    forall (l :: * -> *) b.
    LayoutClass l b =>
    SomeMessage -> [l b] -> X (Maybe [l b])
    broadcastPrivate SomeMessage
    m [l2 a
    l2]
                             Maybe [l ()]
    msuper' <- SomeMessage -> [l ()] -> X (Maybe [l ()])
    forall (l :: * -> *) b.
    LayoutClass l b =>
    SomeMessage -> [l b] -> X (Maybe [l b])
    broadcastPrivate SomeMessage
    m [l ()
    super]
                             if Maybe [l ()] -> Bool
    forall a. Maybe a -> Bool
    isJust Maybe [l ()]
    msuper' Bool -> Bool -> Bool
    || Maybe [l1 a] -> Bool
    forall a. Maybe a -> Bool
    isJust Maybe [l1 a]
    ml1' Bool -> Bool -> Bool
    || Maybe [l2 a] -> Bool
    forall a. Maybe a -> Bool
    isJust Maybe [l2 a]
    ml2'
                                then Maybe (CombineTwo (l ()) l1 l2 a)
    -> X (Maybe (CombineTwo (l ()) l1 l2 a))
    forall a. a -> X a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Maybe (CombineTwo (l ()) l1 l2 a)
     -> X (Maybe (CombineTwo (l ()) l1 l2 a)))
    -> Maybe (CombineTwo (l ()) l1 l2 a)
    -> X (Maybe (CombineTwo (l ()) l1 l2 a))
    forall a b. (a -> b) -> a -> b
    $ CombineTwo (l ()) l1 l2 a -> Maybe (CombineTwo (l ()) l1 l2 a)
    forall a. a -> Maybe a
    Just (CombineTwo (l ()) l1 l2 a -> Maybe (CombineTwo (l ()) l1 l2 a))
    -> CombineTwo (l ()) l1 l2 a -> Maybe (CombineTwo (l ()) l1 l2 a)
    forall a b. (a -> b) -> a -> b
    $ [a] -> [a] -> l () -> l1 a -> l2 a -> CombineTwo (l ()) l1 l2 a
    forall l (l1 :: * -> *) (l2 :: * -> *) a.
    [a] -> [a] -> l -> l1 a -> l2 a -> CombineTwo l l1 l2 a
    C2 [a]
    f [a]
    ws2
                                                     (l () -> ([l ()] -> l ()) -> Maybe [l ()] -> l ()
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe l ()
    super [l ()] -> l ()
    forall a. HasCallStack => [a] -> a
    head Maybe [l ()]
    msuper')
                                                     (l1 a -> ([l1 a] -> l1 a) -> Maybe [l1 a] -> l1 a
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe l1 a
    l1 [l1 a] -> l1 a
    forall a. HasCallStack => [a] -> a
    head Maybe [l1 a]
    ml1')
                                                     (l2 a -> ([l2 a] -> l2 a) -> Maybe [l2 a] -> l2 a
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe l2 a
    l2 [l2 a] -> l2 a
    forall a. HasCallStack => [a] -> a
    head Maybe [l2 a]
    ml2')
                                else Maybe (CombineTwo (l ()) l1 l2 a)
    -> X (Maybe (CombineTwo (l ()) l1 l2 a))
    forall a. a -> X a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe (CombineTwo (l ()) l1 l2 a)
    forall a. Maybe a
    Nothing
        description :: CombineTwo (l ()) l1 l2 a -> String
    description (C2 [a]
    _ [a]
    _ l ()
    super l1 a
    l1 l2 a
    l2) = String
    "combining "String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ l1 a -> String
    forall (layout :: * -> *) a.
    LayoutClass layout a =>
    layout a -> String
    description l1 a
    l1 String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++String
    " and "String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++
                                           l2 a -> String
    forall (layout :: * -> *) a.
    LayoutClass layout a =>
    layout a -> String
    description l2 a
    l2 String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++String
    " with "String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ l () -> String
    forall (layout :: * -> *) a.
    LayoutClass layout a =>
    layout a -> String
    description l ()
    super

    differentiate :: Eq q => [q] -> [q] -> Maybe (Stack q)
    differentiate :: forall q. Eq q => [q] -> [q] -> Maybe (Stack q)
    differentiate (q
    z:[q]
    zs) [q]
    xs | q
    z q -> [q] -> Bool
    forall a. Eq a => a -> [a] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` [q]
    xs = Stack q -> Maybe (Stack q)
    forall a. a -> Maybe a
    Just (Stack q -> Maybe (Stack q)) -> Stack q -> Maybe (Stack q)
    forall a b. (a -> b) -> a -> b
    $ Stack { focus :: q
    focus=q
    z
                                                         , up :: [q]
    up = [q] -> [q]
    forall a. [a] -> [a]
    reverse ([q] -> [q]) -> [q] -> [q]
    forall a b. (a -> b) -> a -> b
    $ (q -> Bool) -> [q] -> [q]
    forall a. (a -> Bool) -> [a] -> [a]
    takeWhile (q -> q -> Bool
    forall a. Eq a => a -> a -> Bool
    /=q
    z) [q]
    xs
                                                         , down :: [q]
    down = [q] -> [q]
    forall a. HasCallStack => [a] -> [a]
    tail ([q] -> [q]) -> [q] -> [q]
    forall a b. (a -> b) -> a -> b
    $ (q -> Bool) -> [q] -> [q]
    forall a. (a -> Bool) -> [a] -> [a]
    dropWhile (q -> q -> Bool
    forall a. Eq a => a -> a -> Bool
    /=q
    z) [q]
    xs }
                            | Bool
    otherwise = [q] -> [q] -> Maybe (Stack q)
    forall q. Eq q => [q] -> [q] -> Maybe (Stack q)
    differentiate [q]
    zs [q]
    xs
    differentiate [] [q]
    xs = [q] -> Maybe (Stack q)
    forall a. [a] -> Maybe (Stack a)
    W.differentiate [q]
    xs

    broadcastPrivate :: LayoutClass l b => SomeMessage -> [l b] -> X (Maybe [l b])
    broadcastPrivate :: forall (l :: * -> *) b.
    LayoutClass l b =>
    SomeMessage -> [l b] -> X (Maybe [l b])
    broadcastPrivate SomeMessage
    a [l b]
    ol = do [Maybe (l b)]
    nml <- (l b -> X (Maybe (l b))) -> [l b] -> X [Maybe (l b)]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
    mapM l b -> X (Maybe (l b))
    forall {layout :: * -> *} {a}.
    LayoutClass layout a =>
    layout a -> X (Maybe (layout a))
    f [l b]
    ol
                               if (Maybe (l b) -> Bool) -> [Maybe (l b)] -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    any Maybe (l b) -> Bool
    forall a. Maybe a -> Bool
    isJust [Maybe (l b)]
    nml
                                  then Maybe [l b] -> X (Maybe [l b])
    forall a. a -> X a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Maybe [l b] -> X (Maybe [l b])) -> Maybe [l b] -> X (Maybe [l b])
    forall a b. (a -> b) -> a -> b
    $ [l b] -> Maybe [l b]
    forall a. a -> Maybe a
    Just ([l b] -> Maybe [l b]) -> [l b] -> Maybe [l b]
    forall a b. (a -> b) -> a -> b
    $ (l b -> Maybe (l b) -> l b) -> [l b] -> [Maybe (l b)] -> [l b]
    forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
    zipWith (l b -> (l b -> l b) -> Maybe (l b) -> l b
    forall b a. b -> (a -> b) -> Maybe a -> b
    `maybe` l b -> l b
    forall a. a -> a
    id) [l b]
    ol [Maybe (l b)]
    nml
                                  else Maybe [l b] -> X (Maybe [l b])
    forall a. a -> X a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe [l b]
    forall a. Maybe a
    Nothing
        where f :: layout a -> X (Maybe (layout a))
    f layout a
    l = layout a -> SomeMessage -> X (Maybe (layout a))
    forall (layout :: * -> *) a.
    LayoutClass layout a =>
    layout a -> SomeMessage -> X (Maybe (layout a))
    handleMessage layout a
    l SomeMessage
    a X (Maybe (layout a))
    -> X (Maybe (layout a)) -> X (Maybe (layout a))
    forall a. X a -> X a -> X a
    `catchX` Maybe (layout a) -> X (Maybe (layout a))
    forall a. a -> X a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe (layout a)
    forall a. Maybe a
    Nothing