From dcf1f3e69400e7fc26564d5eee9483d17b78a28d Mon Sep 17 00:00:00 2001 From: ivanbrennan Date: Thu, 5 Mar 2020 07:38:32 -0500 Subject: [PATCH 1/5] add toggleRecentWS Add toggleRecentWS to switch to the most recent workspace, with repeated use toggling between a pair of workspaces. --- XMonad/Actions/CycleRecentWS.hs | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/XMonad/Actions/CycleRecentWS.hs b/XMonad/Actions/CycleRecentWS.hs index 95986ad8..21d27302 100644 --- a/XMonad/Actions/CycleRecentWS.hs +++ b/XMonad/Actions/CycleRecentWS.hs @@ -19,7 +19,9 @@ module XMonad.Actions.CycleRecentWS ( -- * Usage -- $usage cycleRecentWS, - cycleWindowSets + cycleWindowSets, + toggleRecentWS, + toggleWindowSets ) where import XMonad hiding (workspaces) @@ -47,9 +49,18 @@ cycleRecentWS :: [KeySym] -- ^ A list of modifier keys used when invoking this a -> KeySym -- ^ Key used to switch to previous (more recent) workspace. -- If it's the same as the nextWorkspace key, it is effectively ignored. -> X () -cycleRecentWS = cycleWindowSets options - where options w = map (view `flip` w) (recentTags w) - recentTags w = map tag $ tail (workspaces w) ++ [head (workspaces w)] +cycleRecentWS = cycleWindowSets recentWS + + +-- | Switch to the most recent workspace. The stack of most recently used workspaces +-- is updated, so repeated use toggles between a pair of workspaces. +toggleRecentWS :: X () +toggleRecentWS = toggleWindowSets recentWS + + +recentWS :: WindowSet -> [WindowSet] +recentWS w = map (`view` w) recentTags + where recentTags = map tag $ tail (workspaces w) ++ [head (workspaces w)] cycref :: [a] -> Int -> a @@ -83,3 +94,12 @@ cycleWindowSets genOptions mods keyNext keyPrev = do io $ grabKeyboard d root False grabModeAsync grabModeAsync currentTime setOption 0 io $ ungrabKeyboard d currentTime + + +-- | Switch to the first of a finite list of WindowSets. +toggleWindowSets :: (WindowSet -> [WindowSet]) -> X () +toggleWindowSets genOptions = do + options <- gets $ genOptions . windowset + case options of + [] -> return () + o:_ -> windows (const o) From 53a59d6592997eaa03a8797e41594f98b1317d61 Mon Sep 17 00:00:00 2001 From: ivanbrennan Date: Thu, 5 Mar 2020 08:39:59 -0500 Subject: [PATCH 2/5] cycleRecentNonEmptyWS, toggleRecentNonEmptyWS Add non-empty variants to these workspace cycling/toggling functions. --- XMonad/Actions/CycleRecentWS.hs | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/XMonad/Actions/CycleRecentWS.hs b/XMonad/Actions/CycleRecentWS.hs index 21d27302..8a5158ad 100644 --- a/XMonad/Actions/CycleRecentWS.hs +++ b/XMonad/Actions/CycleRecentWS.hs @@ -19,13 +19,15 @@ module XMonad.Actions.CycleRecentWS ( -- * Usage -- $usage cycleRecentWS, + cycleRecentNonEmptyWS, cycleWindowSets, toggleRecentWS, + toggleRecentNonEmptyWS, toggleWindowSets ) where import XMonad hiding (workspaces) -import XMonad.StackSet +import XMonad.StackSet hiding (filter) -- $usage -- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@ file: @@ -49,18 +51,35 @@ cycleRecentWS :: [KeySym] -- ^ A list of modifier keys used when invoking this a -> KeySym -- ^ Key used to switch to previous (more recent) workspace. -- If it's the same as the nextWorkspace key, it is effectively ignored. -> X () -cycleRecentWS = cycleWindowSets recentWS +cycleRecentWS = cycleWindowSets $ recentWS (const True) + + +-- | Like 'cycleRecentWS', but restricted to non-empty workspaces. +cycleRecentNonEmptyWS :: [KeySym] -- ^ A list of modifier keys used when invoking this action. + -- As soon as one of them is released, the final switch is made. + -> KeySym -- ^ Key used to switch to next (less recent) workspace. + -> KeySym -- ^ Key used to switch to previous (more recent) workspace. + -- If it's the same as the nextWorkspace key, it is effectively ignored. + -> X () +cycleRecentNonEmptyWS = cycleWindowSets $ recentWS (not . null . stack) -- | Switch to the most recent workspace. The stack of most recently used workspaces -- is updated, so repeated use toggles between a pair of workspaces. toggleRecentWS :: X () -toggleRecentWS = toggleWindowSets recentWS +toggleRecentWS = toggleWindowSets $ recentWS (const True) -recentWS :: WindowSet -> [WindowSet] -recentWS w = map (`view` w) recentTags - where recentTags = map tag $ tail (workspaces w) ++ [head (workspaces w)] +-- | Like 'toggleRecentWS', but restricted to non-empty workspaces. +toggleRecentNonEmptyWS :: X () +toggleRecentNonEmptyWS = toggleWindowSets $ recentWS (not . null . stack) + + +recentWS :: (WindowSpace -> Bool) -> WindowSet -> [WindowSet] +recentWS p w = map (`view` w) recentTags + where recentTags = map tag + $ filter p + $ tail (workspaces w) ++ [head (workspaces w)] cycref :: [a] -> Int -> a From 423d70593d0e987fac08890b429d42ec403551b1 Mon Sep 17 00:00:00 2001 From: ivanbrennan Date: Thu, 5 Mar 2020 08:53:45 -0500 Subject: [PATCH 3/5] refactor recentWS Instead of constructing workspaces and rearranging it with tail and head, construct it in the desired formation directly. --- XMonad/Actions/CycleRecentWS.hs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/XMonad/Actions/CycleRecentWS.hs b/XMonad/Actions/CycleRecentWS.hs index 8a5158ad..4a67156c 100644 --- a/XMonad/Actions/CycleRecentWS.hs +++ b/XMonad/Actions/CycleRecentWS.hs @@ -79,7 +79,9 @@ recentWS :: (WindowSpace -> Bool) -> WindowSet -> [WindowSet] recentWS p w = map (`view` w) recentTags where recentTags = map tag $ filter p - $ tail (workspaces w) ++ [head (workspaces w)] + $ map workspace (visible w) + ++ hidden w + ++ [workspace (current w)] cycref :: [a] -> Int -> a From 5aca3fb542bff2c6b4d4d179c33d6654c41f4880 Mon Sep 17 00:00:00 2001 From: ivanbrennan Date: Fri, 6 Mar 2020 08:27:44 -0500 Subject: [PATCH 4/5] export recentWS Allow consumers of this module to filter the recency list with a custom predicate when cycling/toggling workspaces. --- XMonad/Actions/CycleRecentWS.hs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/XMonad/Actions/CycleRecentWS.hs b/XMonad/Actions/CycleRecentWS.hs index 4a67156c..18fe330a 100644 --- a/XMonad/Actions/CycleRecentWS.hs +++ b/XMonad/Actions/CycleRecentWS.hs @@ -23,7 +23,8 @@ module XMonad.Actions.CycleRecentWS ( cycleWindowSets, toggleRecentWS, toggleRecentNonEmptyWS, - toggleWindowSets + toggleWindowSets, + recentWS ) where import XMonad hiding (workspaces) @@ -75,7 +76,11 @@ toggleRecentNonEmptyWS :: X () toggleRecentNonEmptyWS = toggleWindowSets $ recentWS (not . null . stack) -recentWS :: (WindowSpace -> Bool) -> WindowSet -> [WindowSet] +-- | Given a predicate p and the current WindowSet w, create a list of recent WindowSets, +-- most recent first, where the focused workspace satisfies p. +recentWS :: (WindowSpace -> Bool) -- ^ A workspace predicate. + -> WindowSet -- ^ The current WindowSet + -> [WindowSet] recentWS p w = map (`view` w) recentTags where recentTags = map tag $ filter p From c48ddb08afb3f45fcf19afafebc8409ebb03f830 Mon Sep 17 00:00:00 2001 From: ivanbrennan Date: Fri, 6 Mar 2020 07:56:09 -0500 Subject: [PATCH 5/5] CHANGES: additions to XMonad.Actions.CycleRecentWS --- CHANGES.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index 93b68e18..9fb87eee 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -65,6 +65,18 @@ When we calculate dragger widths, we first try to get the border width of the focused window, before failing over to using the initial `borderWidth`. + * `XMonad.Actions.CycleRecentWS` + + - Added `cycleRecentNonEmptyWS` function which behaves like `cycleRecentWS` + but is constrainded to non-empty workspaces. + + - Added `toggleRecentWS` and `toggleRecentNonEmptyWS` functions which toggle + between the current and most recent workspace, and continue to toggle back + and forth on repeated presses, rather than cycling through other workspaces. + + - Added `recentWS` function which allows the recency list to be filtered with + a user-provided predicate. + ## 0.16 ### Breaking Changes