diff options
Diffstat (limited to 'src/Rahm/Desktop/RebindKeys.hs')
| -rw-r--r-- | src/Rahm/Desktop/RebindKeys.hs | 78 |
1 files changed, 37 insertions, 41 deletions
diff --git a/src/Rahm/Desktop/RebindKeys.hs b/src/Rahm/Desktop/RebindKeys.hs index 0b4d768..aeca574 100644 --- a/src/Rahm/Desktop/RebindKeys.hs +++ b/src/Rahm/Desktop/RebindKeys.hs @@ -1,30 +1,27 @@ - -- Module for intercepting key presses not explicity mapped in the key bindings. -- This uses some deep magic with grabKey and windows and everything else, but -- it makes window-specific key bindings awesome! module Rahm.Desktop.RebindKeys where -import XMonad - -import Text.Printf -import Control.Monad.Trans.Class (lift) import Control.Monad (forM, forM_) +import Control.Monad.Trans.Class (lift) import Data.Default (Default, def) import Data.Map (Map) import qualified Data.Map as Map -import qualified XMonad.Util.ExtensibleState as XS -import Data.Monoid (All(..)) - +import Data.Monoid (All (..)) import Rahm.Desktop.Logger import Rahm.Desktop.NoPersist +import Text.Printf +import XMonad +import qualified XMonad.Util.ExtensibleState as XS type WindowHook = Query () -newtype InterceptState = - InterceptState (NoPersist (Map (KeyMask, KeySym) (X ()))) +newtype InterceptState + = InterceptState (NoPersist (Map (KeyMask, KeySym) (X ()))) -newtype RemapState = - RemapState (NoPersist (Map (Window, (KeyMask, KeySym)) (X ()))) +newtype RemapState + = RemapState (NoPersist (Map (Window, (KeyMask, KeySym)) (X ()))) instance ExtensionClass InterceptState where initialValue = InterceptState def @@ -37,19 +34,16 @@ remapHook event = do RemapState (NoPersist map) <- XS.get case event of - KeyEvent { ev_window = win, ev_event_type = typ, ev_keycode = code, ev_state = m } - | typ == keyPress-> do - XConf {display = dpy, theRoot = rootw} <- ask - keysym <- io $ keycodeToKeysym dpy code 0 - - case Map.lookup (win, (m, keysym)) map of - - Just xdo -> do - xdo - return (All False) - - Nothing -> return (All True) - + KeyEvent {ev_window = win, ev_event_type = typ, ev_keycode = code, ev_state = m} + | typ == keyPress -> do + XConf {display = dpy, theRoot = rootw} <- ask + keysym <- io $ keycodeToKeysym dpy code 0 + + case Map.lookup (win, (m, keysym)) map of + Just xdo -> do + xdo + return (All False) + Nothing -> return (All True) _ -> return (All True) getKeyCodesForKeysym :: Display -> KeySym -> IO [KeyCode] @@ -67,7 +61,6 @@ getKeyCodesForKeysym dpy keysym = do return $ keysymToKeycodes keysym - doGrab :: Display -> Window -> (KeyMask, KeySym) -> X () doGrab dpy win (keyMask, keysym) = do let grab kc m = io $ grabKey dpy kc m win True grabModeAsync grabModeAsync @@ -83,12 +76,15 @@ disableKey key = remapKey key (return ()) remapKey :: (KeyMask, KeySym) -> X () -> WindowHook remapKey keyFrom action = do window <- ask - Query $ lift $ do - XConf { display = disp, theRoot = rootw } <- ask - doGrab disp window keyFrom + Query $ + lift $ do + XConf {display = disp, theRoot = rootw} <- ask + doGrab disp window keyFrom - XS.modify $ \(RemapState (NoPersist keyMap)) -> RemapState $ NoPersist $ - Map.insert (window, keyFrom) action keyMap + XS.modify $ \(RemapState (NoPersist keyMap)) -> + RemapState $ + NoPersist $ + Map.insert (window, keyFrom) action keyMap -- sendKey, but as a query. sendKeyQ :: (KeyMask, KeySym) -> Query () @@ -98,20 +94,20 @@ sendKeyQ key = do sendKey :: (KeyMask, KeySym) -> Window -> X () sendKey (keymask, keysym) w = do - XConf { display = disp, theRoot = rootw } <- ask + XConf {display = disp, theRoot = rootw} <- ask codes <- io $ getKeyCodesForKeysym disp keysym case codes of - (keycode:_) -> - io $ allocaXEvent $ \xEv -> do - setEventType xEv keyPress - setKeyEvent xEv w rootw none keymask keycode True - sendEvent disp w True keyPressMask xEv - - setEventType xEv keyRelease - sendEvent disp w True keyReleaseMask xEv - + (keycode : _) -> + io $ + allocaXEvent $ \xEv -> do + setEventType xEv keyPress + setKeyEvent xEv w rootw none keymask keycode True + sendEvent disp w True keyPressMask xEv + + setEventType xEv keyRelease + sendEvent disp w True keyReleaseMask xEv _ -> return () rebindKey :: (KeyMask, KeySym) -> (KeyMask, KeySym) -> WindowHook |