aboutsummaryrefslogtreecommitdiff
path: root/src/Internal
diff options
context:
space:
mode:
authorJosh Rahm <rahm@google.com>2021-11-22 16:03:16 -0700
committerJosh Rahm <joshuarahm@gmail.com>2022-10-09 12:19:45 -0600
commitd2c7a351c0d70ed6fc14590640eb277a15b01333 (patch)
tree194d760ed420f2fae248620a42d4ad92225064c3 /src/Internal
parent736f5b2cba1a7541e6d9173bf0fdbd28eced013d (diff)
downloadrde-d2c7a351c0d70ed6fc14590640eb277a15b01333.tar.gz
rde-d2c7a351c0d70ed6fc14590640eb277a15b01333.tar.bz2
rde-d2c7a351c0d70ed6fc14590640eb277a15b01333.zip
Compeletely change how KeyBindings are done.
Created new KeysM and ButtonsM monads to make configuring keybindings and button bindings more readable through a DSL. Before bindings would just be a giant list, but that made it difficult to read and repetitive. Now the syntax follows the pattern bind key-to-bind mask1 : action mask2 : action i.e. bind xK_a $ do justMod $ doSomeAction a b c shiftMod $ doSomeOtherAction a b c This makes it a lot cleaner to see all the bindings allocated to a specific key. That way, when adding a new binding, I can easily see what bindings already exist for that key.
Diffstat (limited to 'src/Internal')
-rw-r--r--src/Internal/Keys.hs337
-rw-r--r--src/Internal/KeysM.hs408
2 files changed, 584 insertions, 161 deletions
diff --git a/src/Internal/Keys.hs b/src/Internal/Keys.hs
index d50b371..ae2b9bd 100644
--- a/src/Internal/Keys.hs
+++ b/src/Internal/Keys.hs
@@ -1,6 +1,7 @@
{-# LANGUAGE RankNTypes #-}
module Internal.Keys (applyKeys) where
+import Internal.KeysM
import Internal.SwapMaster (swapMaster)
import XMonad.Hooks.ManageDocks
import XMonad.Layout.MosaicAlt
@@ -42,12 +43,183 @@ import Internal.DMenu
import Internal.PassMenu
type KeyMap l = XConfig l -> Map (KeyMask, KeySym) (X ())
+type ButtonsMap l = XConfig l -> Map (KeyMask, Button) (Window -> X ())
+
+keymap :: KeyMap l
+keymap = runKeys $ do
+ config <- getConfig
+
+ let subkeys = submap . flip runKeys config
+
+ bind xK_apostrophe $ do
+ justMod $ subkeys $ do
+ bind xK_apostrophe $
+ justMod jumpToLast
+ mapAlpha 0 jumpToMark
+
+ shiftMod $ subkeys $ do
+ bind xK_apostrophe $
+ shiftMod swapWithLastMark
+ mapAlpha shiftMask swapWithMark
+
+ bind xK_BackSpace $ do
+ -- The only raw keybinding. Meant to get a terminal to unbrick XMonad if
+ -- something goes wrong with the keyboard layout and for first-time boots
+ -- where dmenu/alacritty may not be installed.
+ rawMask mod4Mask $ spawn "xterm"
+ justMod $ spawn "pkill -SIGUSR 1 xmobar"
+
+ bind xK_F1 $
+ -- Button programmed on mouse
+ shiftMod $ click >> withFocused (windows . W.sink)
+
+ bind xK_F2 $
+ -- Button programmed on mouse
+ shiftMod $ click >> sendMessage ToggleZoom
+
+ bind xK_F3 $
+ -- Button programmed on mouse
+ shiftMod $ click >> kill
+
+ bind xK_F10 $ do
+ justMod $ spawn "spotify-control play"
+
+ bind xK_F11 $ do
+ justMod $ spawn "spotify-control prev"
+
+ bind xK_F12 $ do
+ justMod $ spawn "spotify-control next"
+
+ bind xK_Return $ do
+ justMod swapMaster
+
+ bind xK_Tab $ do
+ justMod $ windows W.focusDown
+ shiftMod $ windows W.focusUp
+
+ -- Switch between different screens. These are the leftmost keys on the home
+ -- row in a Dvorak layout. One might want to switch these to ASD for QWERTY.
+ forM_ (zip [xK_a, xK_o, xK_e] [0..]) $ \(key, idx) ->
+ bind key $ do
+ -- Move focus to that screen.
+ justMod $ withScreen W.view idx
+ -- Swap the current screen with the one given
+ altMod $ withScreen W.greedyView idx
+ -- Move the current window to the select screen.
+ shiftMod $ withScreen W.shift idx
+
+ bind xK_bracketright $ do
+ justMod $ sendMessage $ modifyWindowBorder (-1)
+
+ bind xK_bracketleft $ do
+ justMod $ sendMessage $ modifyWindowBorder 1
+
+ bind xK_b $ do
+ justMod $ spawn "bluetooth-select.sh"
+
+ bind xK_c $ do
+ justMod runPassMenu
+ shiftMod kill
+
+ bind xK_f $ do
+ justMod $ sendMessage FlipLayout
+ shiftMod $ sendMessage HFlipLayout
+
+ bind xK_g $ do
+ justMod $ subkeys $ do
+ mapNumbersAndAlpha 0 gotoWorkspace
+ shiftMod $ subkeys $ do
+ mapNumbersAndAlpha 0 shiftToWorkspace
+ mapNumbersAndAlpha shiftMask (\i -> windows (CopyWindow.copy [i]))
+ shiftAltMod $ subkeys $ do
+ mapNumbersAndAlpha 0 swapWorkspace
+
+ bind xK_h $ do
+ justMod $ windows W.focusDown
+ shiftMod $ windows W.swapDown
+ controlMod $ rotAllDown
+
+ bind xK_j $ do
+ justMod $ sendMessage ShrinkZoom
+
+ bind xK_k $ do
+ justMod $ sendMessage ExpandZoom
+
+ bind xK_l $ do
+ justMod $ windows W.focusUp
+ shiftMod $ windows W.swapUp
+ controlMod $ rotAllUp
+ altMod $ spawn "xsecurelock"
+
+ bind xK_minus $ do
+ justMod $ sendMessage (IncMasterN (-1))
+ shiftMod $ withFocused $ sendMessage . expandWindowAlt
+
+ bind xK_m $ do
+ justMod $ subkeys $
+ mapAlpha 0 markCurrentWindow
+
+ bind xK_n $ do
+ justMod $ relativeWorkspaceShift next
+
+ bind xK_plus $ do
+ justMod $ sendMessage (IncMasterN 1)
+ shiftMod $ withFocused $ sendMessage . expandWindowAlt
+
+ bind xK_q $ do
+ shiftMod $ spawn "xmonad --recompile && xmonad --restart"
+
+ bind xK_r $ do
+ justMod runDMenu
+ shiftMod $ sendMessage DoRotate
+
+ bind xK_s $ do
+ altMod $ spawn "sudo -A systemctl suspend && xsecurelock"
+
+ bind xK_space $ do
+ justMod $ sendMessage NextLayout
+ shiftMod $ sendMessage NextLayout
+
+ bind xK_t $ do
+ justMod $ spawn (terminal config)
+ shiftMod $ withFocused $ windows . W.sink
+ altMod $ spawn (terminal config ++ " -t Floating\\ Term")
+
+ bind xK_w $ do
+ justMod windowJump
+
+ bind xK_x $ do
+ justMod $ sendMessage ToggleStruts
+
+ bind xK_z $ do
+ justMod $ sendMessage ToggleZoom
+
+mouseMap :: ButtonsMap l
+mouseMap = runButtons $ do
+ bind button1 $ do
+ justMod $ \w -> focus w >> mouseMoveWindow w >> windows W.shiftMaster
+
+ bind button2 $ do
+ justMod $ windows . (W.shiftMaster .) . W.focusWindow
+
+ bind button3 $ do
+ justMod $ \w -> focus w >> mouseResizeWindow w >> windows W.shiftMaster
+
+ bind (6 :: Button) $
+ justMod $ const (relativeWorkspaceShift prev)
+
+ bind (7 :: Button) $
+ justMod $ const (relativeWorkspaceShift next)
+
+ bind (8 :: Button) $
+ justMod $ const (relativeWorkspaceShift prev)
+
+ bind (9 :: Button) $
+ justMod $ const (relativeWorkspaceShift next)
applyKeys :: XConfig l -> IO (XConfig l)
-applyKeys config@(XConfig {modMask = modm}) = do
- ks <- newKeys
- ms <- newMouse
- return $ config { keys = ks, mouseBindings = ms }
+applyKeys config@(XConfig {modMask = modm}) =
+ return $ config { keys = keymap, mouseBindings = mouseMap }
newMouse :: IO (XConfig l -> Map (KeyMask, Button) (Window -> X ()))
newMouse =
@@ -73,160 +245,3 @@ click = do
modifyWindowBorder :: Integer -> SpacingModifier
modifyWindowBorder i = ModifyWindowBorder $ \(Border a b c d) ->
(Border (a + i) (b + i) (c + i) (d + i))
-
-newKeys :: IO (KeyMap l)
-newKeys =
- return $ \config@(XConfig {modMask = modm}) ->
- Map.fromList
- [ ((modm, xK_F12), (void $ spawn "spotify-control next"))
- , ((modm, xK_F11), (void $ spawn "spotify-control prev"))
- , ((modm, xK_semicolon), scratchpadSpawnActionTerminal "scratchpad")
- , ((modm, xK_F10), (void $ spawn "spotify-control play"))
- , ((modm, xK_r), runDMenu)
- , ((modm, xK_c), runPassMenu)
- , ((modm, xK_h), windows W.focusDown)
- , ((modm, xK_l), windows W.focusUp)
- , ((modm .|. controlMask, xK_h), rotAllDown)
- , ((modm .|. controlMask, xK_l), rotAllUp)
- , ((modm .|. shiftMask, xK_h), windows W.swapUp)
- , ((modm .|. shiftMask, xK_l), windows W.swapDown)
- , ((modm , xK_f), sendMessage FlipLayout)
- , ((modm .|. shiftMask, xK_f), sendMessage HFlipLayout)
- , ((modm , xK_Return), swapMaster)
- , ((modm, xK_j), sendMessage Shrink)
- , ((modm, xK_k), sendMessage Expand)
- , ((modm .|. shiftMask, xK_r), sendMessage DoRotate)
- , ((modm .|. mod1Mask, xK_l), (void $ spawn "xsecurelock"))
- , ((modm .|. mod1Mask, xK_s), (void $ spawn "sudo systemctl suspend && xsecurelock"))
- , ((modm .|. shiftMask, xK_c), kill)
- , ((modm .|. shiftMask, xK_t), withFocused $ windows . W.sink)
- , ((modm .|. shiftMask, xK_plus), withFocused $ sendMessage . expandWindowAlt)
- , ((modm .|. shiftMask, xK_minus), withFocused $ sendMessage . shrinkWindowAlt)
- , ((mod4Mask, xK_BackSpace), (void $ spawn "xterm"))
- , ((modm, xK_BackSpace), (void $ spawn "pkill -SIGUSR1 xmobar"))
- , ((modm, xK_t), (void $ spawn (terminal config)))
- , ((modm .|. mod1Mask, xK_t), (void $ spawn (terminal config ++ " -t Floating\\ Term")))
- , ((modm, xK_m), (submap $ mapAlpha modm markCurrentWindow))
- , ((modm, xK_w), windowJump)
- , ((modm, xK_space), sendMessage NextLayout)
- , ((modm .|. shiftMask, xK_space), sendMessage FirstLayout)
- , ((modm, xK_apostrophe), (submap $
- Map.insert
- (modm, xK_apostrophe)
- jumpToLast
- (mapAlpha modm jumpToMark)))
-
- , ((modm .|. shiftMask, xK_apostrophe), (submap $
- Map.insert
- (modm .|. shiftMask, xK_apostrophe)
- swapWithLastMark
- (mapAlpha (modm .|. shiftMask) swapWithMark)))
-
- , ((modm, xK_g), (submap $
- mapNumbersAndAlpha 0 gotoWorkspace))
-
- , ((modm .|. shiftMask, xK_g), (submap $
- mapNumbersAndAlpha 0 shiftToWorkspace <>
- mapNumbersAndAlpha shiftMask (\i -> windows $ CopyWindow.copy [i])))
-
- , ((modm .|. shiftMask .|. mod1Mask, xK_g), (submap $
- mapNumbersAndAlpha 0 swapWorkspace))
-
- , ((modm, xK_minus), sendMessage (IncMasterN (-1)))
- , ((modm, xK_plus), sendMessage (IncMasterN 1))
- , ((modm .|. shiftMask, xK_bracketleft), sendMessage (modifyWindowBorder (-5)))
- , ((modm .|. shiftMask, xK_bracketright), sendMessage (modifyWindowBorder 5))
- , ((modm, xK_bracketleft), sendMessage ShrinkZoom)
- , ((modm, xK_bracketright), sendMessage ExpandZoom)
-
- , ((modm, xK_space), sendMessage NextLayout)
-
- , ((modm, xK_n), relativeWorkspaceShift next)
- , ((modm, xK_p), relativeWorkspaceShift prev)
-
- , ((modm .|. shiftMask, xK_q), spawn "xmonad --recompile && xmonad --restart")
- , ((modm, xK_z), sendMessage ToggleZoom)
-
- , ((modm, xK_x), spawn "bluetooth-select.sh")
- , ((modm .|. shiftMask, xK_x), spawn "bluetoothctl -- disconnect")
-
- , ((modm, xK_Tab), windows W.focusDown)
- , ((modm .|. shiftMask, xK_Tab), windows W.focusUp)
-
- , ((modm, xK_a), withScreen W.view 0)
- , ((modm, xK_o), withScreen W.view 1)
- , ((modm, xK_e), withScreen W.view 2)
-
- , ((modm .|. shiftMask, xK_a), withScreen W.shift 0)
- , ((modm .|. shiftMask, xK_o), withScreen W.shift 1)
- , ((modm .|. shiftMask, xK_e), withScreen W.shift 2)
-
- , ((modm .|. mod1Mask, xK_a), withScreen W.greedyView 0)
- , ((modm .|. mod1Mask, xK_o), withScreen W.greedyView 1)
- , ((modm .|. mod1Mask, xK_e), withScreen W.greedyView 2)
- , ((modm, xK_b), sendMessage ToggleStruts)
-
- -- Buttons programmed on my mouse.
- , ((shiftMask, xK_F1), click >> (withFocused $ windows . W.sink))
- , ((shiftMask, xK_F2), click >> sendMessage ToggleZoom)
- , ((shiftMask, xK_F3), click >> kill)
- ]
-
-mapNumbersAndAlpha :: KeyMask -> (Char -> X ()) -> Map (KeyMask, KeySym) (X ())
-mapNumbersAndAlpha km fn = mapNumbers km fn <> mapAlpha km fn
-
-mapNumbers :: KeyMask -> (Char -> X ()) -> Map (KeyMask, KeySym) (X ())
-mapNumbers km fn =
- Map.fromList [
- ((km, xK_0), fn '0')
- , ((km, xK_1), fn '1')
- , ((km, xK_2), fn '2')
- , ((km, xK_3), fn '3')
- , ((km, xK_4), fn '4')
- , ((km, xK_5), fn '5')
- , ((km, xK_6), fn '6')
- , ((km, xK_7), fn '7')
- , ((km, xK_8), fn '8')
- , ((km, xK_9), fn '9')
- , ((km, xK_bracketright), fn '6')
- , ((km, xK_exclam), fn '8')
- , ((km, xK_bracketleft), fn '7')
- , ((km, xK_braceleft), fn '5')
- , ((km, xK_braceright), fn '3')
- , ((km, xK_parenleft), fn '1')
- , ((km, xK_equal), fn '9')
- , ((km, xK_asterisk), fn '0')
- , ((km, xK_parenright), fn '2')
- , ((km, xK_plus), fn '4')
- ]
-
-mapAlpha :: KeyMask -> (Char -> X ()) -> Map (KeyMask, KeySym) (X ())
-mapAlpha km fn =
- Map.fromList [
- ((km, xK_a), fn 'a')
- , ((km, xK_b), fn 'b')
- , ((km, xK_c), fn 'c')
- , ((km, xK_d), fn 'd')
- , ((km, xK_e), fn 'e')
- , ((km, xK_f), fn 'f')
- , ((km, xK_g), fn 'g')
- , ((km, xK_h), fn 'h')
- , ((km, xK_i), fn 'i')
- , ((km, xK_j), fn 'j')
- , ((km, xK_k), fn 'k')
- , ((km, xK_l), fn 'l')
- , ((km, xK_m), fn 'm')
- , ((km, xK_n), fn 'n')
- , ((km, xK_o), fn 'o')
- , ((km, xK_p), fn 'p')
- , ((km, xK_q), fn 'q')
- , ((km, xK_r), fn 'r')
- , ((km, xK_s), fn 's')
- , ((km, xK_t), fn 't')
- , ((km, xK_u), fn 'u')
- , ((km, xK_v), fn 'v')
- , ((km, xK_w), fn 'w')
- , ((km, xK_x), fn 'x')
- , ((km, xK_y), fn 'y')
- , ((km, xK_z), fn 'z')
- ]
diff --git a/src/Internal/KeysM.hs b/src/Internal/KeysM.hs
new file mode 100644
index 0000000..de48bee
--- /dev/null
+++ b/src/Internal/KeysM.hs
@@ -0,0 +1,408 @@
+{-# Language GeneralizedNewtypeDeriving, MultiParamTypeClasses,
+ FunctionalDependencies, FlexibleInstances, TypeFamilies #-}
+module Internal.KeysM where
+
+import Control.Arrow (second)
+import Control.Monad (void)
+import Control.Monad.State (State(..), modify', get, execState)
+import XMonad
+import Data.Map (Map)
+import qualified Data.Map as Map
+
+{- Module that defines a DSL for binding keys. -}
+newtype KeysM l a = KeysM (State (XConfig l, Map (KeyMask, KeySym) (X ())) a)
+ deriving (Functor, Applicative, Monad)
+
+newtype ButtonsM l a = ButtonsM (State (XConfig l, Map (KeyMask, Button) (Window -> X ())) a)
+ deriving (Functor, Applicative, Monad)
+
+newtype BindingBuilder b a = BindingBuilder (State (KeyMask, [(KeyMask, b)]) a)
+ deriving (Functor, Applicative, Monad)
+
+class HasConfig m where
+ getConfig :: m l (XConfig l)
+
+class Bindable k where
+ type BindableValue k :: *
+ type BindableMonad k :: (* -> *) -> * -> *
+
+ bind :: k -> BindingBuilder (BindableValue k) a -> BindableMonad k l ()
+
+runKeys :: KeysM l a -> XConfig l -> Map (KeyMask, KeySym) (X ())
+runKeys (KeysM stateM) config =
+ snd $ execState stateM (config, Map.empty)
+
+runButtons :: ButtonsM l a -> XConfig l -> Map (KeyMask, Button) (Window -> X ())
+runButtons (ButtonsM stateM) config =
+ snd $ execState stateM (config, Map.empty)
+
+instance HasConfig KeysM where
+ getConfig = fst <$> KeysM get
+
+instance HasConfig ButtonsM where
+ getConfig = fst <$> ButtonsM get
+
+{- Generally it is assumed that the mod key shoud be pressed, but not always. -}
+naked :: f -> BindingBuilder f ()
+naked = rawMask 0
+
+rawMask :: KeyMask -> f -> BindingBuilder f ()
+rawMask m x = BindingBuilder $ modify' (second ((m, x):))
+
+maskMod :: KeyMask -> f -> BindingBuilder f ()
+maskMod mask action = do
+ modMask <- fst <$> BindingBuilder get
+ rawMask (modMask .|. mask) action
+
+altMask :: KeyMask
+altMask = mod1Mask
+
+hyperMask :: KeyMask
+hyperMask = mod3Mask
+
+altgrMask :: KeyMask
+altgrMask = mod2Mask
+
+superMask :: KeyMask
+superMask = mod4Mask
+
+justMod :: f -> BindingBuilder f ()
+justMod = maskMod 0
+
+instance Bindable KeySym where
+ type BindableValue KeySym = X ()
+ type BindableMonad KeySym = KeysM
+
+ -- bind :: KeySym -> BindingBuilder (X x) a -> KeysM l ()
+ bind key (BindingBuilder stM) = do
+ m <- modMask <$> getConfig
+ let (_, values) = execState stM (m, [])
+
+ KeysM $ modify' $ second $
+ flip (<>) (Map.fromList (map (\(m, v) -> ((m, key), v)) values))
+
+instance Bindable Button where
+ type BindableValue Button = Window -> X ()
+ type BindableMonad Button = ButtonsM
+
+ -- bind :: KeySym -> BindingBuilder (Window -> X ()) a -> ButtonsM l ()
+ bind button (BindingBuilder stM) = do
+ m <- modMask <$> getConfig
+ let (_, values) = execState stM (m, [])
+
+ ButtonsM $ modify' $ second $
+ flip (<>) (Map.fromList (map (\(m, v) -> ((m, button), v)) values))
+
+shiftControlAltSuperHyperAltgrMod :: f -> BindingBuilder f ()
+shiftControlAltSuperHyperAltgrMod =
+ maskMod (shiftMask .|. controlMask .|. altMask .|. superMask .|. hyperMask .|. altgrMask)
+
+shiftControlAltSuperHyperMod :: f -> BindingBuilder f ()
+shiftControlAltSuperHyperMod =
+ maskMod (shiftMask .|. controlMask .|. altMask .|. superMask .|. hyperMask)
+
+shiftControlAltSuperAltgrMod :: f -> BindingBuilder f ()
+shiftControlAltSuperAltgrMod =
+ maskMod (shiftMask .|. controlMask .|. altMask .|. superMask .|. altgrMask)
+
+shiftControlAltSuperMod :: f -> BindingBuilder f ()
+shiftControlAltSuperMod =
+ maskMod (shiftMask .|. controlMask .|. altMask .|. superMask)
+
+shiftControlAltHyperAltgrMod :: f -> BindingBuilder f ()
+shiftControlAltHyperAltgrMod =
+ maskMod (shiftMask .|. controlMask .|. altMask .|. hyperMask .|. altgrMask)
+
+shiftControlAltHyperMod :: f -> BindingBuilder f ()
+shiftControlAltHyperMod =
+ maskMod (shiftMask .|. controlMask .|. altMask .|. hyperMask)
+
+shiftControlAltAltgrMod :: f -> BindingBuilder f ()
+shiftControlAltAltgrMod =
+ maskMod (shiftMask .|. controlMask .|. altMask .|. altgrMask)
+
+shiftControlAltMod :: f -> BindingBuilder f ()
+shiftControlAltMod =
+ maskMod (shiftMask .|. controlMask .|. altMask)
+
+shiftControlSuperHyperAltgrMod :: f -> BindingBuilder f ()
+shiftControlSuperHyperAltgrMod =
+ maskMod (shiftMask .|. controlMask .|. superMask .|. hyperMask .|. altgrMask)
+
+shiftControlSuperHyperMod :: f -> BindingBuilder f ()
+shiftControlSuperHyperMod =
+ maskMod (shiftMask .|. controlMask .|. superMask .|. hyperMask)
+
+shiftControlSuperAltgrMod :: f -> BindingBuilder f ()
+shiftControlSuperAltgrMod =
+ maskMod (shiftMask .|. controlMask .|. superMask .|. altgrMask)
+
+shiftControlSuperMod :: f -> BindingBuilder f ()
+shiftControlSuperMod =
+ maskMod (shiftMask .|. controlMask .|. superMask)
+
+shiftControlHyperAltgrMod :: f -> BindingBuilder f ()
+shiftControlHyperAltgrMod =
+ maskMod (shiftMask .|. controlMask .|. hyperMask .|. altgrMask)
+
+shiftControlHyperMod :: f -> BindingBuilder f ()
+shiftControlHyperMod =
+ maskMod (shiftMask .|. controlMask .|. hyperMask)
+
+shiftControlAltgrMod :: f -> BindingBuilder f ()
+shiftControlAltgrMod =
+ maskMod (shiftMask .|. controlMask .|. altgrMask)
+
+shiftControlMod :: f -> BindingBuilder f ()
+shiftControlMod =
+ maskMod (shiftMask .|. controlMask)
+
+shiftAltSuperHyperAltgrMod :: f -> BindingBuilder f ()
+shiftAltSuperHyperAltgrMod =
+ maskMod (shiftMask .|. altMask .|. superMask .|. hyperMask .|. altgrMask)
+
+shiftAltSuperHyperMod :: f -> BindingBuilder f ()
+shiftAltSuperHyperMod =
+ maskMod (shiftMask .|. altMask .|. superMask .|. hyperMask)
+
+shiftAltSuperAltgrMod :: f -> BindingBuilder f ()
+shiftAltSuperAltgrMod =
+ maskMod (shiftMask .|. altMask .|. superMask .|. altgrMask)
+
+shiftAltSuperMod :: f -> BindingBuilder f ()
+shiftAltSuperMod =
+ maskMod (shiftMask .|. altMask .|. superMask)
+
+shiftAltHyperAltgrMod :: f -> BindingBuilder f ()
+shiftAltHyperAltgrMod =
+ maskMod (shiftMask .|. altMask .|. hyperMask .|. altgrMask)
+
+shiftAltHyperMod :: f -> BindingBuilder f ()
+shiftAltHyperMod =
+ maskMod (shiftMask .|. altMask .|. hyperMask)
+
+shiftAltAltgrMod :: f -> BindingBuilder f ()
+shiftAltAltgrMod =
+ maskMod (shiftMask .|. altMask .|. altgrMask)
+
+shiftAltMod :: f -> BindingBuilder f ()
+shiftAltMod =
+ maskMod (shiftMask .|. altMask)
+
+shiftSuperHyperAltgrMod :: f -> BindingBuilder f ()
+shiftSuperHyperAltgrMod =
+ maskMod (shiftMask .|. superMask .|. hyperMask .|. altgrMask)
+
+shiftSuperHyperMod :: f -> BindingBuilder f ()
+shiftSuperHyperMod =
+ maskMod (shiftMask .|. superMask .|. hyperMask)
+
+shiftSuperAltgrMod :: f -> BindingBuilder f ()
+shiftSuperAltgrMod =
+ maskMod (shiftMask .|. superMask .|. altgrMask)
+
+shiftSuperMod :: f -> BindingBuilder f ()
+shiftSuperMod =
+ maskMod (shiftMask .|. superMask)
+
+shiftHyperAltgrMod :: f -> BindingBuilder f ()
+shiftHyperAltgrMod =
+ maskMod (shiftMask .|. hyperMask .|. altgrMask)
+
+shiftHyperMod :: f -> BindingBuilder f ()
+shiftHyperMod =
+ maskMod (shiftMask .|. hyperMask)
+
+shiftAltgrMod :: f -> BindingBuilder f ()
+shiftAltgrMod =
+ maskMod (shiftMask .|. altgrMask)
+
+shiftMod :: f -> BindingBuilder f ()
+shiftMod = maskMod shiftMask
+
+controlAltSuperHyperAltgrMod :: f -> BindingBuilder f ()
+controlAltSuperHyperAltgrMod =
+ maskMod (controlMask .|. altMask .|. superMask .|. hyperMask .|. altgrMask)
+
+controlAltSuperHyperMod :: f -> BindingBuilder f ()
+controlAltSuperHyperMod =
+ maskMod (controlMask .|. altMask .|. superMask .|. hyperMask)
+
+controlAltSuperAltgrMod :: f -> BindingBuilder f ()
+controlAltSuperAltgrMod =
+ maskMod (controlMask .|. altMask .|. superMask .|. altgrMask)
+
+controlAltSuperMod :: f -> BindingBuilder f ()
+controlAltSuperMod =
+ maskMod (controlMask .|. altMask .|. superMask)
+
+controlAltHyperAltgrMod :: f -> BindingBuilder f ()
+controlAltHyperAltgrMod =
+ maskMod (controlMask .|. altMask .|. hyperMask .|. altgrMask)
+
+controlAltHyperMod :: f -> BindingBuilder f ()
+controlAltHyperMod =
+ maskMod (controlMask .|. altMask .|. hyperMask)
+
+controlAltAltgrMod :: f -> BindingBuilder f ()
+controlAltAltgrMod =
+ maskMod (controlMask .|. altMask .|. altgrMask)
+
+controlAltMod :: f -> BindingBuilder f ()
+controlAltMod =
+ maskMod (controlMask .|. altMask)
+
+controlSuperHyperAltgrMod :: f -> BindingBuilder f ()
+controlSuperHyperAltgrMod =
+ maskMod (controlMask .|. superMask .|. hyperMask .|. altgrMask)
+
+controlSuperHyperMod :: f -> BindingBuilder f ()
+controlSuperHyperMod =
+ maskMod (controlMask .|. superMask .|. hyperMask)
+
+controlSuperAltgrMod :: f -> BindingBuilder f ()
+controlSuperAltgrMod =
+ maskMod (controlMask .|. superMask .|. altgrMask)
+
+controlSuperMod :: f -> BindingBuilder f ()
+controlSuperMod =
+ maskMod (controlMask .|. superMask)
+
+controlHyperAltgrMod :: f -> BindingBuilder f ()
+controlHyperAltgrMod =
+ maskMod (controlMask .|. hyperMask .|. altgrMask)
+
+controlHyperMod :: f -> BindingBuilder f ()
+controlHyperMod =
+ maskMod (controlMask .|. hyperMask)
+
+controlAltgrMod :: f -> BindingBuilder f ()
+controlAltgrMod =
+ maskMod (controlMask .|. altgrMask)
+
+controlMod :: f -> BindingBuilder f ()
+controlMod = maskMod controlMask
+
+altSuperHyperAltgrMod :: f -> BindingBuilder f ()
+altSuperHyperAltgrMod =
+ maskMod (altMask .|. superMask .|. hyperMask .|. altgrMask)
+
+altSuperHyperMod :: f -> BindingBuilder f ()
+altSuperHyperMod =
+ maskMod (altMask .|. superMask .|. hyperMask)
+
+altSuperAltgrMod :: f -> BindingBuilder f ()
+altSuperAltgrMod =
+ maskMod (altMask .|. superMask .|. altgrMask)
+
+altSuperMod :: f -> BindingBuilder f ()
+altSuperMod =
+ maskMod (altMask .|. superMask)
+
+altHyperAltgrMod :: f -> BindingBuilder f ()
+altHyperAltgrMod =
+ maskMod (altMask .|. hyperMask .|. altgrMask)
+
+altHyperMod :: f -> BindingBuilder f ()
+altHyperMod =
+ maskMod (altMask .|. hyperMask)
+
+altAltgrMod :: f -> BindingBuilder f ()
+altAltgrMod =
+ maskMod (altMask .|. altgrMask)
+
+altMod :: f -> BindingBuilder f ()
+altMod = maskMod altMask
+
+superHyperAltgrMod :: f -> BindingBuilder f ()
+superHyperAltgrMod =
+ maskMod (superMask .|. hyperMask .|. altgrMask)
+
+superHyperMod :: f -> BindingBuilder f ()
+superHyperMod =
+ maskMod (superMask .|. hyperMask)
+
+superAltgrMod :: f -> BindingBuilder f ()
+superAltgrMod =
+ maskMod (superMask .|. altgrMask)
+
+superMod :: f -> BindingBuilder f ()
+superMod = maskMod superMask
+
+hyperAltgrMod :: f -> BindingBuilder f ()
+hyperAltgrMod =
+ maskMod (hyperMask .|. altgrMask)
+
+hyperMod :: f -> BindingBuilder f ()
+hyperMod = maskMod hyperMask
+
+altgrMod :: f -> BindingBuilder f ()
+altgrMod = maskMod altgrMask
+
+
+{- Meant for submapping, binds all alphanumeric charactes to (fn c). -}
+mapNumbersAndAlpha :: KeyMask -> (Char -> X ()) -> KeysM l ()
+mapNumbersAndAlpha km fn = do
+ mapNumbers km fn
+ mapAlpha km fn
+
+{- Meant for submapping. This binds all numbers to (fn x) where x is the number
+ - pressed and fn is the function provided. -}
+mapNumbers :: KeyMask -> (Char -> X ()) -> KeysM l ()
+mapNumbers km fn = do
+ mapM_ (\(key, ch) -> bind key $ rawMask km (fn ch))
+ [ (xK_0, '0')
+ , (xK_1, '1')
+ , (xK_2, '2')
+ , (xK_3, '3')
+ , (xK_4, '4')
+ , (xK_5, '5')
+ , (xK_6, '6')
+ , (xK_7, '7')
+ , (xK_8, '8')
+ , (xK_9, '9')
+ -- Programmer Dvorak shifts the numbers so I have to map to their unshifted
+ -- form.
+ , (xK_bracketright, '6')
+ , (xK_exclam, '8')
+ , (xK_bracketleft, '7')
+ , (xK_braceleft, '5')
+ , (xK_braceright, '3')
+ , (xK_parenleft, '1')
+ , (xK_equal, '9')
+ , (xK_asterisk, '0')
+ , (xK_parenright, '2')
+ , (xK_plus, '4') ]
+
+{- Meant for submapping. This binds all alpha charactes to (fn c) where c is the
+ - character pressed and fn is the function provided. -}
+mapAlpha :: KeyMask -> (Char -> X ()) -> KeysM l ()
+mapAlpha km fn =
+ mapM_ (\(key, ch) -> bind key $ rawMask km (fn ch)) [
+ (xK_a, 'a')
+ , (xK_b, 'b')
+ , (xK_c, 'c')
+ , (xK_d, 'd')
+ , (xK_e, 'e')
+ , (xK_f, 'f')
+ , (xK_g, 'g')
+ , (xK_h, 'h')
+ , (xK_i, 'i')
+ , (xK_j, 'j')
+ , (xK_k, 'k')
+ , (xK_l, 'l')
+ , (xK_m, 'm')
+ , (xK_n, 'n')
+ , (xK_o, 'o')
+ , (xK_p, 'p')
+ , (xK_q, 'q')
+ , (xK_r, 'r')
+ , (xK_s, 's')
+ , (xK_t, 't')
+ , (xK_u, 'u')
+ , (xK_v, 'v')
+ , (xK_w, 'w')
+ , (xK_x, 'x')
+ , (xK_y, 'y')
+ , (xK_z, 'z')
+ ]