{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, MultiWayIf #-}
module XMonad.Hooks.RefocusLast (
refocusLastLogHook,
refocusLastLayoutHook,
refocusLastWhen,
refocusingIsActive,
isFloat,
toggleRefocusing,
toggleFocus,
swapWithLast,
refocusWhen,
shiftRLWhen,
updateRecentsOn,
RecentWins(..),
RecentsMap(..),
RefocusLastLayoutHook(..),
RefocusLastToggle(..),
withRecentsIn,
) where
import XMonad
import XMonad.Prelude (All (..), asum, fromMaybe, when)
import qualified XMonad.StackSet as W
import qualified XMonad.Util.ExtensibleState as XS
import XMonad.Util.Stack (findS, mapZ_)
import XMonad.Layout.LayoutModifier
import qualified Data.Map.Strict as M
data RecentWins = Recent { RecentWins -> Window
previous :: !Window, RecentWins -> Window
current :: !Window }
deriving (Int -> RecentWins -> ShowS
[RecentWins] -> ShowS
RecentWins -> WorkspaceId
(Int -> RecentWins -> ShowS)
-> (RecentWins -> WorkspaceId)
-> ([RecentWins] -> ShowS)
-> Show RecentWins
forall a.
(Int -> a -> ShowS)
-> (a -> WorkspaceId) -> ([a] -> ShowS) -> Show a
showList :: [RecentWins] -> ShowS
$cshowList :: [RecentWins] -> ShowS
show :: RecentWins -> WorkspaceId
$cshow :: RecentWins -> WorkspaceId
showsPrec :: Int -> RecentWins -> ShowS
$cshowsPrec :: Int -> RecentWins -> ShowS
Show, ReadPrec [RecentWins]
ReadPrec RecentWins
Int -> ReadS RecentWins
ReadS [RecentWins]
(Int -> ReadS RecentWins)
-> ReadS [RecentWins]
-> ReadPrec RecentWins
-> ReadPrec [RecentWins]
-> Read RecentWins
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [RecentWins]
$creadListPrec :: ReadPrec [RecentWins]
readPrec :: ReadPrec RecentWins
$creadPrec :: ReadPrec RecentWins
readList :: ReadS [RecentWins]
$creadList :: ReadS [RecentWins]
readsPrec :: Int -> ReadS RecentWins
$creadsPrec :: Int -> ReadS RecentWins
Read, RecentWins -> RecentWins -> Bool
(RecentWins -> RecentWins -> Bool)
-> (RecentWins -> RecentWins -> Bool) -> Eq RecentWins
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: RecentWins -> RecentWins -> Bool
$c/= :: RecentWins -> RecentWins -> Bool
== :: RecentWins -> RecentWins -> Bool
$c== :: RecentWins -> RecentWins -> Bool
Eq)
newtype RecentsMap = RecentsMap (M.Map WorkspaceId RecentWins)
deriving (Int -> RecentsMap -> ShowS
[RecentsMap] -> ShowS
RecentsMap -> WorkspaceId
(Int -> RecentsMap -> ShowS)
-> (RecentsMap -> WorkspaceId)
-> ([RecentsMap] -> ShowS)
-> Show RecentsMap
forall a.
(Int -> a -> ShowS)
-> (a -> WorkspaceId) -> ([a] -> ShowS) -> Show a
showList :: [RecentsMap] -> ShowS
$cshowList :: [RecentsMap] -> ShowS
show :: RecentsMap -> WorkspaceId
$cshow :: RecentsMap -> WorkspaceId
showsPrec :: Int -> RecentsMap -> ShowS
$cshowsPrec :: Int -> RecentsMap -> ShowS
Show, ReadPrec [RecentsMap]
ReadPrec RecentsMap
Int -> ReadS RecentsMap
ReadS [RecentsMap]
(Int -> ReadS RecentsMap)
-> ReadS [RecentsMap]
-> ReadPrec RecentsMap
-> ReadPrec [RecentsMap]
-> Read RecentsMap
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [RecentsMap]
$creadListPrec :: ReadPrec [RecentsMap]
readPrec :: ReadPrec RecentsMap
$creadPrec :: ReadPrec RecentsMap
readList :: ReadS [RecentsMap]
$creadList :: ReadS [RecentsMap]
readsPrec :: Int -> ReadS RecentsMap
$creadsPrec :: Int -> ReadS RecentsMap
Read, RecentsMap -> RecentsMap -> Bool
(RecentsMap -> RecentsMap -> Bool)
-> (RecentsMap -> RecentsMap -> Bool) -> Eq RecentsMap
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: RecentsMap -> RecentsMap -> Bool
$c/= :: RecentsMap -> RecentsMap -> Bool
== :: RecentsMap -> RecentsMap -> Bool
$c== :: RecentsMap -> RecentsMap -> Bool
Eq)
instance ExtensionClass RecentsMap where
initialValue :: RecentsMap
initialValue = Map WorkspaceId RecentWins -> RecentsMap
RecentsMap Map WorkspaceId RecentWins
forall k a. Map k a
M.empty
extensionType :: RecentsMap -> StateExtension
extensionType = RecentsMap -> StateExtension
forall a. (Read a, Show a, ExtensionClass a) => a -> StateExtension
PersistentExtension
data RefocusLastLayoutHook a = RefocusLastLayoutHook
deriving (Int -> RefocusLastLayoutHook a -> ShowS
[RefocusLastLayoutHook a] -> ShowS
RefocusLastLayoutHook a -> WorkspaceId
(Int -> RefocusLastLayoutHook a -> ShowS)
-> (RefocusLastLayoutHook a -> WorkspaceId)
-> ([RefocusLastLayoutHook a] -> ShowS)
-> Show (RefocusLastLayoutHook a)
forall a. Int -> RefocusLastLayoutHook a -> ShowS
forall a. [RefocusLastLayoutHook a] -> ShowS
forall a. RefocusLastLayoutHook a -> WorkspaceId
forall a.
(Int -> a -> ShowS)
-> (a -> WorkspaceId) -> ([a] -> ShowS) -> Show a
showList :: [RefocusLastLayoutHook a] -> ShowS
$cshowList :: forall a. [RefocusLastLayoutHook a] -> ShowS
show :: RefocusLastLayoutHook a -> WorkspaceId
$cshow :: forall a. RefocusLastLayoutHook a -> WorkspaceId
showsPrec :: Int -> RefocusLastLayoutHook a -> ShowS
$cshowsPrec :: forall a. Int -> RefocusLastLayoutHook a -> ShowS
Show, ReadPrec [RefocusLastLayoutHook a]
ReadPrec (RefocusLastLayoutHook a)
Int -> ReadS (RefocusLastLayoutHook a)
ReadS [RefocusLastLayoutHook a]
(Int -> ReadS (RefocusLastLayoutHook a))
-> ReadS [RefocusLastLayoutHook a]
-> ReadPrec (RefocusLastLayoutHook a)
-> ReadPrec [RefocusLastLayoutHook a]
-> Read (RefocusLastLayoutHook a)
forall a. ReadPrec [RefocusLastLayoutHook a]
forall a. ReadPrec (RefocusLastLayoutHook a)
forall a. Int -> ReadS (RefocusLastLayoutHook a)
forall a. ReadS [RefocusLastLayoutHook a]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [RefocusLastLayoutHook a]
$creadListPrec :: forall a. ReadPrec [RefocusLastLayoutHook a]
readPrec :: ReadPrec (RefocusLastLayoutHook a)
$creadPrec :: forall a. ReadPrec (RefocusLastLayoutHook a)
readList :: ReadS [RefocusLastLayoutHook a]
$creadList :: forall a. ReadS [RefocusLastLayoutHook a]
readsPrec :: Int -> ReadS (RefocusLastLayoutHook a)
$creadsPrec :: forall a. Int -> ReadS (RefocusLastLayoutHook a)
Read)
instance LayoutModifier RefocusLastLayoutHook a where
modifyLayout :: forall (l :: * -> *).
LayoutClass l a =>
RefocusLastLayoutHook a
-> Workspace WorkspaceId (l a) a
-> Rectangle
-> X ([(a, Rectangle)], Maybe (l a))
modifyLayout RefocusLastLayoutHook a
_ w :: Workspace WorkspaceId (l a) a
w@(W.Workspace WorkspaceId
tg l a
_ Maybe (Stack a)
_) Rectangle
r = WorkspaceId -> X ()
updateRecentsOn WorkspaceId
tg X ()
-> X ([(a, Rectangle)], Maybe (l a))
-> X ([(a, Rectangle)], Maybe (l a))
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Workspace WorkspaceId (l a) a
-> Rectangle -> X ([(a, Rectangle)], Maybe (l a))
forall (layout :: * -> *) a.
LayoutClass layout a =>
Workspace WorkspaceId (layout a) a
-> Rectangle -> X ([(a, Rectangle)], Maybe (layout a))
runLayout Workspace WorkspaceId (l a) a
w Rectangle
r
newtype RefocusLastToggle = RefocusLastToggle { RefocusLastToggle -> Bool
refocusing :: Bool }
deriving (Int -> RefocusLastToggle -> ShowS
[RefocusLastToggle] -> ShowS
RefocusLastToggle -> WorkspaceId
(Int -> RefocusLastToggle -> ShowS)
-> (RefocusLastToggle -> WorkspaceId)
-> ([RefocusLastToggle] -> ShowS)
-> Show RefocusLastToggle
forall a.
(Int -> a -> ShowS)
-> (a -> WorkspaceId) -> ([a] -> ShowS) -> Show a
showList :: [RefocusLastToggle] -> ShowS
$cshowList :: [RefocusLastToggle] -> ShowS
show :: RefocusLastToggle -> WorkspaceId
$cshow :: RefocusLastToggle -> WorkspaceId
showsPrec :: Int -> RefocusLastToggle -> ShowS
$cshowsPrec :: Int -> RefocusLastToggle -> ShowS
Show, ReadPrec [RefocusLastToggle]
ReadPrec RefocusLastToggle
Int -> ReadS RefocusLastToggle
ReadS [RefocusLastToggle]
(Int -> ReadS RefocusLastToggle)
-> ReadS [RefocusLastToggle]
-> ReadPrec RefocusLastToggle
-> ReadPrec [RefocusLastToggle]
-> Read RefocusLastToggle
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [RefocusLastToggle]
$creadListPrec :: ReadPrec [RefocusLastToggle]
readPrec :: ReadPrec RefocusLastToggle
$creadPrec :: ReadPrec RefocusLastToggle
readList :: ReadS [RefocusLastToggle]
$creadList :: ReadS [RefocusLastToggle]
readsPrec :: Int -> ReadS RefocusLastToggle
$creadsPrec :: Int -> ReadS RefocusLastToggle
Read, RefocusLastToggle -> RefocusLastToggle -> Bool
(RefocusLastToggle -> RefocusLastToggle -> Bool)
-> (RefocusLastToggle -> RefocusLastToggle -> Bool)
-> Eq RefocusLastToggle
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: RefocusLastToggle -> RefocusLastToggle -> Bool
$c/= :: RefocusLastToggle -> RefocusLastToggle -> Bool
== :: RefocusLastToggle -> RefocusLastToggle -> Bool
$c== :: RefocusLastToggle -> RefocusLastToggle -> Bool
Eq)
instance ExtensionClass RefocusLastToggle where
initialValue :: RefocusLastToggle
initialValue = RefocusLastToggle :: Bool -> RefocusLastToggle
RefocusLastToggle { refocusing :: Bool
refocusing = Bool
True }
extensionType :: RefocusLastToggle -> StateExtension
extensionType = RefocusLastToggle -> StateExtension
forall a. (Read a, Show a, ExtensionClass a) => a -> StateExtension
PersistentExtension
refocusLastLogHook :: X ()
refocusLastLogHook :: X ()
refocusLastLogHook = (WindowSet -> X ()) -> X ()
forall a. (WindowSet -> X a) -> X a
withWindowSet (WorkspaceId -> X ()
updateRecentsOn (WorkspaceId -> X ())
-> (WindowSet -> WorkspaceId) -> WindowSet -> X ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. WindowSet -> WorkspaceId
forall i l a s sd. StackSet i l a s sd -> i
W.currentTag)
refocusLastLayoutHook :: l a -> ModifiedLayout RefocusLastLayoutHook l a
refocusLastLayoutHook :: forall (l :: * -> *) a.
l a -> ModifiedLayout RefocusLastLayoutHook l a
refocusLastLayoutHook = RefocusLastLayoutHook a
-> l a -> ModifiedLayout RefocusLastLayoutHook l a
forall (m :: * -> *) (l :: * -> *) a.
m a -> l a -> ModifiedLayout m l a
ModifiedLayout RefocusLastLayoutHook a
forall a. RefocusLastLayoutHook a
RefocusLastLayoutHook
refocusLastWhen :: Query Bool -> Event -> X All
refocusLastWhen :: Query Bool -> Event -> X All
refocusLastWhen Query Bool
p Event
event = Bool -> All
All Bool
True All -> X () -> X All
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ case Event
event of
UnmapEvent { ev_send_event :: Event -> Bool
ev_send_event = Bool
synth, ev_window :: Event -> Window
ev_window = Window
w } -> do
Int
e <- (XState -> Int) -> X Int
forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets (Int -> Maybe Int -> Int
forall a. a -> Maybe a -> a
fromMaybe Int
0 (Maybe Int -> Int) -> (XState -> Maybe Int) -> XState -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Window -> Map Window Int -> Maybe Int
forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup Window
w (Map Window Int -> Maybe Int)
-> (XState -> Map Window Int) -> XState -> Maybe Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. XState -> Map Window Int
waitingUnmap)
Bool -> X () -> X ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Bool
synth Bool -> Bool -> Bool
|| Int
e Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0) (Window -> X ()
refocusLast Window
w)
DestroyWindowEvent { ev_window :: Event -> Window
ev_window = Window
w } -> Window -> X ()
refocusLast Window
w
Event
_ -> () -> X ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
where
refocusLast :: Window -> X ()
refocusLast Window
w = X Bool -> X () -> X ()
whenX (Query Bool -> Window -> X Bool
forall a. Query a -> Window -> X a
runQuery Query Bool
p Window
w) (X () -> X ())
-> ((WindowSet -> X ()) -> X ()) -> (WindowSet -> X ()) -> X ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (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
ws ->
Maybe WorkspaceId -> (WorkspaceId -> X ()) -> X ()
forall (m :: * -> *) a. Monad m => Maybe a -> (a -> m ()) -> m ()
whenJust (Window -> WindowSet -> Maybe WorkspaceId
forall a i l s sd. Eq a => a -> StackSet i l a s sd -> Maybe i
W.findTag Window
w WindowSet
ws) ((WorkspaceId -> X ()) -> X ()) -> (WorkspaceId -> X ()) -> X ()
forall a b. (a -> b) -> a -> b
$ \WorkspaceId
tag ->
WorkspaceId -> () -> (Window -> Window -> X ()) -> X ()
forall a. WorkspaceId -> a -> (Window -> Window -> X a) -> X a
withRecentsIn WorkspaceId
tag () ((Window -> Window -> X ()) -> X ())
-> (Window -> Window -> X ()) -> X ()
forall a b. (a -> b) -> a -> b
$ \Window
lw Window
cw ->
Bool -> X () -> X ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Window
w Window -> Window -> Bool
forall a. Eq a => a -> a -> Bool
== Window
cw) (X () -> X ())
-> ((XState -> XState) -> X ()) -> (XState -> XState) -> X ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (XState -> XState) -> X ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify ((XState -> XState) -> X ()) -> (XState -> XState) -> X ()
forall a b. (a -> b) -> a -> b
$ \XState
xs ->
XState
xs { windowset :: WindowSet
windowset = WorkspaceId -> [Window] -> WindowSet -> WindowSet
tryFocusIn WorkspaceId
tag [Window
lw] WindowSet
ws }
refocusingIsActive :: Query Bool
refocusingIsActive :: Query Bool
refocusingIsActive = (X Bool -> Query Bool
forall a. X a -> Query a
liftX (X Bool -> Query Bool)
-> ((RefocusLastToggle -> Bool) -> X Bool)
-> (RefocusLastToggle -> Bool)
-> Query Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (RefocusLastToggle -> Bool) -> X Bool
forall a (m :: * -> *) b.
(ExtensionClass a, XLike m) =>
(a -> b) -> m b
XS.gets) RefocusLastToggle -> Bool
refocusing
isFloat :: Query Bool
isFloat :: Query Bool
isFloat = Query Window
forall r (m :: * -> *). MonadReader r m => m r
ask Query Window -> (Window -> Query Bool) -> Query Bool
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Window
w -> (X Bool -> Query Bool
forall a. X a -> Query a
liftX (X Bool -> Query Bool)
-> ((XState -> Bool) -> X Bool) -> (XState -> Bool) -> Query Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (XState -> Bool) -> X Bool
forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets) (Window -> Map Window RationalRect -> Bool
forall k a. Ord k => k -> Map k a -> Bool
M.member Window
w (Map Window RationalRect -> Bool)
-> (XState -> Map Window RationalRect) -> XState -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. WindowSet -> Map Window RationalRect
forall i l a sid sd. StackSet i l a sid sd -> Map a RationalRect
W.floating (WindowSet -> Map Window RationalRect)
-> (XState -> WindowSet) -> XState -> Map Window RationalRect
forall b c a. (b -> c) -> (a -> b) -> a -> c
. XState -> WindowSet
windowset)
toggleRefocusing :: X ()
toggleRefocusing :: X ()
toggleRefocusing = (RefocusLastToggle -> RefocusLastToggle) -> X ()
forall a (m :: * -> *).
(ExtensionClass a, XLike m) =>
(a -> a) -> m ()
XS.modify (Bool -> RefocusLastToggle
RefocusLastToggle (Bool -> RefocusLastToggle)
-> (RefocusLastToggle -> Bool)
-> RefocusLastToggle
-> RefocusLastToggle
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> Bool
not (Bool -> Bool)
-> (RefocusLastToggle -> Bool) -> RefocusLastToggle -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RefocusLastToggle -> Bool
refocusing)
toggleFocus :: X ()
toggleFocus :: X ()
toggleFocus = (Window -> Window -> X ()) -> X ()
withRecents ((Window -> Window -> X ()) -> X ())
-> (Window -> Window -> X ()) -> X ()
forall a b. (a -> b) -> a -> b
$ \Window
lw Window
cw ->
Bool -> X () -> X ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Window
cw Window -> Window -> Bool
forall a. Eq a => a -> a -> Bool
/= Window
lw) (X () -> X ())
-> ((WindowSet -> WindowSet) -> X ())
-> (WindowSet -> WindowSet)
-> X ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (WindowSet -> WindowSet) -> X ()
windows ((WindowSet -> WindowSet) -> X ())
-> (WindowSet -> WindowSet) -> X ()
forall a b. (a -> b) -> a -> b
$ [Window] -> WindowSet -> WindowSet
tryFocus [Window
lw]
swapWithLast :: X ()
swapWithLast :: X ()
swapWithLast = (Window -> Window -> X ()) -> X ()
withRecents ((Window -> Window -> X ()) -> X ())
-> (Window -> Window -> X ()) -> X ()
forall a b. (a -> b) -> a -> b
$ \Window
lw Window
cw ->
Bool -> X () -> X ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Window
cw Window -> Window -> Bool
forall a. Eq a => a -> a -> Bool
/= Window
lw) (X () -> X ())
-> ((Window -> Window) -> X ()) -> (Window -> Window) -> X ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (WindowSet -> WindowSet) -> X ()
windows ((WindowSet -> WindowSet) -> X ())
-> ((Window -> Window) -> WindowSet -> WindowSet)
-> (Window -> Window)
-> X ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Maybe (Stack Window) -> Maybe (Stack Window))
-> WindowSet -> WindowSet
forall {a} {i} {l} {s} {sd}.
(Maybe (Stack a) -> Maybe (Stack a))
-> StackSet i l a s sd -> StackSet i l a s sd
modify''((Maybe (Stack Window) -> Maybe (Stack Window))
-> WindowSet -> WindowSet)
-> ((Window -> Window)
-> Maybe (Stack Window) -> Maybe (Stack Window))
-> (Window -> Window)
-> WindowSet
-> WindowSet
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Window -> Window) -> Maybe (Stack Window) -> Maybe (Stack Window)
forall a b. (a -> b) -> Zipper a -> Zipper b
mapZ_ ((Window -> Window) -> X ()) -> (Window -> Window) -> X ()
forall a b. (a -> b) -> a -> b
$ \Window
w ->
if | (Window
w Window -> Window -> Bool
forall a. Eq a => a -> a -> Bool
== Window
lw) -> Window
cw
| (Window
w Window -> Window -> Bool
forall a. Eq a => a -> a -> Bool
== Window
cw) -> Window
lw
| Bool
otherwise -> Window
w
where modify'' :: (Maybe (Stack a) -> Maybe (Stack a))
-> StackSet i l a s sd -> StackSet i l a s sd
modify'' Maybe (Stack a) -> Maybe (Stack a)
f = Maybe (Stack a)
-> (Stack a -> Maybe (Stack a))
-> StackSet i l a s sd
-> StackSet i l a s sd
forall a i l s sd.
Maybe (Stack a)
-> (Stack a -> Maybe (Stack a))
-> StackSet i l a s sd
-> StackSet i l a s sd
W.modify (Maybe (Stack a) -> Maybe (Stack a)
f Maybe (Stack a)
forall a. Maybe a
Nothing) (Maybe (Stack a) -> Maybe (Stack a)
f (Maybe (Stack a) -> Maybe (Stack a))
-> (Stack a -> Maybe (Stack a)) -> Stack a -> Maybe (Stack a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Stack a -> Maybe (Stack a)
forall a. a -> Maybe a
Just)
refocusWhen :: Query Bool -> WorkspaceId -> X (WindowSet -> WindowSet)
refocusWhen :: Query Bool -> WorkspaceId -> X (WindowSet -> WindowSet)
refocusWhen Query Bool
p WorkspaceId
tag = WorkspaceId
-> (WindowSet -> WindowSet)
-> (Window -> Window -> X (WindowSet -> WindowSet))
-> X (WindowSet -> WindowSet)
forall a. WorkspaceId -> a -> (Window -> Window -> X a) -> X a
withRecentsIn WorkspaceId
tag WindowSet -> WindowSet
forall a. a -> a
id ((Window -> Window -> X (WindowSet -> WindowSet))
-> X (WindowSet -> WindowSet))
-> (Window -> Window -> X (WindowSet -> WindowSet))
-> X (WindowSet -> WindowSet)
forall a b. (a -> b) -> a -> b
$ \Window
lw Window
cw -> do
Bool
b <- Query Bool -> Window -> X Bool
forall a. Query a -> Window -> X a
runQuery Query Bool
p Window
cw
(WindowSet -> WindowSet) -> X (WindowSet -> WindowSet)
forall (m :: * -> *) a. Monad m => a -> m a
return (if Bool
b then WorkspaceId -> [Window] -> WindowSet -> WindowSet
tryFocusIn WorkspaceId
tag [Window
cw, Window
lw] else WindowSet -> WindowSet
forall a. a -> a
id)
shiftRLWhen :: Query Bool -> WorkspaceId -> X (WindowSet -> WindowSet)
shiftRLWhen :: Query Bool -> WorkspaceId -> X (WindowSet -> WindowSet)
shiftRLWhen Query Bool
p WorkspaceId
to = (WindowSet -> X (WindowSet -> WindowSet))
-> X (WindowSet -> WindowSet)
forall a. (WindowSet -> X a) -> X a
withWindowSet ((WindowSet -> X (WindowSet -> WindowSet))
-> X (WindowSet -> WindowSet))
-> (WindowSet -> X (WindowSet -> WindowSet))
-> X (WindowSet -> WindowSet)
forall a b. (a -> b) -> a -> b
$ \WindowSet
ws -> do
WindowSet -> WindowSet
refocus <- Query Bool -> WorkspaceId -> X (WindowSet -> WindowSet)
refocusWhen Query Bool
p (WindowSet -> WorkspaceId
forall i l a s sd. StackSet i l a s sd -> i
W.currentTag WindowSet
ws)
let shift :: StackSet WorkspaceId l Window ScreenId sd
-> StackSet WorkspaceId l Window ScreenId sd
shift = (StackSet WorkspaceId l Window ScreenId sd
-> StackSet WorkspaceId l Window ScreenId sd)
-> (Window
-> StackSet WorkspaceId l Window ScreenId sd
-> StackSet WorkspaceId l Window ScreenId sd)
-> Maybe Window
-> StackSet WorkspaceId l Window ScreenId sd
-> StackSet WorkspaceId l Window ScreenId sd
forall b a. b -> (a -> b) -> Maybe a -> b
maybe StackSet WorkspaceId l Window ScreenId sd
-> StackSet WorkspaceId l Window ScreenId sd
forall a. a -> a
id (WorkspaceId
-> Window
-> StackSet WorkspaceId l Window ScreenId sd
-> StackSet WorkspaceId l Window ScreenId sd
forall a s i l sd.
(Ord a, Eq s, Eq i) =>
i -> a -> StackSet i l a s sd -> StackSet i l a s sd
W.shiftWin WorkspaceId
to) (WindowSet -> Maybe Window
forall i l a s sd. StackSet i l a s sd -> Maybe a
W.peek WindowSet
ws)
(WindowSet -> WindowSet) -> X (WindowSet -> WindowSet)
forall (m :: * -> *) a. Monad m => a -> m a
return (WindowSet -> WindowSet
refocus (WindowSet -> WindowSet)
-> (WindowSet -> WindowSet) -> WindowSet -> WindowSet
forall b c a. (b -> c) -> (a -> b) -> a -> c
. WindowSet -> WindowSet
forall {l} {sd}.
StackSet WorkspaceId l Window ScreenId sd
-> StackSet WorkspaceId l Window ScreenId sd
shift)
updateRecentsOn :: WorkspaceId -> X ()
updateRecentsOn :: WorkspaceId -> X ()
updateRecentsOn WorkspaceId
tag = (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
ws ->
Maybe Window -> (Window -> X ()) -> X ()
forall (m :: * -> *) a. Monad m => Maybe a -> (a -> m ()) -> m ()
whenJust (WindowSet -> Maybe Window
forall i l a s sd. StackSet i l a s sd -> Maybe a
W.peek (WindowSet -> Maybe Window) -> WindowSet -> Maybe Window
forall a b. (a -> b) -> a -> b
$ 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
W.view WorkspaceId
tag WindowSet
ws) ((Window -> X ()) -> X ()) -> (Window -> X ()) -> X ()
forall a b. (a -> b) -> a -> b
$ \Window
fw -> do
Map WorkspaceId RecentWins
m <- X (Map WorkspaceId RecentWins)
getRecentsMap
let insertRecent :: Window -> Window -> m ()
insertRecent Window
l Window
c = RecentsMap -> m ()
forall a (m :: * -> *). (ExtensionClass a, XLike m) => a -> m ()
XS.put (RecentsMap -> m ())
-> (Map WorkspaceId RecentWins -> RecentsMap)
-> Map WorkspaceId RecentWins
-> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Map WorkspaceId RecentWins -> RecentsMap
RecentsMap (Map WorkspaceId RecentWins -> m ())
-> Map WorkspaceId RecentWins -> m ()
forall a b. (a -> b) -> a -> b
$ WorkspaceId
-> RecentWins
-> Map WorkspaceId RecentWins
-> Map WorkspaceId RecentWins
forall k a. Ord k => k -> a -> Map k a -> Map k a
M.insert WorkspaceId
tag (Window -> Window -> RecentWins
Recent Window
l Window
c) Map WorkspaceId RecentWins
m
case WorkspaceId -> Map WorkspaceId RecentWins -> Maybe RecentWins
forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup WorkspaceId
tag Map WorkspaceId RecentWins
m of
Just (Recent Window
_ Window
cw) -> Bool -> X () -> X ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Window
cw Window -> Window -> Bool
forall a. Eq a => a -> a -> Bool
/= Window
fw) (Window -> Window -> X ()
forall {m :: * -> *}. XLike m => Window -> Window -> m ()
insertRecent Window
cw Window
fw)
Maybe RecentWins
Nothing -> Window -> Window -> X ()
forall {m :: * -> *}. XLike m => Window -> Window -> m ()
insertRecent Window
fw Window
fw
tryFocus :: [Window] -> WindowSet -> WindowSet
tryFocus :: [Window] -> WindowSet -> WindowSet
tryFocus [Window]
wins = (Stack Window -> Stack Window) -> WindowSet -> WindowSet
forall a i l s sd.
(Stack a -> Stack a) -> StackSet i l a s sd -> StackSet i l a s sd
W.modify' ((Stack Window -> Stack Window) -> WindowSet -> WindowSet)
-> (Stack Window -> Stack Window) -> WindowSet -> WindowSet
forall a b. (a -> b) -> a -> b
$ \Stack Window
s ->
Stack Window -> Maybe (Stack Window) -> Stack Window
forall a. a -> Maybe a -> a
fromMaybe Stack Window
s (Maybe (Stack Window) -> Stack Window)
-> ([Maybe (Stack Window)] -> Maybe (Stack Window))
-> [Maybe (Stack Window)]
-> Stack Window
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Maybe (Stack Window)] -> Maybe (Stack Window)
forall (t :: * -> *) (f :: * -> *) a.
(Foldable t, Alternative f) =>
t (f a) -> f a
asum ([Maybe (Stack Window)] -> Stack Window)
-> [Maybe (Stack Window)] -> Stack Window
forall a b. (a -> b) -> a -> b
$ (\Window
w -> (Window -> Bool) -> Stack Window -> Maybe (Stack Window)
forall a. (a -> Bool) -> Stack a -> Maybe (Stack a)
findS (Window -> Window -> Bool
forall a. Eq a => a -> a -> Bool
== Window
w) Stack Window
s) (Window -> Maybe (Stack Window))
-> [Window] -> [Maybe (Stack Window)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Window]
wins
tryFocusIn :: WorkspaceId -> [Window] -> WindowSet -> WindowSet
tryFocusIn :: WorkspaceId -> [Window] -> WindowSet -> WindowSet
tryFocusIn WorkspaceId
tag [Window]
wins WindowSet
ws =
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
W.view (WindowSet -> WorkspaceId
forall i l a s sd. StackSet i l a s sd -> i
W.currentTag WindowSet
ws) (WindowSet -> WindowSet)
-> (WindowSet -> WindowSet) -> WindowSet -> WindowSet
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Window] -> WindowSet -> WindowSet
tryFocus [Window]
wins (WindowSet -> WindowSet)
-> (WindowSet -> WindowSet) -> WindowSet -> WindowSet
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
W.view WorkspaceId
tag (WindowSet -> WindowSet) -> WindowSet -> WindowSet
forall a b. (a -> b) -> a -> b
$ WindowSet
ws
getRecentsMap :: X (M.Map WorkspaceId RecentWins)
getRecentsMap :: X (Map WorkspaceId RecentWins)
getRecentsMap = X RecentsMap
forall a (m :: * -> *). (ExtensionClass a, XLike m) => m a
XS.get X RecentsMap
-> (RecentsMap -> X (Map WorkspaceId RecentWins))
-> X (Map WorkspaceId RecentWins)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \(RecentsMap Map WorkspaceId RecentWins
m) -> Map WorkspaceId RecentWins -> X (Map WorkspaceId RecentWins)
forall (m :: * -> *) a. Monad m => a -> m a
return Map WorkspaceId RecentWins
m
withRecentsIn :: WorkspaceId -> a -> (Window -> Window -> X a) -> X a
withRecentsIn :: forall a. WorkspaceId -> a -> (Window -> Window -> X a) -> X a
withRecentsIn WorkspaceId
tag a
dflt Window -> Window -> X a
f = X a -> (RecentWins -> X a) -> Maybe RecentWins -> X a
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (a -> X a
forall (m :: * -> *) a. Monad m => a -> m a
return a
dflt) (\(Recent Window
lw Window
cw) -> Window -> Window -> X a
f Window
lw Window
cw)
(Maybe RecentWins -> X a)
-> (Map WorkspaceId RecentWins -> Maybe RecentWins)
-> Map WorkspaceId RecentWins
-> X a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. WorkspaceId -> Map WorkspaceId RecentWins -> Maybe RecentWins
forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup WorkspaceId
tag
(Map WorkspaceId RecentWins -> X a)
-> X (Map WorkspaceId RecentWins) -> X a
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< X (Map WorkspaceId RecentWins)
getRecentsMap
withRecents :: (Window -> Window -> X ()) -> X ()
withRecents :: (Window -> Window -> X ()) -> X ()
withRecents Window -> Window -> X ()
f = (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
ws -> WorkspaceId -> () -> (Window -> Window -> X ()) -> X ()
forall a. WorkspaceId -> a -> (Window -> Window -> X a) -> X a
withRecentsIn (WindowSet -> WorkspaceId
forall i l a s sd. StackSet i l a s sd -> i
W.currentTag WindowSet
ws) () Window -> Window -> X ()
f