X.H.WorkspaceHistory: Add ability to exclude workspaces

This commit is contained in:
slotThe
2021-02-12 10:53:53 +01:00
parent ab60361c5b
commit 62e9941d3d

View File

@@ -19,6 +19,7 @@ module XMonad.Hooks.WorkspaceHistory (
-- $usage
-- * Hooking
workspaceHistoryHook
, workspaceHistoryHookExclude
-- * Querying
, workspaceHistory
, workspaceHistoryByScreen
@@ -32,8 +33,8 @@ import Control.Applicative
import Prelude
import XMonad
import XMonad.StackSet hiding (filter, delete)
import Data.List
import XMonad.StackSet hiding (delete, filter, new)
import Data.List (delete, find, groupBy, nub, sortBy)
import qualified XMonad.Util.ExtensibleState as XS
-- $usage
@@ -50,6 +51,14 @@ import qualified XMonad.Util.ExtensibleState as XS
-- > , ...
-- > }
--
-- If you want to completely exclude certain workspaces from entering
-- the history, you can use 'workspaceHistoryHookExclude' instead. For
-- example, to ignore the named scratchpad workspace:
--
-- > import XMonad.Util.NamedScratchpad (scratchpadWorkspaceTag)
-- > ...
-- > , logHook = ... >> workspaceHistoryHookExclude [scratchpadWorkspaceTag] >> ...
--
-- To make use of the collected data, a query function is provided.
data WorkspaceHistory = WorkspaceHistory
@@ -66,6 +75,12 @@ instance ExtensionClass WorkspaceHistory where
workspaceHistoryHook :: X ()
workspaceHistoryHook = gets windowset >>= (XS.modify . updateLastActiveOnEachScreen)
-- | Like 'workspaceHistoryHook', but with the ability to exclude
-- certain workspaces.
workspaceHistoryHookExclude :: [WorkspaceId] -> X ()
workspaceHistoryHookExclude ws =
gets windowset >>= XS.modify . updateLastActiveOnEachScreenExclude ws
workspaceHistoryWithScreen :: X [(ScreenId, WorkspaceId)]
workspaceHistoryWithScreen = XS.gets history
@@ -92,16 +107,22 @@ workspaceHistoryTransaction action = do
-- | Update the last visible workspace on each monitor if needed
-- already there, or move it to the front if it is.
updateLastActiveOnEachScreen :: WindowSet -> WorkspaceHistory -> WorkspaceHistory
updateLastActiveOnEachScreen StackSet {current = cur, visible = vis} wh =
updateLastActiveOnEachScreen = updateLastActiveOnEachScreenExclude []
-- | Like 'updateLastActiveOnEachScreen', but with the ability to
-- exclude certain workspaces.
updateLastActiveOnEachScreenExclude :: [WorkspaceId] -> WindowSet -> WorkspaceHistory -> WorkspaceHistory
updateLastActiveOnEachScreenExclude ws StackSet {current = cur, visible = vis} wh =
WorkspaceHistory { history = doUpdate cur $ foldl updateLastForScreen (history wh) $ vis ++ [cur] }
where
firstOnScreen sid = find ((== sid) . fst)
doUpdate Screen {workspace = Workspace { tag = wid }, screen = sid} curr =
let newEntry = (sid, wid) in newEntry:delete newEntry curr
let newEntry = (sid, wid)
in if wid `elem` ws then curr else newEntry : delete newEntry curr
updateLastForScreen curr Screen {workspace = Workspace { tag = wid }, screen = sid} =
let newEntry = (sid, wid)
alreadyCurrent = maybe False (== newEntry) $ firstOnScreen sid curr
in if alreadyCurrent then curr else newEntry:delete newEntry curr
alreadyCurrent = Just newEntry == firstOnScreen sid curr
in if alreadyCurrent || wid `elem` ws then curr else newEntry : delete newEntry curr
-- | Modify a the workspace history with a given pure function.
workspaceHistoryModify :: ([(ScreenId, WorkspaceId)] -> [(ScreenId, WorkspaceId)]) -> X ()