    -----------------------------------------------------------------------------
    -- |
    -- Module      :  XMonad.Actions.CycleWS
    -- Description :  Cycle through workspaces.
    -- Copyright   :  (c) Joachim Breitner <mail@joachim-breitner.de>,
    --                    Nelson Elhage <nelhage@mit.edu> (`toggleWS' function)
    -- License     :  BSD3-style (see LICENSE)
    --
    -- Maintainer  :  Joachim Breitner <mail@joachim-breitner.de>
    -- Stability   :  unstable
    -- Portability :  unportable
    --
    -- Provides bindings to cycle forward or backward through the list of
    -- workspaces, to move windows between workspaces, and to cycle
    -- between screens.  More general combinators provide ways to cycle
    -- through workspaces in various orders, to only cycle through some
    -- subset of workspaces, and to cycle by more than one workspace at a
    -- time.
    --
    -- Note that this module now subsumes the functionality of the former
    -- @XMonad.Actions.RotView@.  Former users of @rotView@ can simply replace
    -- @rotView True@ with @moveTo Next (Not emptyWS)@, and so on.
    --
    -- If you want to exactly replicate the action of @rotView@ (cycling
    -- through workspace in order lexicographically by tag, instead of in
    -- the order specified in the config), it can be implemented as:
    --
    -- > rotView b  = do t <- findWorkspace getSortByTag (bToDir b) (Not emptyWS) 1
    -- >                 windows . greedyView $ t
    -- >   where bToDir True  = Next
    -- >         bToDir False = Prev
    --
    -----------------------------------------------------------------------------

    module XMonad.Actions.CycleWS (
                                    -- * Usage
                                    -- $usage

                                    -- * Moving between workspaces
                                    -- $moving

                                    nextWS
                                  , prevWS
                                  , shiftToNext
                                  , shiftToPrev

                                    -- * Toggling the previous workspace
                                    -- $toggling
                                  , toggleWS
                                  , toggleWS'
                                  , toggleOrView

                                    -- * Moving between screens (xinerama)

                                  , nextScreen
                                  , prevScreen
                                  , shiftNextScreen
                                  , shiftPrevScreen
                                  , swapNextScreen
                                  , swapPrevScreen

                                    -- * Moving between workspaces, take two!
                                    -- $taketwo

                                  , Direction1D(..)
                                  , WSType(..)
                                  , emptyWS
                                  , hiddenWS
                                  , anyWS
                                  , wsTagGroup
                                  , ignoringWSs

                                  , shiftTo
                                  , moveTo
                                  , doTo

                                    -- * The mother-combinator

                                  , findWorkspace
                                  , toggleOrDoSkip
                                  , skipTags

                                  , screenBy

                                 ) where

    import XMonad.Prelude (find, findIndex, isJust, isNothing, liftM2)
    import XMonad hiding (workspaces)
    import qualified XMonad.Hooks.WorkspaceHistory as WH
    import XMonad.StackSet hiding (filter)
    import XMonad.Util.Types
    import XMonad.Util.WorkspaceCompare

    -- $usage
    -- You can use this module with the following in your @xmonad.hs@ file:
    --
    -- > import XMonad.Actions.CycleWS
    -- >
    -- > -- a basic CycleWS setup
    -- >
    -- >   , ((modm,               xK_Down),  nextWS)
    -- >   , ((modm,               xK_Up),    prevWS)
    -- >   , ((modm .|. shiftMask, xK_Down),  shiftToNext)
    -- >   , ((modm .|. shiftMask, xK_Up),    shiftToPrev)
    -- >   , ((modm,               xK_Right), nextScreen)
    -- >   , ((modm,               xK_Left),  prevScreen)
    -- >   , ((modm .|. shiftMask, xK_Right), shiftNextScreen)
    -- >   , ((modm .|. shiftMask, xK_Left),  shiftPrevScreen)
    -- >   , ((modm,               xK_z),     toggleWS)
    --
    -- If you want to follow the moved window, you can use both actions:
    --
    -- >   , ((modm .|. shiftMask, xK_Down), shiftToNext >> nextWS)
    -- >   , ((modm .|. shiftMask, xK_Up),   shiftToPrev >> prevWS)
    --
    -- You can also get fancier with 'moveTo', 'shiftTo', and 'findWorkspace'.
    -- For example:
    --
    -- >   , ((modm     , xK_f), moveTo Next emptyWS)  -- find a free workspace
    -- >   , ((modm .|. controlMask, xK_Right),        -- a crazy keybinding!
    -- >         do t <- findWorkspace getSortByXineramaRule Next (Not emptyWS) 2
    -- >            windows . view $ t                                         )
    --
    -- For detailed instructions on editing your key bindings, see
    -- <https://xmonad.org/TUTORIAL.html#customizing-xmonad the tutorial>.
    --
    -- When using the toggle functions, in order to ensure that the workspace
    -- to which you switch is the previously viewed workspace, use the
    -- 'logHook' in "XMonad.Hooks.WorkspaceHistory".

    {- $moving

    The following commands for moving the view and windows between
    workspaces are somewhat inflexible, but are very simple and probably
    Do The Right Thing for most users.

    All of the commands in this section cycle through workspaces in the
    order in which they are given in your config.

    -}

    -- | Switch to the next workspace.
    nextWS :: X ()
    nextWS :: X ()
    nextWS = Int -> X ()
    switchWorkspace Int
    1

    -- | Switch to the previous workspace.
    prevWS :: X ()
    prevWS :: X ()
    prevWS = Int -> X ()
    switchWorkspace (-Int
    1)

    -- | Move the focused window to the next workspace.
    shiftToNext :: X ()
    shiftToNext :: X ()
    shiftToNext = Int -> X ()
    shiftBy Int
    1

    -- | Move the focused window to the previous workspace.
    shiftToPrev :: X ()
    shiftToPrev :: X ()
    shiftToPrev = Int -> X ()
    shiftBy (-Int
    1)

    -- $toggling

    -- | Toggle to the workspace displayed previously.
    toggleWS :: X ()
    toggleWS :: X ()
    toggleWS = [WorkspaceId] -> X ()
    toggleWS' []

    -- | Toggle to the previous workspace while excluding some workspaces.
    --
    -- > -- Ignore the scratchpad workspace while toggling:
    -- > ("M-b", toggleWS' ["NSP"])
    toggleWS' :: [WorkspaceId] -> X ()
    toggleWS' :: [WorkspaceId] -> X ()
    toggleWS' [WorkspaceId]
    skips = [WorkspaceId] -> X (Maybe WorkspaceId)
    lastViewedHiddenExcept [WorkspaceId]
    skips X (Maybe WorkspaceId) -> (Maybe WorkspaceId -> X ()) -> X ()
    forall a b. X a -> (a -> X b) -> X b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= (Maybe WorkspaceId -> (WorkspaceId -> X ()) -> X ())
    -> (WorkspaceId -> X ()) -> Maybe WorkspaceId -> X ()
    forall a b c. (a -> b -> c) -> b -> a -> c
    flip Maybe WorkspaceId -> (WorkspaceId -> X ()) -> X ()
    forall (m :: * -> *) a. Monad m => Maybe a -> (a -> m ()) -> m ()
    whenJust ((WindowSet -> WindowSet) -> X ()
    windows ((WindowSet -> WindowSet) -> X ())
    -> (WorkspaceId -> WindowSet -> WindowSet) -> WorkspaceId -> X ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . WorkspaceId -> WindowSet -> WindowSet
    forall s i l a sd.
    (Eq s, Eq i) =>
    i -> StackSet i l a s sd -> StackSet i l a s sd
    view)

    -- | 'XMonad.StackSet.greedyView' a workspace, or if already there, view
    -- the previously displayed workspace ala weechat. Change @greedyView@ to
    -- @toggleOrView@ in your workspace bindings as in the 'XMonad.StackSet.view'
    -- faq at <http://haskell.org/haskellwiki/Xmonad/Frequently_asked_questions>.
    -- For more flexibility see 'toggleOrDoSkip'.
    toggleOrView :: WorkspaceId -> X ()
    toggleOrView :: WorkspaceId -> X ()
    toggleOrView = [WorkspaceId]
    -> (WorkspaceId -> WindowSet -> WindowSet) -> WorkspaceId -> X ()
    toggleOrDoSkip [] WorkspaceId -> WindowSet -> WindowSet
    forall s i l a sd.
    (Eq s, Eq i) =>
    i -> StackSet i l a s sd -> StackSet i l a s sd
    greedyView

    -- | Allows ignoring listed workspace tags (such as scratchpad's \"NSP\"), and
    -- running other actions such as view, shift, etc.  For example:
    --
    -- > import qualified XMonad.StackSet as W
    -- > import XMonad.Actions.CycleWS
    -- >
    -- > -- toggleOrView for people who prefer view to greedyView
    -- > toggleOrView' = toggleOrDoSkip [] W.view
    -- >
    -- > -- toggleOrView ignoring scratchpad and named scratchpad workspace
    -- > toggleOrViewNoSP = toggleOrDoSkip ["NSP"] W.greedyView
    toggleOrDoSkip :: [WorkspaceId] -> (WorkspaceId -> WindowSet -> WindowSet)
                                      -> WorkspaceId -> X ()
    toggleOrDoSkip :: [WorkspaceId]
    -> (WorkspaceId -> WindowSet -> WindowSet) -> WorkspaceId -> X ()
    toggleOrDoSkip [WorkspaceId]
    skips WorkspaceId -> WindowSet -> WindowSet
    f WorkspaceId
    toWS = do
        WorkspaceId
    cur <- (XState -> WorkspaceId) -> X WorkspaceId
    forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
    gets (WindowSet -> WorkspaceId
    forall i l a s sd. StackSet i l a s sd -> i
    currentTag (WindowSet -> WorkspaceId)
    -> (XState -> WindowSet) -> XState -> WorkspaceId
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . XState -> WindowSet
    windowset)
        if WorkspaceId
    toWS WorkspaceId -> WorkspaceId -> Bool
    forall a. Eq a => a -> a -> Bool
    == WorkspaceId
    cur
            then [WorkspaceId] -> X (Maybe WorkspaceId)
    lastViewedHiddenExcept [WorkspaceId]
    skips X (Maybe WorkspaceId) -> (Maybe WorkspaceId -> X ()) -> X ()
    forall a b. X a -> (a -> X b) -> X b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= (Maybe WorkspaceId -> (WorkspaceId -> X ()) -> X ())
    -> (WorkspaceId -> X ()) -> Maybe WorkspaceId -> X ()
    forall a b c. (a -> b -> c) -> b -> a -> c
    flip Maybe WorkspaceId -> (WorkspaceId -> X ()) -> X ()
    forall (m :: * -> *) a. Monad m => Maybe a -> (a -> m ()) -> m ()
    whenJust ((WindowSet -> WindowSet) -> X ()
    windows ((WindowSet -> WindowSet) -> X ())
    -> (WorkspaceId -> WindowSet -> WindowSet) -> WorkspaceId -> X ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . WorkspaceId -> WindowSet -> WindowSet
    f)
            else (WindowSet -> WindowSet) -> X ()
    windows (WorkspaceId -> WindowSet -> WindowSet
    f WorkspaceId
    toWS)

    -- | List difference ('\\') for workspaces and tags. Removes workspaces
    -- matching listed tags from the given workspace list.
    skipTags :: (Eq i) => [Workspace i l a] -> [i] -> [Workspace i l a]
    skipTags :: forall i l a. Eq i => [Workspace i l a] -> [i] -> [Workspace i l a]
    skipTags [Workspace i l a]
    wss [i]
    ids = (Workspace i l a -> Bool) -> [Workspace i l a] -> [Workspace i l a]
    forall a. (a -> Bool) -> [a] -> [a]
    filter ((i -> [i] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `notElem` [i]
    ids) (i -> Bool) -> (Workspace i l a -> i) -> Workspace i l a -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Workspace i l a -> i
    forall i l a. Workspace i l a -> i
    tag) [Workspace i l a]
    wss

    -- | Ignoring the skips, find the best candidate for the last viewed hidden
    -- workspace.
    lastViewedHiddenExcept :: [WorkspaceId] -> X (Maybe WorkspaceId)
    lastViewedHiddenExcept :: [WorkspaceId] -> X (Maybe WorkspaceId)
    lastViewedHiddenExcept [WorkspaceId]
    skips = do
        [WorkspaceId]
    hs <- (XState -> [WorkspaceId]) -> X [WorkspaceId]
    forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
    gets ((XState -> [WorkspaceId]) -> X [WorkspaceId])
    -> (XState -> [WorkspaceId]) -> X [WorkspaceId]
    forall a b. (a -> b) -> a -> b
    $ (WindowSpace -> WorkspaceId) -> [WindowSpace] -> [WorkspaceId]
    forall a b. (a -> b) -> [a] -> [b]
    map WindowSpace -> WorkspaceId
    forall i l a. Workspace i l a -> i
    tag ([WindowSpace] -> [WorkspaceId])
    -> (XState -> [WindowSpace]) -> XState -> [WorkspaceId]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ([WindowSpace] -> [WorkspaceId] -> [WindowSpace])
    -> [WorkspaceId] -> [WindowSpace] -> [WindowSpace]
    forall a b c. (a -> b -> c) -> b -> a -> c
    flip [WindowSpace] -> [WorkspaceId] -> [WindowSpace]
    forall i l a. Eq i => [Workspace i l a] -> [i] -> [Workspace i l a]
    skipTags [WorkspaceId]
    skips ([WindowSpace] -> [WindowSpace])
    -> (XState -> [WindowSpace]) -> XState -> [WindowSpace]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . WindowSet -> [WindowSpace]
    forall i l a sid sd. StackSet i l a sid sd -> [Workspace i l a]
    hidden (WindowSet -> [WindowSpace])
    -> (XState -> WindowSet) -> XState -> [WindowSpace]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . XState -> WindowSet
    windowset
        [WorkspaceId] -> Maybe WorkspaceId -> Maybe WorkspaceId
    forall {a}. [a] -> Maybe a -> Maybe a
    choose [WorkspaceId]
    hs (Maybe WorkspaceId -> Maybe WorkspaceId)
    -> ([WorkspaceId] -> Maybe WorkspaceId)
    -> [WorkspaceId]
    -> Maybe WorkspaceId
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (WorkspaceId -> Bool) -> [WorkspaceId] -> Maybe WorkspaceId
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
    find (WorkspaceId -> [WorkspaceId] -> Bool
    forall a. Eq a => a -> [a] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` [WorkspaceId]
    hs) ([WorkspaceId] -> Maybe WorkspaceId)
    -> X [WorkspaceId] -> X (Maybe WorkspaceId)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> X [WorkspaceId]
    WH.workspaceHistory
        where choose :: [a] -> Maybe a -> Maybe a
    choose []    Maybe a
    _           = Maybe a
    forall a. Maybe a
    Nothing
              choose (a
    h:[a]
    _) Maybe a
    Nothing     = a -> Maybe a
    forall a. a -> Maybe a
    Just a
    h
              choose [a]
    _     vh :: Maybe a
    vh@(Just a
    _) = Maybe a
    vh

    switchWorkspace :: Int -> X ()
    switchWorkspace :: Int -> X ()
    switchWorkspace Int
    d = Int -> X WorkspaceId
    wsBy Int
    d X WorkspaceId -> (WorkspaceId -> X ()) -> X ()
    forall a b. X a -> (a -> X b) -> X b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= (WindowSet -> WindowSet) -> X ()
    windows ((WindowSet -> WindowSet) -> X ())
    -> (WorkspaceId -> WindowSet -> WindowSet) -> WorkspaceId -> X ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . WorkspaceId -> WindowSet -> WindowSet
    forall s i l a sd.
    (Eq s, Eq i) =>
    i -> StackSet i l a s sd -> StackSet i l a s sd
    greedyView

    shiftBy :: Int -> X ()
    shiftBy :: Int -> X ()
    shiftBy Int
    d = Int -> X WorkspaceId
    wsBy Int
    d X WorkspaceId -> (WorkspaceId -> X ()) -> X ()
    forall a b. X a -> (a -> X b) -> X b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= (WindowSet -> WindowSet) -> X ()
    windows ((WindowSet -> WindowSet) -> X ())
    -> (WorkspaceId -> WindowSet -> WindowSet) -> WorkspaceId -> X ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . WorkspaceId -> WindowSet -> WindowSet
    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
    shift

    wsBy :: Int -> X WorkspaceId
    wsBy :: Int -> X WorkspaceId
    wsBy = X ([WindowSpace] -> [WindowSpace])
    -> Direction1D -> WSType -> Int -> X WorkspaceId
    findWorkspace X ([WindowSpace] -> [WindowSpace])
    getSortByIndex Direction1D
    Next WSType
    anyWS

    {- $taketwo

    A few more general commands are also provided, which allow cycling
    through subsets of workspaces.

    For example,

    >   moveTo Next emptyWS

    will move to the first available workspace with no windows, and

    >   shiftTo Prev (WSIs $ return (('p' `elem`) . tag))

    will move the focused window backwards to the first workspace containing
    the letter 'p' in its name. =)

    -}

    {-# DEPRECATED EmptyWS             "Use emptyWS instead." #-}
    {-# DEPRECATED HiddenWS            "Use hiddenWS instead." #-}
    {-# DEPRECATED NonEmptyWS          "Use Not emptyWS instead." #-}
    {-# DEPRECATED HiddenNonEmptyWS    "Use hiddenWS :&: Not emptyWS instead." #-}
    {-# DEPRECATED HiddenEmptyWS       "Use hiddenWS :&: emptyWS instead." #-}
    {-# DEPRECATED AnyWS               "Use anyWS instead." #-}
    {-# DEPRECATED WSTagGroup          "Use wsTagGroup instead." #-}
    -- | What type of workspaces should be included in the cycle?
    data WSType = EmptyWS     -- ^ cycle through empty workspaces
                | NonEmptyWS  -- ^ cycle through non-empty workspaces
                | HiddenWS    -- ^ cycle through non-visible workspaces
                | HiddenNonEmptyWS  -- ^ cycle through non-empty non-visible workspaces
                | HiddenEmptyWS  -- ^ cycle through empty non-visible workspaces
                | AnyWS       -- ^ cycle through all workspaces
                | WSTagGroup Char
                              -- ^ cycle through workspaces in the same group, the
                              --   group name is all characters up to the first
                              --   separator character or the end of the tag
                | WSIs (X (WindowSpace -> Bool))
                              -- ^ cycle through workspaces satisfying
                              --   an arbitrary predicate
                | WSType :&: WSType -- ^ cycle through workspaces satisfying both
                                    --   predicates.
                | WSType :|: WSType -- ^ cycle through workspaces satisfying one of
                                    --   the predicates.
                | Not WSType -- ^ cycle through workspaces not satisfying the predicate

    -- | Convert a WSType value to a predicate on workspaces.
    wsTypeToPred :: WSType -> X (WindowSpace -> Bool)
    wsTypeToPred :: WSType -> X (WindowSpace -> Bool)
    wsTypeToPred WSType
    EmptyWS    = (WindowSpace -> Bool) -> X (WindowSpace -> Bool)
    forall a. a -> X a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Maybe (Stack Window) -> Bool
    forall a. Maybe a -> Bool
    isNothing (Maybe (Stack Window) -> Bool)
    -> (WindowSpace -> Maybe (Stack Window)) -> WindowSpace -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . WindowSpace -> Maybe (Stack Window)
    forall i l a. Workspace i l a -> Maybe (Stack a)
    stack)
    wsTypeToPred WSType
    NonEmptyWS = (WindowSpace -> Bool) -> X (WindowSpace -> Bool)
    forall a. a -> X a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Maybe (Stack Window) -> Bool
    forall a. Maybe a -> Bool
    isJust (Maybe (Stack Window) -> Bool)
    -> (WindowSpace -> Maybe (Stack Window)) -> WindowSpace -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . WindowSpace -> Maybe (Stack Window)
    forall i l a. Workspace i l a -> Maybe (Stack a)
    stack)
    wsTypeToPred WSType
    HiddenWS   = do [WorkspaceId]
    hs <- (XState -> [WorkspaceId]) -> X [WorkspaceId]
    forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
    gets ((WindowSpace -> WorkspaceId) -> [WindowSpace] -> [WorkspaceId]
    forall a b. (a -> b) -> [a] -> [b]
    map WindowSpace -> WorkspaceId
    forall i l a. Workspace i l a -> i
    tag ([WindowSpace] -> [WorkspaceId])
    -> (XState -> [WindowSpace]) -> XState -> [WorkspaceId]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . WindowSet -> [WindowSpace]
    forall i l a sid sd. StackSet i l a sid sd -> [Workspace i l a]
    hidden (WindowSet -> [WindowSpace])
    -> (XState -> WindowSet) -> XState -> [WindowSpace]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . XState -> WindowSet
    windowset)
                                 (WindowSpace -> Bool) -> X (WindowSpace -> Bool)
    forall a. a -> X a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (\WindowSpace
    w -> WindowSpace -> WorkspaceId
    forall i l a. Workspace i l a -> i
    tag WindowSpace
    w WorkspaceId -> [WorkspaceId] -> Bool
    forall a. Eq a => a -> [a] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` [WorkspaceId]
    hs)
    wsTypeToPred WSType
    HiddenNonEmptyWS  = do WindowSpace -> Bool
    ne <- WSType -> X (WindowSpace -> Bool)
    wsTypeToPred WSType
    NonEmptyWS
                                        WindowSpace -> Bool
    hi <- WSType -> X (WindowSpace -> Bool)
    wsTypeToPred WSType
    HiddenWS
                                        (WindowSpace -> Bool) -> X (WindowSpace -> Bool)
    forall a. a -> X a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (\WindowSpace
    w -> WindowSpace -> Bool
    hi WindowSpace
    w Bool -> Bool -> Bool
    && WindowSpace -> Bool
    ne WindowSpace
    w)
    wsTypeToPred WSType
    HiddenEmptyWS  = do WindowSpace -> Bool
    ne <- WSType -> X (WindowSpace -> Bool)
    wsTypeToPred WSType
    EmptyWS
                                     WindowSpace -> Bool
    hi <- WSType -> X (WindowSpace -> Bool)
    wsTypeToPred WSType
    HiddenWS
                                     (WindowSpace -> Bool) -> X (WindowSpace -> Bool)
    forall a. a -> X a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (\WindowSpace
    w -> WindowSpace -> Bool
    hi WindowSpace
    w Bool -> Bool -> Bool
    && WindowSpace -> Bool
    ne WindowSpace
    w)
    wsTypeToPred WSType
    AnyWS      = (WindowSpace -> Bool) -> X (WindowSpace -> Bool)
    forall a. a -> X a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Bool -> WindowSpace -> Bool
    forall a b. a -> b -> a
    const Bool
    True)
    wsTypeToPred (WSTagGroup Char
    sep) = do WorkspaceId
    cur <- WindowSpace -> WorkspaceId
    forall {l} {a}. Workspace WorkspaceId l a -> WorkspaceId
    groupName(WindowSpace -> WorkspaceId)
    -> (WindowSet -> WindowSpace) -> WindowSet -> WorkspaceId
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .Screen WorkspaceId (Layout Window) Window ScreenId ScreenDetail
    -> WindowSpace
    forall i l a sid sd. Screen i l a sid sd -> Workspace i l a
    workspace(Screen WorkspaceId (Layout Window) Window ScreenId ScreenDetail
     -> WindowSpace)
    -> (WindowSet
        -> Screen WorkspaceId (Layout Window) Window ScreenId ScreenDetail)
    -> WindowSet
    -> WindowSpace
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .WindowSet
    -> Screen WorkspaceId (Layout Window) Window ScreenId ScreenDetail
    forall i l a sid sd. StackSet i l a sid sd -> Screen i l a sid sd
    current (WindowSet -> WorkspaceId) -> X WindowSet -> X WorkspaceId
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (XState -> WindowSet) -> X WindowSet
    forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
    gets XState -> WindowSet
    windowset
                                       (WindowSpace -> Bool) -> X (WindowSpace -> Bool)
    forall a. a -> X a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ((WindowSpace -> Bool) -> X (WindowSpace -> Bool))
    -> (WindowSpace -> Bool) -> X (WindowSpace -> Bool)
    forall a b. (a -> b) -> a -> b
    $ (WorkspaceId
    cur WorkspaceId -> WorkspaceId -> Bool
    forall a. Eq a => a -> a -> Bool
    ==)(WorkspaceId -> Bool)
    -> (WindowSpace -> WorkspaceId) -> WindowSpace -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .WindowSpace -> WorkspaceId
    forall {l} {a}. Workspace WorkspaceId l a -> WorkspaceId
    groupName
                                       where groupName :: Workspace WorkspaceId l a -> WorkspaceId
    groupName = (Char -> Bool) -> WorkspaceId -> WorkspaceId
    forall a. (a -> Bool) -> [a] -> [a]
    takeWhile (Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    /=Char
    sep)(WorkspaceId -> WorkspaceId)
    -> (Workspace WorkspaceId l a -> WorkspaceId)
    -> Workspace WorkspaceId l a
    -> WorkspaceId
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .Workspace WorkspaceId l a -> WorkspaceId
    forall i l a. Workspace i l a -> i
    tag
    wsTypeToPred (WSIs X (WindowSpace -> Bool)
    p ) = X (WindowSpace -> Bool)
    p
    wsTypeToPred (WSType
    p :&: WSType
    q) = (Bool -> Bool -> Bool)
    -> (WindowSpace -> Bool)
    -> (WindowSpace -> Bool)
    -> WindowSpace
    -> Bool
    forall (m :: * -> *) a1 a2 r.
    Monad m =>
    (a1 -> a2 -> r) -> m a1 -> m a2 -> m r
    liftM2 Bool -> Bool -> Bool
    (&&) ((WindowSpace -> Bool)
     -> (WindowSpace -> Bool) -> WindowSpace -> Bool)
    -> X (WindowSpace -> Bool)
    -> X ((WindowSpace -> Bool) -> WindowSpace -> Bool)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> WSType -> X (WindowSpace -> Bool)
    wsTypeToPred WSType
    p X ((WindowSpace -> Bool) -> WindowSpace -> Bool)
    -> X (WindowSpace -> Bool) -> X (WindowSpace -> Bool)
    forall a b. X (a -> b) -> X a -> X b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> WSType -> X (WindowSpace -> Bool)
    wsTypeToPred WSType
    q
    wsTypeToPred (WSType
    p :|: WSType
    q) = (Bool -> Bool -> Bool)
    -> (WindowSpace -> Bool)
    -> (WindowSpace -> Bool)
    -> WindowSpace
    -> Bool
    forall (m :: * -> *) a1 a2 r.
    Monad m =>
    (a1 -> a2 -> r) -> m a1 -> m a2 -> m r
    liftM2 Bool -> Bool -> Bool
    (||) ((WindowSpace -> Bool)
     -> (WindowSpace -> Bool) -> WindowSpace -> Bool)
    -> X (WindowSpace -> Bool)
    -> X ((WindowSpace -> Bool) -> WindowSpace -> Bool)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> WSType -> X (WindowSpace -> Bool)
    wsTypeToPred WSType
    p X ((WindowSpace -> Bool) -> WindowSpace -> Bool)
    -> X (WindowSpace -> Bool) -> X (WindowSpace -> Bool)
    forall a b. X (a -> b) -> X a -> X b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> WSType -> X (WindowSpace -> Bool)
    wsTypeToPred WSType
    q
    wsTypeToPred (Not WSType
    p  ) = (Bool -> Bool) -> (WindowSpace -> Bool) -> WindowSpace -> Bool
    forall a b. (a -> b) -> (WindowSpace -> a) -> WindowSpace -> b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap Bool -> Bool
    not ((WindowSpace -> Bool) -> WindowSpace -> Bool)
    -> X (WindowSpace -> Bool) -> X (WindowSpace -> Bool)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> WSType -> X (WindowSpace -> Bool)
    wsTypeToPred WSType
    p

    -- | Cycle through empty workspaces
    emptyWS :: WSType
    emptyWS :: WSType
    emptyWS = X (WindowSpace -> Bool) -> WSType
    WSIs (X (WindowSpace -> Bool) -> WSType)
    -> ((WindowSpace -> Bool) -> X (WindowSpace -> Bool))
    -> (WindowSpace -> Bool)
    -> WSType
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (WindowSpace -> Bool) -> X (WindowSpace -> Bool)
    forall a. a -> X a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ((WindowSpace -> Bool) -> WSType)
    -> (WindowSpace -> Bool) -> WSType
    forall a b. (a -> b) -> a -> b
    $ Maybe (Stack Window) -> Bool
    forall a. Maybe a -> Bool
    isNothing (Maybe (Stack Window) -> Bool)
    -> (WindowSpace -> Maybe (Stack Window)) -> WindowSpace -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . WindowSpace -> Maybe (Stack Window)
    forall i l a. Workspace i l a -> Maybe (Stack a)
    stack

    -- | Cycle through non-visible workspaces
    hiddenWS :: WSType
    hiddenWS :: WSType
    hiddenWS = X (WindowSpace -> Bool) -> WSType
    WSIs (X (WindowSpace -> Bool) -> WSType)
    -> X (WindowSpace -> Bool) -> WSType
    forall a b. (a -> b) -> a -> b
    $ do
      [WorkspaceId]
    hs <- (XState -> [WorkspaceId]) -> X [WorkspaceId]
    forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
    gets ((WindowSpace -> WorkspaceId) -> [WindowSpace] -> [WorkspaceId]
    forall a b. (a -> b) -> [a] -> [b]
    map WindowSpace -> WorkspaceId
    forall i l a. Workspace i l a -> i
    tag ([WindowSpace] -> [WorkspaceId])
    -> (XState -> [WindowSpace]) -> XState -> [WorkspaceId]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . WindowSet -> [WindowSpace]
    forall i l a sid sd. StackSet i l a sid sd -> [Workspace i l a]
    hidden (WindowSet -> [WindowSpace])
    -> (XState -> WindowSet) -> XState -> [WindowSpace]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . XState -> WindowSet
    windowset)
      (WindowSpace -> Bool) -> X (WindowSpace -> Bool)
    forall a. a -> X a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ((WindowSpace -> Bool) -> X (WindowSpace -> Bool))
    -> (WindowSpace -> Bool) -> X (WindowSpace -> Bool)
    forall a b. (a -> b) -> a -> b
    $ (WorkspaceId -> [WorkspaceId] -> Bool
    forall a. Eq a => a -> [a] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` [WorkspaceId]
    hs) (WorkspaceId -> Bool)
    -> (WindowSpace -> WorkspaceId) -> WindowSpace -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . WindowSpace -> WorkspaceId
    forall i l a. Workspace i l a -> i
    tag

    -- | Cycle through all workspaces
    anyWS :: WSType
    anyWS :: WSType
    anyWS = X (WindowSpace -> Bool) -> WSType
    WSIs (X (WindowSpace -> Bool) -> WSType)
    -> ((WindowSpace -> Bool) -> X (WindowSpace -> Bool))
    -> (WindowSpace -> Bool)
    -> WSType
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (WindowSpace -> Bool) -> X (WindowSpace -> Bool)
    forall a. a -> X a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ((WindowSpace -> Bool) -> WSType)
    -> (WindowSpace -> Bool) -> WSType
    forall a b. (a -> b) -> a -> b
    $ Bool -> WindowSpace -> Bool
    forall a b. a -> b -> a
    const Bool
    True

    -- | Cycle through workspaces that are not in the given list. This could, for
    --   example, be used for skipping the workspace reserved for
    --   "XMonad.Util.NamedScratchpad":
    --
    -- >  moveTo Next $ hiddenWS :&: Not emptyWS :&: ignoringWSs [scratchpadWorkspaceTag]
    --
    ignoringWSs :: [WorkspaceId] -> WSType
    ignoringWSs :: [WorkspaceId] -> WSType
    ignoringWSs [WorkspaceId]
    ts = X (WindowSpace -> Bool) -> WSType
    WSIs (X (WindowSpace -> Bool) -> WSType)
    -> ((WindowSpace -> Bool) -> X (WindowSpace -> Bool))
    -> (WindowSpace -> Bool)
    -> WSType
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (WindowSpace -> Bool) -> X (WindowSpace -> Bool)
    forall a. a -> X a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ((WindowSpace -> Bool) -> WSType)
    -> (WindowSpace -> Bool) -> WSType
    forall a b. (a -> b) -> a -> b
    $ (WorkspaceId -> [WorkspaceId] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `notElem` [WorkspaceId]
    ts) (WorkspaceId -> Bool)
    -> (WindowSpace -> WorkspaceId) -> WindowSpace -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . WindowSpace -> WorkspaceId
    forall i l a. Workspace i l a -> i
    tag

    -- | Cycle through workspaces in the same group, the
    --   group name is all characters up to the first
    --   separator character or the end of the tag
    wsTagGroup :: Char -> WSType
    wsTagGroup :: Char -> WSType
    wsTagGroup Char
    sep = X (WindowSpace -> Bool) -> WSType
    WSIs (X (WindowSpace -> Bool) -> WSType)
    -> X (WindowSpace -> Bool) -> WSType
    forall a b. (a -> b) -> a -> b
    $ do
      WorkspaceId
    cur <- WindowSpace -> WorkspaceId
    forall {l} {a}. Workspace WorkspaceId l a -> WorkspaceId
    groupName (WindowSpace -> WorkspaceId)
    -> (WindowSet -> WindowSpace) -> WindowSet -> WorkspaceId
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Screen WorkspaceId (Layout Window) Window ScreenId ScreenDetail
    -> WindowSpace
    forall i l a sid sd. Screen i l a sid sd -> Workspace i l a
    workspace (Screen WorkspaceId (Layout Window) Window ScreenId ScreenDetail
     -> WindowSpace)
    -> (WindowSet
        -> Screen WorkspaceId (Layout Window) Window ScreenId ScreenDetail)
    -> WindowSet
    -> WindowSpace
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . WindowSet
    -> Screen WorkspaceId (Layout Window) Window ScreenId ScreenDetail
    forall i l a sid sd. StackSet i l a sid sd -> Screen i l a sid sd
    current (WindowSet -> WorkspaceId) -> X WindowSet -> X WorkspaceId
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (XState -> WindowSet) -> X WindowSet
    forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
    gets XState -> WindowSet
    windowset
      (WindowSpace -> Bool) -> X (WindowSpace -> Bool)
    forall a. a -> X a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ((WindowSpace -> Bool) -> X (WindowSpace -> Bool))
    -> (WindowSpace -> Bool) -> X (WindowSpace -> Bool)
    forall a b. (a -> b) -> a -> b
    $ (WorkspaceId
    cur WorkspaceId -> WorkspaceId -> Bool
    forall a. Eq a => a -> a -> Bool
    ==) (WorkspaceId -> Bool)
    -> (WindowSpace -> WorkspaceId) -> WindowSpace -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . WindowSpace -> WorkspaceId
    forall {l} {a}. Workspace WorkspaceId l a -> WorkspaceId
    groupName
      where groupName :: Workspace WorkspaceId l a -> WorkspaceId
    groupName = (Char -> Bool) -> WorkspaceId -> WorkspaceId
    forall a. (a -> Bool) -> [a] -> [a]
    takeWhile (Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    /= Char
    sep) (WorkspaceId -> WorkspaceId)
    -> (Workspace WorkspaceId l a -> WorkspaceId)
    -> Workspace WorkspaceId l a
    -> WorkspaceId
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Workspace WorkspaceId l a -> WorkspaceId
    forall i l a. Workspace i l a -> i
    tag

    -- | View the next workspace in the given direction that satisfies
    --   the given condition.
    moveTo :: Direction1D -> WSType -> X ()
    moveTo :: Direction1D -> WSType -> X ()
    moveTo Direction1D
    dir WSType
    t = Direction1D
    -> WSType
    -> X ([WindowSpace] -> [WindowSpace])
    -> (WorkspaceId -> X ())
    -> X ()
    doTo Direction1D
    dir WSType
    t X ([WindowSpace] -> [WindowSpace])
    getSortByIndex ((WindowSet -> WindowSet) -> X ()
    windows ((WindowSet -> WindowSet) -> X ())
    -> (WorkspaceId -> WindowSet -> WindowSet) -> WorkspaceId -> X ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . WorkspaceId -> WindowSet -> WindowSet
    forall s i l a sd.
    (Eq s, Eq i) =>
    i -> StackSet i l a s sd -> StackSet i l a s sd
    greedyView)

    -- | Move the currently focused window to the next workspace in the
    --   given direction that satisfies the given condition.
    shiftTo :: Direction1D -> WSType -> X ()
    shiftTo :: Direction1D -> WSType -> X ()
    shiftTo Direction1D
    dir WSType
    t = Direction1D
    -> WSType
    -> X ([WindowSpace] -> [WindowSpace])
    -> (WorkspaceId -> X ())
    -> X ()
    doTo Direction1D
    dir WSType
    t X ([WindowSpace] -> [WindowSpace])
    getSortByIndex ((WindowSet -> WindowSet) -> X ()
    windows ((WindowSet -> WindowSet) -> X ())
    -> (WorkspaceId -> WindowSet -> WindowSet) -> WorkspaceId -> X ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . WorkspaceId -> WindowSet -> WindowSet
    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
    shift)

    -- | Using the given sort, find the next workspace in the given
    -- direction of the given type, and perform the given action on it.
    doTo :: Direction1D -> WSType -> X WorkspaceSort -> (WorkspaceId -> X ()) -> X ()
    doTo :: Direction1D
    -> WSType
    -> X ([WindowSpace] -> [WindowSpace])
    -> (WorkspaceId -> X ())
    -> X ()
    doTo Direction1D
    dir WSType
    t X ([WindowSpace] -> [WindowSpace])
    srt WorkspaceId -> X ()
    act = X ([WindowSpace] -> [WindowSpace])
    -> Direction1D -> WSType -> Int -> X WorkspaceId
    findWorkspace X ([WindowSpace] -> [WindowSpace])
    srt Direction1D
    dir WSType
    t Int
    1 X WorkspaceId -> (WorkspaceId -> X ()) -> X ()
    forall a b. X a -> (a -> X b) -> X b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= WorkspaceId -> X ()
    act

    -- | Given a function @s@ to sort workspaces, a direction @dir@, a
    --   predicate @p@ on workspaces, and an integer @n@, find the tag of
    --   the workspace which is @n@ away from the current workspace in
    --   direction @dir@ (wrapping around if necessary), among those
    --   workspaces, sorted by @s@, which satisfy @p@.
    --
    --   For some useful workspace sorting functions, see
    --   "XMonad.Util.WorkspaceCompare".
    --
    --   For ideas of what to do with a workspace tag once obtained, note
    --   that 'moveTo' and 'shiftTo' are implemented by applying @(>>=
    --   (windows . greedyView))@ and @(>>= (windows . shift))@, respectively,
    --   to the output of 'findWorkspace'.
    findWorkspace :: X WorkspaceSort -> Direction1D -> WSType -> Int -> X WorkspaceId
    findWorkspace :: X ([WindowSpace] -> [WindowSpace])
    -> Direction1D -> WSType -> Int -> X WorkspaceId
    findWorkspace X ([WindowSpace] -> [WindowSpace])
    s Direction1D
    dir WSType
    t Int
    n = X ([WindowSpace] -> [WindowSpace])
    -> X (WindowSpace -> Bool) -> Int -> X WorkspaceId
    findWorkspaceGen X ([WindowSpace] -> [WindowSpace])
    s (WSType -> X (WindowSpace -> Bool)
    wsTypeToPred WSType
    t) (Direction1D -> Int -> Int
    forall {p}. Num p => Direction1D -> p -> p
    maybeNegate Direction1D
    dir Int
    n)
      where
        maybeNegate :: Direction1D -> p -> p
    maybeNegate Direction1D
    Next p
    d = p
    d
        maybeNegate Direction1D
    Prev p
    d = -p
    d

    findWorkspaceGen :: X WorkspaceSort -> X (WindowSpace -> Bool) -> Int -> X WorkspaceId
    findWorkspaceGen :: X ([WindowSpace] -> [WindowSpace])
    -> X (WindowSpace -> Bool) -> Int -> X WorkspaceId
    findWorkspaceGen X ([WindowSpace] -> [WindowSpace])
    _ X (WindowSpace -> Bool)
    _ Int
    0 = (XState -> WorkspaceId) -> X WorkspaceId
    forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
    gets (WindowSet -> WorkspaceId
    forall i l a s sd. StackSet i l a s sd -> i
    currentTag (WindowSet -> WorkspaceId)
    -> (XState -> WindowSet) -> XState -> WorkspaceId
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . XState -> WindowSet
    windowset)
    findWorkspaceGen X ([WindowSpace] -> [WindowSpace])
    sortX X (WindowSpace -> Bool)
    wsPredX Int
    d = do
        WindowSpace -> Bool
    wsPred <- X (WindowSpace -> Bool)
    wsPredX
        [WindowSpace] -> [WindowSpace]
    sort   <- X ([WindowSpace] -> [WindowSpace])
    sortX
        WindowSet
    ws     <- (XState -> WindowSet) -> X WindowSet
    forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
    gets XState -> WindowSet
    windowset
        let cur :: WindowSpace
    cur     = Screen WorkspaceId (Layout Window) Window ScreenId ScreenDetail
    -> WindowSpace
    forall i l a sid sd. Screen i l a sid sd -> Workspace i l a
    workspace (WindowSet
    -> Screen WorkspaceId (Layout Window) Window ScreenId ScreenDetail
    forall i l a sid sd. StackSet i l a sid sd -> Screen i l a sid sd
    current WindowSet
    ws)
            sorted :: [WindowSpace]
    sorted  = [WindowSpace] -> [WindowSpace]
    sort (WindowSet -> [WindowSpace]
    forall i l a sid sd. StackSet i l a sid sd -> [Workspace i l a]
    workspaces WindowSet
    ws)
            pivoted :: [WindowSpace]
    pivoted = let ([WindowSpace]
    a,[WindowSpace]
    b) = (WindowSpace -> Bool)
    -> [WindowSpace] -> ([WindowSpace], [WindowSpace])
    forall a. (a -> Bool) -> [a] -> ([a], [a])
    span ((WorkspaceId -> WorkspaceId -> Bool
    forall a. Eq a => a -> a -> Bool
    /= WindowSpace -> WorkspaceId
    forall i l a. Workspace i l a -> i
    tag WindowSpace
    cur) (WorkspaceId -> Bool)
    -> (WindowSpace -> WorkspaceId) -> WindowSpace -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . WindowSpace -> WorkspaceId
    forall i l a. Workspace i l a -> i
    tag) [WindowSpace]
    sorted in [WindowSpace]
    b [WindowSpace] -> [WindowSpace] -> [WindowSpace]
    forall a. [a] -> [a] -> [a]
    ++ [WindowSpace]
    a
            ws' :: [WindowSpace]
    ws'     = (WindowSpace -> Bool) -> [WindowSpace] -> [WindowSpace]
    forall a. (a -> Bool) -> [a] -> [a]
    filter WindowSpace -> Bool
    wsPred [WindowSpace]
    pivoted
            mCurIx :: Maybe Int
    mCurIx  = WindowSpace -> [WindowSpace] -> Maybe Int
    findWsIndex WindowSpace
    cur [WindowSpace]
    ws'
            d' :: Int
    d'      = if Int
    d Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    > Int
    0 then Int
    d Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    1 else Int
    d
            next :: WindowSpace
    next    = if [WindowSpace] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [WindowSpace]
    ws'
                          then WindowSpace
    cur
                          else case Maybe Int
    mCurIx of
                                Maybe Int
    Nothing -> [WindowSpace]
    ws' [WindowSpace] -> Int -> WindowSpace
    forall a. HasCallStack => [a] -> Int -> a
    !! (Int
    d' Int -> Int -> Int
    forall a. Integral a => a -> a -> a
    `mod` [WindowSpace] -> Int
    forall a. [a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [WindowSpace]
    ws')
                                Just Int
    ix -> [WindowSpace]
    ws' [WindowSpace] -> Int -> WindowSpace
    forall a. HasCallStack => [a] -> Int -> a
    !! ((Int
    ix Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    d) Int -> Int -> Int
    forall a. Integral a => a -> a -> a
    `mod` [WindowSpace] -> Int
    forall a. [a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [WindowSpace]
    ws')
        WorkspaceId -> X WorkspaceId
    forall a. a -> X a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (WorkspaceId -> X WorkspaceId) -> WorkspaceId -> X WorkspaceId
    forall a b. (a -> b) -> a -> b
    $ WindowSpace -> WorkspaceId
    forall i l a. Workspace i l a -> i
    tag WindowSpace
    next

    findWsIndex :: WindowSpace -> [WindowSpace] -> Maybe Int
    findWsIndex :: WindowSpace -> [WindowSpace] -> Maybe Int
    findWsIndex WindowSpace
    ws = (WindowSpace -> Bool) -> [WindowSpace] -> Maybe Int
    forall a. (a -> Bool) -> [a] -> Maybe Int
    findIndex ((WorkspaceId -> WorkspaceId -> Bool
    forall a. Eq a => a -> a -> Bool
    == WindowSpace -> WorkspaceId
    forall i l a. Workspace i l a -> i
    tag WindowSpace
    ws) (WorkspaceId -> Bool)
    -> (WindowSpace -> WorkspaceId) -> WindowSpace -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . WindowSpace -> WorkspaceId
    forall i l a. Workspace i l a -> i
    tag)

    -- | View next screen
    nextScreen :: X ()
    nextScreen :: X ()
    nextScreen = Int -> X ()
    switchScreen Int
    1

    -- | View prev screen
    prevScreen :: X ()
    prevScreen :: X ()
    prevScreen = Int -> X ()
    switchScreen (-Int
    1)

    switchScreen :: Int -> X ()
    switchScreen :: Int -> X ()
    switchScreen Int
    d = do ScreenId
    s <- Int -> X ScreenId
    screenBy Int
    d
                        Maybe WorkspaceId
    mws <- ScreenId -> X (Maybe WorkspaceId)
    screenWorkspace ScreenId
    s
                        case Maybe WorkspaceId
    mws of
                             Maybe WorkspaceId
    Nothing -> () -> X ()
    forall a. a -> X a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()
                             Just WorkspaceId
    ws -> (WindowSet -> WindowSet) -> X ()
    windows (WorkspaceId -> WindowSet -> WindowSet
    forall s i l a sd.
    (Eq s, Eq i) =>
    i -> StackSet i l a s sd -> StackSet i l a s sd
    view WorkspaceId
    ws)

    {- | Get the 'ScreenId' /d/ places over. Example usage is a variation of the
    the default screen keybindings:

    >     -- mod-{w,e}, Switch to previous/next Xinerama screen
    >     -- mod-shift-{w,e}, Move client to previous/next Xinerama screen
    >     --
    >     [((m .|. modm, key), sc >>= screenWorkspace >>= flip whenJust (windows . f))
    >         | (key, sc) <- zip [xK_w, xK_e] [(screenBy (-1)),(screenBy 1)]
    >         , (f, m) <- [(W.view, 0), (W.shift, shiftMask)]]

    -}
    screenBy :: Int -> X ScreenId
    screenBy :: Int -> X ScreenId
    screenBy Int
    d = do WindowSet
    ws <- (XState -> WindowSet) -> X WindowSet
    forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
    gets XState -> WindowSet
    windowset
                    --let ss = sortBy screen (screens ws)
                    let now :: ScreenId
    now = Screen WorkspaceId (Layout Window) Window ScreenId ScreenDetail
    -> ScreenId
    forall i l a sid sd. Screen i l a sid sd -> sid
    screen (WindowSet
    -> Screen WorkspaceId (Layout Window) Window ScreenId ScreenDetail
    forall i l a sid sd. StackSet i l a sid sd -> Screen i l a sid sd
    current WindowSet
    ws)
                    ScreenId -> X ScreenId
    forall a. a -> X a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (ScreenId -> X ScreenId) -> ScreenId -> X ScreenId
    forall a b. (a -> b) -> a -> b
    $ (ScreenId
    now ScreenId -> ScreenId -> ScreenId
    forall a. Num a => a -> a -> a
    + Int -> ScreenId
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    d) ScreenId -> ScreenId -> ScreenId
    forall a. Integral a => a -> a -> a
    `mod` Int -> ScreenId
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral ([Screen WorkspaceId (Layout Window) Window ScreenId ScreenDetail]
    -> Int
    forall a. [a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length (WindowSet
    -> [Screen
          WorkspaceId (Layout Window) Window ScreenId ScreenDetail]
    forall i l a s sd. StackSet i l a s sd -> [Screen i l a s sd]
    screens WindowSet
    ws))

    -- | Swap current screen with next screen
    swapNextScreen :: X ()
    swapNextScreen :: X ()
    swapNextScreen = Int -> X ()
    swapScreen Int
    1

    -- | Swap current screen with previous screen
    swapPrevScreen :: X ()
    swapPrevScreen :: X ()
    swapPrevScreen = Int -> X ()
    swapScreen (-Int
    1)

    swapScreen :: Int -> X ()
    swapScreen :: Int -> X ()
    swapScreen Int
    d = do ScreenId
    s <- Int -> X ScreenId
    screenBy Int
    d
                      Maybe WorkspaceId
    mws <- ScreenId -> X (Maybe WorkspaceId)
    screenWorkspace ScreenId
    s
                      case Maybe WorkspaceId
    mws of
                        Maybe WorkspaceId
    Nothing -> () -> X ()
    forall a. a -> X a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()
                        Just WorkspaceId
    ws -> (WindowSet -> WindowSet) -> X ()
    windows (WorkspaceId -> WindowSet -> WindowSet
    forall s i l a sd.
    (Eq s, Eq i) =>
    i -> StackSet i l a s sd -> StackSet i l a s sd
    greedyView WorkspaceId
    ws)

    -- | Move focused window to workspace on next screen
    shiftNextScreen :: X ()
    shiftNextScreen :: X ()
    shiftNextScreen = Int -> X ()
    shiftScreenBy Int
    1

    -- | Move focused window to workspace on prev screen
    shiftPrevScreen :: X ()
    shiftPrevScreen :: X ()
    shiftPrevScreen = Int -> X ()
    shiftScreenBy (-Int
    1)

    shiftScreenBy :: Int -> X ()
    shiftScreenBy :: Int -> X ()
    shiftScreenBy Int
    d = do ScreenId
    s <- Int -> X ScreenId
    screenBy Int
    d
                         Maybe WorkspaceId
    mws <- ScreenId -> X (Maybe WorkspaceId)
    screenWorkspace ScreenId
    s
                         case Maybe WorkspaceId
    mws of
                             Maybe WorkspaceId
    Nothing -> () -> X ()
    forall a. a -> X a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()
                             Just WorkspaceId
    ws -> (WindowSet -> WindowSet) -> X ()
    windows (WorkspaceId -> WindowSet -> WindowSet
    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
    shift WorkspaceId
    ws)