diff --git a/XMonad/Hooks/WorkspaceHistory.hs b/XMonad/Hooks/WorkspaceHistory.hs index dccfd42a..fe4f7a78 100644 --- a/XMonad/Hooks/WorkspaceHistory.hs +++ b/XMonad/Hooks/WorkspaceHistory.hs @@ -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 ()