----------------------------------------------------------------------------- -- | -- Module : XMonad.Actions.ConditionalKeys -- better as PerLayoutKeys not generalized? -- Copyright : (c) -- License : BSD3-style (see LICENSE) -- -- Maintainer : ? -- Stability : unstable -- Portability : unportable -- -- Define key-bindings on per-workspace or per-layout basis. -- ----------------------------------------------------------------------------- module XMonad.Actions.ConditionalKeys ( -- * Usage -- $usage XCond(..), chooseAction, bindOn ) where import XMonad import qualified XMonad.StackSet as W import Data.List (find) -- $usage -- TODO choose API and module split and document correctly. -- next paragraph for separate modules, rather than combined -- although the code is for combined modules. -- i.e. documentation is mix of does and doesn't match code. -- -- See also 'XMonad.Actions.PerWorkspaceKeys' from which this module is shamelessly -- derived. If you use both import this one qualified as in the following example: -- Use 'XMonad.Layout.Named' to shorten and distinguish the layouts you -- want to bind conditionaly. -- -- Add something like the following in your @~\/.xmonad\/xmonad.hs@: -- -- > import qualified XMonad.Actions.PerLayoutKeys as LK -- # TODO choose! -- > import XMonad.Actions.ConditionalKeys -- # or -- -- > import XMonad.Layout.Named -- > import XMonad.Layout.ResizableTile -- -- > layoutHook = avoidStruts (named "MRT" (Mirror rt) ||| rt) ||| Full -- > where rt = ResizableTall 2 (1/118) (11/15) [] -- -- > , ("C-M-h", bindOn LD [("MRT", sendMessage MirrorExpand), ("", sendMessage Shrink)] -- > , ("C-M-l", bindOn LD [("MRT", sendMessage MirrorShrink), ("", sendMessage Expand)] -- > , ("C-M-k", bindOn LD [("MRT", sendMessage Shrink), ("", sendMessage MirrorExpand)] -- > , ("C-M-j", bindOn LD [("MRT", sendMessage Expand), ("", sendMessage MirrorShrink)] -- -- > -- # vs. -- > , ("C-M-h", LK.bindOn [("MRT", sendMessage MirrorExpand), ("", sendMessage Shrink)] -- > -- # or -- > , ("C-M-h", bindOnLayouts [("MRT", sendMessage MirrorExpand), ("", sendMessage Shrink)] data XCond = WS | LD -- | Choose an action based on the current workspace id (WS) or -- layout description (LD). chooseAction :: XCond -> (String->X()) -> X() chooseAction WS f = withWindowSet (f . W.currentTag) chooseAction LD f = withWindowSet (f . description . W.layout . W.workspace . W.current) -- | If current workspace or layout string is listed, run the associated -- action (only the first match counts!) If it isn't listed, then run the default -- action (marked with empty string, \"\"), or do nothing if default isn't supplied. bindOn :: XCond -> [(String, X())] -> X() bindOn xc bindings = chooseAction xc $ chooser where chooser xc = case find ((xc==).fst) bindings of Just (_, action) -> action Nothing -> case find ((""==).fst) bindings of Just (_, action) -> action Nothing -> return ()