[xmonad] Suspend Keybinding Temporarily

Dmitriy Matrosov sgf.dma at gmail.com
Wed Nov 28 18:19:44 UTC 2018


Hi.

On 11/21/2018 09:49 PM, Eyal Erez wrote:
> Hi,
> 
> I'm getting some collisions between my xmonad keybindings and an 
> application I'm running (it's a game that is suppose to run full screen 
> but in reality just uses a large window).  I was wondering if I could 
> suspend or change some keybindings from a script that I can run before 
> the app launches and then restore later.
> 
> Is this at all possible?  Happy to entertain other options.

Here is proof of concept:


         import XMonad
         import XMonad.Hooks.EwmhDesktops

         import System.Directory
         import System.FilePath


         main :: IO ()
         main = do
                 let xcf = ewmh $ def
                             { modMask = mod4Mask
                             , handleExtraArgs = disableKeys
                             }
                 xmonad xcf

         disableKeys :: [String] -> XConfig Layout -> IO (XConfig Layout)
         disableKeys _ xcf = do
             xd <- getXMonadDir
             let disableFn = xd </> "disable_keys"
             b <- doesFileExist disableFn
             if b
               then do
                 trace "Disabling all keys."
                 removeFile disableFn
                 return (xcf {keys = \_ -> mempty})
               else return xcf


To disable all keys create file `~/.xmonad/disable_keys` and then
restart xmonad with `xmonad --restart`. All keys will be disabled
_and_ file deleted (to avoid locking yourself), thus next restart will
restore all keys back.

As far as i understand, xmonad grabs keys in `X.Main.launch` before
entering main loop. Thus, the one way to change key grab is to restart
xmonad. I need to modify `XConfig` before calling X.Main.launch`, and
this may be done by `handleExtraArgs` (called in `launch'` in
`X.Main.xmonad`). Unfortunately, it seems, that xmonad does not allow
to pass extra cmd arguments during restart (`X.Operations.restart`
always starts xmonad with name `xmonad` and no arguments). Also, i
can't use extensible state in `handleExtraArgs`, because it runs in
`IO` (`X` context is not yet built at that time).  Thus, to pass
something to it, i may use either file or (probably) `--replace`. The
above version uses file. And i have no luck with `--replace`: it
seems, `xmonad` can't replace itself?..


More information about the xmonad mailing list