mirror of
https://github.com/xmonad/xmonad-contrib.git
synced 2025-08-01 12:41:52 -07:00
X.H.RefocusLast: added action to swap current window with last + minor refactoring.
This commit is contained in:
committed by
Roosembert Palacios
parent
9c6d1e696f
commit
04b32ae021
@@ -1,4 +1,4 @@
|
|||||||
{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-}
|
{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, MultiWayIf #-}
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
-- |
|
-- |
|
||||||
@@ -32,6 +32,7 @@ module XMonad.Hooks.RefocusLast (
|
|||||||
-- * Actions
|
-- * Actions
|
||||||
toggleRefocusing,
|
toggleRefocusing,
|
||||||
toggleFocus,
|
toggleFocus,
|
||||||
|
swapWithLast,
|
||||||
refocusWhen,
|
refocusWhen,
|
||||||
shiftRLWhen,
|
shiftRLWhen,
|
||||||
updateRecentsOn,
|
updateRecentsOn,
|
||||||
@@ -46,7 +47,7 @@ module XMonad.Hooks.RefocusLast (
|
|||||||
import XMonad
|
import XMonad
|
||||||
import qualified XMonad.StackSet as W
|
import qualified XMonad.StackSet as W
|
||||||
import qualified XMonad.Util.ExtensibleState as XS
|
import qualified XMonad.Util.ExtensibleState as XS
|
||||||
import XMonad.Util.Stack (findS)
|
import XMonad.Util.Stack (findS, mapZ_)
|
||||||
import XMonad.Layout.LayoutModifier
|
import XMonad.Layout.LayoutModifier
|
||||||
|
|
||||||
import Data.Maybe (fromMaybe)
|
import Data.Maybe (fromMaybe)
|
||||||
@@ -84,12 +85,12 @@ import Control.Monad (when)
|
|||||||
-- > -- , layoutHook = refocusLastLayoutHook $ layoutHook def
|
-- > -- , layoutHook = refocusLastLayoutHook $ layoutHook def
|
||||||
-- > , keys = refocusLastKeys <+> keys def
|
-- > , keys = refocusLastKeys <+> keys def
|
||||||
-- > } where
|
-- > } where
|
||||||
-- > myPred = refocusingIsActive
|
-- > myPred = refocusingIsActive <||> isFloat
|
||||||
-- > -- myPred = refocusingIsActive <||> isFloat
|
|
||||||
-- > refocusLastKeys cnf
|
-- > refocusLastKeys cnf
|
||||||
-- > = M.fromList
|
-- > = M.fromList
|
||||||
-- > $ ((modMask cnf, xK_a), toggleRefocusing)
|
-- > $ ((modMask cnf , xK_a), toggleFocus)
|
||||||
-- > : ((modMask cnf, xK_b), toggleFocus)
|
-- > : ((modMask cnf .|. shiftMask, xK_a), swapWithLast)
|
||||||
|
-- > : ((modMask cnf , xK_b), toggleRefocusing)
|
||||||
-- > : [ ( (modMask cnf .|. shiftMask, n)
|
-- > : [ ( (modMask cnf .|. shiftMask, n)
|
||||||
-- > , windows =<< shiftRLWhen myPred wksp
|
-- > , windows =<< shiftRLWhen myPred wksp
|
||||||
-- > )
|
-- > )
|
||||||
@@ -205,12 +206,21 @@ isFloat = ask >>= \w -> (liftX . gets) (M.member w . W.floating . windowset)
|
|||||||
toggleRefocusing :: X ()
|
toggleRefocusing :: X ()
|
||||||
toggleRefocusing = XS.modify (RefocusLastToggle . not . refocusing)
|
toggleRefocusing = XS.modify (RefocusLastToggle . not . refocusing)
|
||||||
|
|
||||||
-- | Refocuses the previously focused window; acts as a toggle. Is not affected
|
-- | Refocuses the previously focused window; acts as a toggle.
|
||||||
-- by @toggleRefocusing@.
|
-- Is not affected by @toggleRefocusing@.
|
||||||
toggleFocus :: X ()
|
toggleFocus :: X ()
|
||||||
toggleFocus = withFocii () $ \_ tag ->
|
toggleFocus = withRecents $ \lw cw ->
|
||||||
withRecentsIn tag () $ \lw cw ->
|
when (cw /= lw) . windows $ tryFocus [lw]
|
||||||
when (cw /= lw) (windows $ tryFocusInCurrent [lw])
|
|
||||||
|
-- | Swaps the current and previous windows of the current workspace.
|
||||||
|
-- Is not affected by @toggleRefocusing@.
|
||||||
|
swapWithLast :: X ()
|
||||||
|
swapWithLast = withRecents $ \lw cw ->
|
||||||
|
when (cw /= lw) . windows . modify''. mapZ_ $ \w ->
|
||||||
|
if | (w == lw) -> cw
|
||||||
|
| (w == cw) -> lw
|
||||||
|
| otherwise -> w
|
||||||
|
where modify'' f = W.modify (f Nothing) (f . Just)
|
||||||
|
|
||||||
-- | Given a target workspace and a predicate on its current window, produce a
|
-- | Given a target workspace and a predicate on its current window, produce a
|
||||||
-- 'windows' suitable function that will refocus that workspace appropriately.
|
-- 'windows' suitable function that will refocus that workspace appropriately.
|
||||||
@@ -236,9 +246,10 @@ refocusWhen p tag = withRecentsIn tag id $ \lw cw -> do
|
|||||||
--
|
--
|
||||||
-- where '<=<' is imported from "Control.Monad".
|
-- where '<=<' is imported from "Control.Monad".
|
||||||
shiftRLWhen :: Query Bool -> WorkspaceId -> X (WindowSet -> WindowSet)
|
shiftRLWhen :: Query Bool -> WorkspaceId -> X (WindowSet -> WindowSet)
|
||||||
shiftRLWhen p to = withFocii id $ \fw from -> do
|
shiftRLWhen p to = withWindowSet $ \ws -> do
|
||||||
f <- refocusWhen p from
|
refocus <- refocusWhen p (W.currentTag ws)
|
||||||
return (f . W.shiftWin to fw)
|
let shift = maybe id (W.shiftWin to) (W.peek ws)
|
||||||
|
return (refocus . shift)
|
||||||
|
|
||||||
-- | Perform an update to the 'RecentWins' for the specified workspace.
|
-- | Perform an update to the 'RecentWins' for the specified workspace.
|
||||||
-- The RefocusLast log and layout hooks are both implemented trivially in
|
-- The RefocusLast log and layout hooks are both implemented trivially in
|
||||||
@@ -257,30 +268,28 @@ updateRecentsOn tag = withWindowSet $ \ws ->
|
|||||||
-- --< Private Utilities >-- {{{
|
-- --< Private Utilities >-- {{{
|
||||||
|
|
||||||
-- | Focuses the first window in the list it can find on the current workspace.
|
-- | Focuses the first window in the list it can find on the current workspace.
|
||||||
tryFocusInCurrent :: [Window] -> WindowSet -> WindowSet
|
tryFocus :: [Window] -> WindowSet -> WindowSet
|
||||||
tryFocusInCurrent wins = W.modify' $ \s ->
|
tryFocus wins = W.modify' $ \s ->
|
||||||
fromMaybe s . asum $ (\w -> findS (== w) s) <$> wins
|
fromMaybe s . asum $ (\w -> findS (== w) s) <$> wins
|
||||||
|
|
||||||
-- | Operate the above on a specified workspace.
|
-- | Operate the above on a specified workspace.
|
||||||
tryFocusIn :: WorkspaceId -> [Window] -> WindowSet -> WindowSet
|
tryFocusIn :: WorkspaceId -> [Window] -> WindowSet -> WindowSet
|
||||||
tryFocusIn tag wins ws =
|
tryFocusIn tag wins ws =
|
||||||
W.view (W.currentTag ws) . tryFocusInCurrent wins . W.view tag $ ws
|
W.view (W.currentTag ws) . tryFocus wins . W.view tag $ ws
|
||||||
|
|
||||||
-- | Get the RecentsMap out of extensible state and remove its newtype wrapper.
|
-- | Get the RecentsMap out of extensible state and remove its newtype wrapper.
|
||||||
getRecentsMap :: X (M.Map WorkspaceId RecentWins)
|
getRecentsMap :: X (M.Map WorkspaceId RecentWins)
|
||||||
getRecentsMap = XS.get >>= \(RecentsMap m) -> return m
|
getRecentsMap = XS.get >>= \(RecentsMap m) -> return m
|
||||||
|
|
||||||
-- | Given a default return value, perform an X action dependent on the focused
|
|
||||||
-- window and current workspace.
|
|
||||||
withFocii :: a -> (Window -> WorkspaceId -> X a) -> X a
|
|
||||||
withFocii dflt f = withWindowSet $ \ws ->
|
|
||||||
maybe (return dflt) (\w -> f w $ W.currentTag ws) (W.peek ws)
|
|
||||||
|
|
||||||
-- | Perform an X action dependent on successful lookup of the RecentWins for
|
-- | Perform an X action dependent on successful lookup of the RecentWins for
|
||||||
-- the specified workspace, or return a default value.
|
-- the specified workspace, or return a default value.
|
||||||
withRecentsIn :: WorkspaceId -> a -> (Window -> Window -> X a) -> X a
|
withRecentsIn :: WorkspaceId -> a -> (Window -> Window -> X a) -> X a
|
||||||
withRecentsIn tag dflt f = M.lookup tag <$> getRecentsMap
|
withRecentsIn tag dflt f = M.lookup tag <$> getRecentsMap
|
||||||
>>= maybe (return dflt) (\(Recent lw cw) -> f lw cw)
|
>>= maybe (return dflt) (\(Recent lw cw) -> f lw cw)
|
||||||
|
|
||||||
|
-- | The above specialised to the current workspace and unit.
|
||||||
|
withRecents :: (Window -> Window -> X ()) -> X ()
|
||||||
|
withRecents f = withWindowSet $ \ws -> withRecentsIn (W.currentTag ws) () f
|
||||||
|
|
||||||
-- }}}
|
-- }}}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user