diff options
| author | Josh Rahm <rahm@google.com> | 2022-04-13 15:57:58 -0600 |
|---|---|---|
| committer | Josh Rahm <rahm@google.com> | 2022-04-13 15:57:58 -0600 |
| commit | 8c0e13e1d6f27657b9c439927814d01f143216d3 (patch) | |
| tree | 3b85702b0367d1bdf626b1c46988021f8506d9fa /src | |
| parent | 0dfe872da02d5d63eb2b334decd3a8292aff3ca3 (diff) | |
| download | rde-experimental_only_bind_necessary.tar.gz rde-experimental_only_bind_necessary.tar.bz2 rde-experimental_only_bind_necessary.zip | |
Only bind the necessary keys during a submap. A little strange, not sure how I feel about it, but it is worthwhile to keep aroundexperimental_only_bind_necessary
Diffstat (limited to 'src')
| -rw-r--r-- | src/Rahm/Desktop/RebindKeys.hs | 9 | ||||
| -rw-r--r-- | src/Rahm/Desktop/Submap.hs | 45 |
2 files changed, 48 insertions, 6 deletions
diff --git a/src/Rahm/Desktop/RebindKeys.hs b/src/Rahm/Desktop/RebindKeys.hs index 0b4d768..040946f 100644 --- a/src/Rahm/Desktop/RebindKeys.hs +++ b/src/Rahm/Desktop/RebindKeys.hs @@ -77,6 +77,15 @@ doGrab dpy win (keyMask, keysym) = do forM_ codes $ \kc -> mapM_ (grab kc . (keyMask .|.)) =<< extraModifiers +doUngrab :: Display -> Window -> (KeyMask, KeySym) -> X () +doUngrab dpy win (keyMask, keysym) = do + let grab kc m = io $ ungrabKey dpy kc m win + + codes <- io $ getKeyCodesForKeysym dpy keysym + + forM_ codes $ \kc -> + mapM_ (grab kc . (keyMask .|.)) =<< extraModifiers + disableKey :: (KeyMask, KeySym) -> WindowHook disableKey key = remapKey key (return ()) diff --git a/src/Rahm/Desktop/Submap.hs b/src/Rahm/Desktop/Submap.hs index da9fe77..496b5f5 100644 --- a/src/Rahm/Desktop/Submap.hs +++ b/src/Rahm/Desktop/Submap.hs @@ -11,11 +11,15 @@ module Rahm.Desktop.Submap ( import XMonad hiding (keys) import Control.Monad.Fix (fix) +import Control.Monad (void) import qualified Data.Map as Map import Data.Map (Map) import Control.Concurrent (threadDelay) import Data.Word (Word64) import Data.Time.Clock.POSIX +import Rahm.Desktop.RebindKeys +import Data.Set (Set, (\\)) +import qualified Data.Set as Set currentTimeMillis :: IO Int @@ -46,7 +50,32 @@ getMaskEventWithTimeout timeout d mask fn = do then return True else threadDelay 1000 >> getMaskEventWithTimeout' ptr timeout +data KeysToGrab = OnlyKeys [(KeyMask, KeySym)] | AllKeys + +grabKeys :: KeysToGrab -> X () +grabKeys AllKeys = do + XConf { theRoot = root, display = d } <- ask + void $ io $ grabKeyboard d root False grabModeAsync grabModeAsync currentTime +grabKeys (OnlyKeys (Set.fromList -> keys)) = do + ks <- (Set.fromList . Map.keys) <$> asks keyActions + let keysToGrab = keys \\ ks -- Avoid grabbing already bound keys + + XConf { theRoot = root, display = d } <- ask + mapM_ (doGrab d root) keysToGrab + +ungrabKeys :: KeysToGrab -> X () +ungrabKeys AllKeys = do + XConf { display = d } <- ask + io $ ungrabKeyboard d currentTime +ungrabKeys (OnlyKeys (Set.fromList -> keys)) = do + ks <- (Set.fromList . Map.keys) <$> asks keyActions + let keysToUngrab = keys \\ ks -- Don't ungrab unbound keys! + + XConf { display = d, theRoot = root } <- ask + mapM_ (doUngrab d root) keysToUngrab + {- + - - Like submap fram XMonad.Actions.Submap, but sends the string from - XLookupString to the function along side the keysym. - @@ -54,10 +83,10 @@ getMaskEventWithTimeout timeout d mask fn = do - but also allows submappings for keys that may not have a character associated - with them (for example, the function keys). -} -mapNextStringWithKeysym :: (KeyMask -> KeySym -> String -> X ()) -> X () -mapNextStringWithKeysym fn = do +mapNextStringWithKeysymOnlyGrabbing :: KeysToGrab -> (KeyMask -> KeySym -> String -> X ()) -> X () +mapNextStringWithKeysymOnlyGrabbing keysToGrab fn = do XConf { theRoot = root, display = d } <- ask - io $ grabKeyboard d root False grabModeAsync grabModeAsync currentTime + grabKeys keysToGrab ret <- io $ fix $ \nextkey -> do ret <- @@ -75,18 +104,22 @@ mapNextStringWithKeysym fn = do Nothing -> return Nothing - io $ ungrabKeyboard d currentTime + ungrabKeys keysToGrab case ret of Just (m, str, keysym) -> fn m keysym str Nothing -> return () +mapNextStringWithKeysym :: (KeyMask -> KeySym -> String -> X ()) -> X () +mapNextStringWithKeysym = mapNextStringWithKeysymOnlyGrabbing AllKeys + {- Like submap, but on the character typed rather than the kysym. -} mapNextString :: (KeyMask -> String -> X ()) -> X () mapNextString fn = mapNextStringWithKeysym (\m _ s -> fn m s) submapDefaultWithKey :: ((KeyMask, KeySym) -> X ()) -> Map (KeyMask, KeySym) (X ()) -> X () -submapDefaultWithKey def m = mapNextStringWithKeysym $ \mask sym _ -> do - Map.findWithDefault (def (mask, sym)) (mask, sym) m +submapDefaultWithKey def m = + mapNextStringWithKeysymOnlyGrabbing (OnlyKeys $ Map.keys m) $ \mask sym _ -> do + Map.findWithDefault (def (mask, sym)) (mask, sym) m submapDefault :: X () -> Map (KeyMask, KeySym) (X ()) -> X () submapDefault def = submapDefaultWithKey (const def) |