This is an XMonad extension that allows to switch the current set of workspaces with other named sets. This is quite useful if you use multiple workspaces to work on a single project. Then you can create a context per project and temporarily make sure you don't need to see irrelevant workspaces.
See this screencast for a demo.
Clone this repo into your ~/.xmonad/lib directory or make it available to you
in another way.
git clone [email protected]:Procrat/xmonad-contexts ~/.xmonad/lib/I find this extension particularly enjoyable in combination with a menu, like
dmenu. So I am going to assume you have it
(or something similar) installed.
Add the following to the imports of your ~/.xmonad/xmonad.hs.
import qualified XMonad.Util.Dmenu as D
import qualified XMonad.Actions.Contexts as CThen add a key binding that switches contexts and creates it if it did not exist, and a key binding that deletes a context. This example uses XMonad.Util.EZConfig-style key bindings, but this is not necessary.
...
, ("M-s", C.listContextNames >>= D.dmenu >>= C.createAndSwitchContext)
, ("M-S-s", C.listContextNames >>= D.dmenu >>= C.deleteContext >> return ())
...As a final step, which is required to make your layouts in non-visible contexts
persistent across restarts of XMonad, you have to make the following instance
where myLayout is the layout you defined in the layoutHook field of your
XMonad configuration.
{-# LANGUAGE FlexibleInstances #-}
import XMonad (readsLayout)
instance Read (Layout Window) where
readsPrec _ = readsLayout (Layout myLayout)I think the function names are pretty self-explanatory. If they are not, please
tell me so. Usage of them requires an orphan instance of Read (Layout Window)
in your xmonad.hs to be able to make layouts persistents across restarts of
XMonad. If there is a way to work around this hack, I would love to know!
type ContextName = String
createContext :: Read (Layout Window) => ContextName -> X ()
switchContext :: Read (Layout Window) => ContextName -> X Bool
createAndSwitchContext :: Read (Layout Window) => ContextName -> X ()
deleteContext :: Read (Layout Window) => ContextName -> X Bool
showCurrentContextName :: Read (Layout Window) => X String
listContextNames :: Read (Layout Window) => X [ContextName]
defaultContextName :: ContextNameAs far as I know, there isn't really another extension like this. It may be vaguely related to X.A.Plane, X.A.DynamicWorkspaceGroups and X.L.IndependentScreens.
The most important difference between those extensions and this one is how the workspaces are internally handled. Most extensions manipulate the workspaces that XMonad keeps track of internally. This extension leaves those workspace sets completely intact, but just switches to completely other ones. One of the advantages is that this means that all your key bindings and extensions that manage workspaces can remain intact!
I encountered a similar issue when using dmwit's
yeganesh. The problem is that XMonad cleans up
child processes. In this particular case, it cleaned up yeganesh's call to
dmenu. To fix this, temporarily disable XMonad's signal handlers in the call
to the menu.
import XMonad
safeMenu :: [String] -> X String
safeMenu options = do
uninstallSignalHandlers
choice <- D.menu "yeganesh" options
installSignalHandlers
return choiceThen replace the dmenu call by a call to this function.
...
, ("M-s", C.listContextNames >>= safeMenu >>= C.createAndSwitchContext)
, ("M-S-s", C.listContextNames >>= safeMenu >>= C.deleteContext >> return ())
...