{-# LANGUAGE ViewPatterns #-}
module XMonad.Actions.WindowGo (
raise,
raiseNext,
runOrRaise,
runOrRaiseNext,
raiseMaybe,
raiseNextMaybe,
raiseNextMaybeCustomFocus,
raiseBrowser,
raiseEditor,
runOrRaiseAndDo,
runOrRaiseMaster,
raiseAndDo,
raiseMaster,
ifWindows,
ifWindow,
raiseHook,
module XMonad.ManageHook
) where
import qualified Data.List as L (nub,sortBy)
import XMonad.Prelude
import XMonad (Query(), X(), ManageHook, WindowSet, withWindowSet, runQuery, liftIO, ask)
import Graphics.X11 (Window)
import XMonad.ManageHook
import XMonad.Operations (windows)
import XMonad.Prompt.Shell (getBrowser, getEditor)
import qualified XMonad.StackSet as W (peek, swapMaster, focusWindow, workspaces, StackSet, Workspace, integrate', tag, stack)
import XMonad.Util.Run (safeSpawnProg)
workspacesSorted :: Ord i => W.StackSet i l a s sd -> [W.Workspace i l a]
workspacesSorted :: forall i l a s sd.
Ord i =>
StackSet i l a s sd -> [Workspace i l a]
workspacesSorted StackSet i l a s sd
s = (Workspace i l a -> Workspace i l a -> Ordering)
-> [Workspace i l a] -> [Workspace i l a]
forall a. (a -> a -> Ordering) -> [a] -> [a]
L.sortBy (\Workspace i l a
u Workspace i l a
t -> Workspace i l a -> i
forall i l a. Workspace i l a -> i
W.tag Workspace i l a
u i -> i -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` Workspace i l a -> i
forall i l a. Workspace i l a -> i
W.tag Workspace i l a
t) ([Workspace i l a] -> [Workspace i l a])
-> [Workspace i l a] -> [Workspace i l a]
forall a b. (a -> b) -> a -> b
$ StackSet i l a s sd -> [Workspace i l a]
forall i l a s sd. StackSet i l a s sd -> [Workspace i l a]
W.workspaces StackSet i l a s sd
s
allWindowsSorted :: Ord i => Eq a => W.StackSet i l a s sd -> [a]
allWindowsSorted :: forall i a l s sd. (Ord i, Eq a) => StackSet i l a s sd -> [a]
allWindowsSorted = [a] -> [a]
forall a. Eq a => [a] -> [a]
L.nub ([a] -> [a])
-> (StackSet i l a s sd -> [a]) -> StackSet i l a s sd -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Workspace i l a -> [a]) -> [Workspace i l a] -> [a]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (Maybe (Stack a) -> [a]
forall a. Maybe (Stack a) -> [a]
W.integrate' (Maybe (Stack a) -> [a])
-> (Workspace i l a -> Maybe (Stack a)) -> Workspace i l a -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Workspace i l a -> Maybe (Stack a)
forall i l a. Workspace i l a -> Maybe (Stack a)
W.stack) ([Workspace i l a] -> [a])
-> (StackSet i l a s sd -> [Workspace i l a])
-> StackSet i l a s sd
-> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StackSet i l a s sd -> [Workspace i l a]
forall i l a s sd.
Ord i =>
StackSet i l a s sd -> [Workspace i l a]
workspacesSorted
ifWindows :: Query Bool -> ([Window] -> X ()) -> X () -> X ()
ifWindows :: Query Bool -> ([Window] -> X ()) -> X () -> X ()
ifWindows Query Bool
qry [Window] -> X ()
f X ()
el = (WindowSet -> X ()) -> X ()
forall a. (WindowSet -> X a) -> X a
withWindowSet ((WindowSet -> X ()) -> X ()) -> (WindowSet -> X ()) -> X ()
forall a b. (a -> b) -> a -> b
$ \WindowSet
wins -> do
[Window]
matches <- (Window -> X Bool) -> [Window] -> X [Window]
forall (m :: * -> *) a.
Applicative m =>
(a -> m Bool) -> [a] -> m [a]
filterM (Query Bool -> Window -> X Bool
forall a. Query a -> Window -> X a
runQuery Query Bool
qry) ([Window] -> X [Window]) -> [Window] -> X [Window]
forall a b. (a -> b) -> a -> b
$ WindowSet -> [Window]
forall i a l s sd. (Ord i, Eq a) => StackSet i l a s sd -> [a]
allWindowsSorted WindowSet
wins
case [Window]
matches of
[] -> X ()
el
[Window]
ws -> [Window] -> X ()
f [Window]
ws
ifWindow :: Query Bool -> ManageHook -> X () -> X ()
ifWindow :: Query Bool -> Query (Endo WindowSet) -> X () -> X ()
ifWindow Query Bool
qry Query (Endo WindowSet)
mh = Query Bool -> ([Window] -> X ()) -> X () -> X ()
ifWindows Query Bool
qry ((WindowSet -> WindowSet) -> X ()
windows ((WindowSet -> WindowSet) -> X ())
-> (Endo WindowSet -> WindowSet -> WindowSet)
-> Endo WindowSet
-> X ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Endo WindowSet -> WindowSet -> WindowSet
forall a. Endo a -> a -> a
appEndo (Endo WindowSet -> X ())
-> ([Window] -> X (Endo WindowSet)) -> [Window] -> X ()
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< Query (Endo WindowSet) -> Window -> X (Endo WindowSet)
forall a. Query a -> Window -> X a
runQuery Query (Endo WindowSet)
mh (Window -> X (Endo WindowSet))
-> ([Window] -> Window) -> [Window] -> X (Endo WindowSet)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Window] -> Window
forall a. [a] -> a
head)
runOrRaise :: String -> Query Bool -> X ()
runOrRaise :: WorkspaceId -> Query Bool -> X ()
runOrRaise = X () -> Query Bool -> X ()
raiseMaybe (X () -> Query Bool -> X ())
-> (WorkspaceId -> X ()) -> WorkspaceId -> Query Bool -> X ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. WorkspaceId -> X ()
forall (m :: * -> *). MonadIO m => WorkspaceId -> m ()
safeSpawnProg
raise :: Query Bool -> X ()
raise :: Query Bool -> X ()
raise = X () -> Query Bool -> X ()
raiseMaybe (X () -> Query Bool -> X ()) -> X () -> Query Bool -> X ()
forall a b. (a -> b) -> a -> b
$ () -> X ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
raiseMaybe :: X () -> Query Bool -> X ()
raiseMaybe :: X () -> Query Bool -> X ()
raiseMaybe X ()
f Query Bool
qry = Query Bool -> Query (Endo WindowSet) -> X () -> X ()
ifWindow Query Bool
qry Query (Endo WindowSet)
raiseHook X ()
f
raiseHook :: ManageHook
raiseHook :: Query (Endo WindowSet)
raiseHook = Query Window
forall r (m :: * -> *). MonadReader r m => m r
ask Query Window
-> (Window -> Query (Endo WindowSet)) -> Query (Endo WindowSet)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (WindowSet -> WindowSet) -> Query (Endo WindowSet)
forall s. (s -> s) -> Query (Endo s)
doF ((WindowSet -> WindowSet) -> Query (Endo WindowSet))
-> (Window -> WindowSet -> WindowSet)
-> Window
-> Query (Endo WindowSet)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Window -> WindowSet -> WindowSet
forall s a i l sd.
(Eq s, Eq a, Eq i) =>
a -> StackSet i l a s sd -> StackSet i l a s sd
W.focusWindow
runOrRaiseNext :: String -> Query Bool -> X ()
runOrRaiseNext :: WorkspaceId -> Query Bool -> X ()
runOrRaiseNext = X () -> Query Bool -> X ()
raiseNextMaybe (X () -> Query Bool -> X ())
-> (WorkspaceId -> X ()) -> WorkspaceId -> Query Bool -> X ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. WorkspaceId -> X ()
forall (m :: * -> *). MonadIO m => WorkspaceId -> m ()
safeSpawnProg
raiseNext :: Query Bool -> X ()
raiseNext :: Query Bool -> X ()
raiseNext = X () -> Query Bool -> X ()
raiseNextMaybe (X () -> Query Bool -> X ()) -> X () -> Query Bool -> X ()
forall a b. (a -> b) -> a -> b
$ () -> X ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
raiseNextMaybe :: X () -> Query Bool -> X ()
raiseNextMaybe :: X () -> Query Bool -> X ()
raiseNextMaybe = (Window -> WindowSet -> WindowSet) -> X () -> Query Bool -> X ()
raiseNextMaybeCustomFocus Window -> WindowSet -> WindowSet
forall s a i l sd.
(Eq s, Eq a, Eq i) =>
a -> StackSet i l a s sd -> StackSet i l a s sd
W.focusWindow
raiseNextMaybeCustomFocus :: (Window -> WindowSet -> WindowSet) -> X() -> Query Bool -> X()
raiseNextMaybeCustomFocus :: (Window -> WindowSet -> WindowSet) -> X () -> Query Bool -> X ()
raiseNextMaybeCustomFocus Window -> WindowSet -> WindowSet
focusFn X ()
f Query Bool
qry = (([Window] -> X ()) -> X () -> X ())
-> X () -> ([Window] -> X ()) -> X ()
forall a b c. (a -> b -> c) -> b -> a -> c
flip (Query Bool -> ([Window] -> X ()) -> X () -> X ()
ifWindows Query Bool
qry) X ()
f (([Window] -> X ()) -> X ()) -> ([Window] -> X ()) -> X ()
forall a b. (a -> b) -> a -> b
$ \[Window]
ws -> do
Maybe Window
foc <- (WindowSet -> X (Maybe Window)) -> X (Maybe Window)
forall a. (WindowSet -> X a) -> X a
withWindowSet ((WindowSet -> X (Maybe Window)) -> X (Maybe Window))
-> (WindowSet -> X (Maybe Window)) -> X (Maybe Window)
forall a b. (a -> b) -> a -> b
$ Maybe Window -> X (Maybe Window)
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe Window -> X (Maybe Window))
-> (WindowSet -> Maybe Window) -> WindowSet -> X (Maybe Window)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. WindowSet -> Maybe Window
forall i l a s sd. StackSet i l a s sd -> Maybe a
W.peek
case Maybe Window
foc of
Just Window
w | Window
w Window -> [Window] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Window]
ws ->
let ([Window] -> NonEmpty Window
forall a. HasCallStack => [a] -> NonEmpty a
notEmpty -> Window
_ :| ([Window] -> NonEmpty Window
forall a. HasCallStack => [a] -> NonEmpty a
notEmpty -> Window
y :| [Window]
_)) = (Window -> Bool) -> [Window] -> [Window]
forall a. (a -> Bool) -> [a] -> [a]
dropWhile (Window -> Window -> Bool
forall a. Eq a => a -> a -> Bool
/=Window
w) ([Window] -> [Window]) -> [Window] -> [Window]
forall a b. (a -> b) -> a -> b
$ [Window] -> [Window]
forall a. [a] -> [a]
cycle [Window]
ws
in (WindowSet -> WindowSet) -> X ()
windows ((WindowSet -> WindowSet) -> X ())
-> (WindowSet -> WindowSet) -> X ()
forall a b. (a -> b) -> a -> b
$ Window -> WindowSet -> WindowSet
focusFn Window
y
Maybe Window
_ -> (WindowSet -> WindowSet) -> X ()
windows ((WindowSet -> WindowSet) -> X ())
-> ([Window] -> WindowSet -> WindowSet) -> [Window] -> X ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Window -> WindowSet -> WindowSet
focusFn (Window -> WindowSet -> WindowSet)
-> ([Window] -> Window) -> [Window] -> WindowSet -> WindowSet
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Window] -> Window
forall a. [a] -> a
head ([Window] -> X ()) -> [Window] -> X ()
forall a b. (a -> b) -> a -> b
$ [Window]
ws
raiseVar :: IO String -> X ()
raiseVar :: IO WorkspaceId -> X ()
raiseVar IO WorkspaceId
getvar = IO WorkspaceId -> X WorkspaceId
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO IO WorkspaceId
getvar X WorkspaceId -> (WorkspaceId -> X ()) -> X ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \WorkspaceId
var -> WorkspaceId -> Query Bool -> X ()
runOrRaise WorkspaceId
var ((WorkspaceId -> WorkspaceId)
-> Query WorkspaceId -> Query WorkspaceId
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Char -> Char) -> WorkspaceId -> WorkspaceId
forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
toLower) Query WorkspaceId
className Query WorkspaceId -> WorkspaceId -> Query Bool
forall a. Eq a => Query a -> a -> Query Bool
=? WorkspaceId
var)
raiseBrowser, raiseEditor :: X ()
raiseBrowser :: X ()
raiseBrowser = IO WorkspaceId -> X ()
raiseVar IO WorkspaceId
getBrowser
raiseEditor :: X ()
raiseEditor = IO WorkspaceId -> X ()
raiseVar IO WorkspaceId
getEditor
raiseAndDo :: X () -> Query Bool -> (Window -> X ()) -> X ()
raiseAndDo :: X () -> Query Bool -> (Window -> X ()) -> X ()
raiseAndDo X ()
f Query Bool
qry Window -> X ()
after = Query Bool -> Query (Endo WindowSet) -> X () -> X ()
ifWindow Query Bool
qry (Query (Endo WindowSet)
afterRaise Query (Endo WindowSet)
-> Query (Endo WindowSet) -> Query (Endo WindowSet)
forall a. Monoid a => a -> a -> a
`mappend` Query (Endo WindowSet)
raiseHook) X ()
f
where afterRaise :: Query (Endo WindowSet)
afterRaise = Query Window
forall r (m :: * -> *). MonadReader r m => m r
ask Query Window
-> (Window -> Query (Endo WindowSet)) -> Query (Endo WindowSet)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (Query () -> Query (Endo WindowSet) -> Query (Endo WindowSet)
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Query (Endo WindowSet)
forall m. Monoid m => m
idHook) (Query () -> Query (Endo WindowSet))
-> (Window -> Query ()) -> Window -> Query (Endo WindowSet)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. X () -> Query ()
forall a. X a -> Query a
liftX (X () -> Query ()) -> (Window -> X ()) -> Window -> Query ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Window -> X ()
after
runOrRaiseAndDo :: String -> Query Bool -> (Window -> X ()) -> X ()
runOrRaiseAndDo :: WorkspaceId -> Query Bool -> (Window -> X ()) -> X ()
runOrRaiseAndDo = X () -> Query Bool -> (Window -> X ()) -> X ()
raiseAndDo (X () -> Query Bool -> (Window -> X ()) -> X ())
-> (WorkspaceId -> X ())
-> WorkspaceId
-> Query Bool
-> (Window -> X ())
-> X ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. WorkspaceId -> X ()
forall (m :: * -> *). MonadIO m => WorkspaceId -> m ()
safeSpawnProg
raiseMaster :: X () -> Query Bool -> X ()
raiseMaster :: X () -> Query Bool -> X ()
raiseMaster X ()
raisef Query Bool
thatUserQuery = X () -> Query Bool -> (Window -> X ()) -> X ()
raiseAndDo X ()
raisef Query Bool
thatUserQuery (\Window
_ -> (WindowSet -> WindowSet) -> X ()
windows WindowSet -> WindowSet
forall i l a s sd. StackSet i l a s sd -> StackSet i l a s sd
W.swapMaster)
runOrRaiseMaster :: String -> Query Bool -> X ()
runOrRaiseMaster :: WorkspaceId -> Query Bool -> X ()
runOrRaiseMaster WorkspaceId
run Query Bool
query = WorkspaceId -> Query Bool -> (Window -> X ()) -> X ()
runOrRaiseAndDo WorkspaceId
run Query Bool
query (\Window
_ -> (WindowSet -> WindowSet) -> X ()
windows WindowSet -> WindowSet
forall i l a s sd. StackSet i l a s sd -> StackSet i l a s sd
W.swapMaster)