xmonad io binding not working

北城余情 提交于 2019-12-11 07:05:20

问题


One of the key bindings in my ~/.xmonad/xmonad.hs file is this:

((modMask .|. shiftMask, xK_q), io (exitWith ExitSuccess))

So, I tried to use this pattern to make a binding that would cycle through keyboard layouts. I have cycleKLayouts :: IO (), which works perfectly when run from ghci. Then, I write:

((modMask, xK_minus), io cycleKLayouts)

This compiles fine, but when I try the key, the only thing that happens is that the current terminal and the one the mouse is under (both Terminology) flash faintly. This is different to what happens with an unbound key, which just passes the letter through to the application.

I've also tried liftIO, rather than io, with the same results. I also have a direct spawn binding:

((modMask, xK_equal), spawn "setxkbmap -v gb -variant colemak")

which works, but provides a different behaviour. (cycleKLayouts runs setxkbmap at some point).


Edit: definition of cycleKLayouts:

module Keyboards where
import System.Process
import Control.Applicative
kLayouts = [("gb(colemak)", "UK-CO")
          ,("gb", "UK-QW")
          ,("us(colemak)", "US-CO")
          ,("us", "US-QW")]
getKLayout :: IO String
getKLayout = f . (!! 4) . lines <$> readProcess "setxkbmap" ["-print"] []
    where
        f ('+':cs) = g cs
        f (_:cs) = f cs
        f _ = ""

        g ('+':_) = ""
        g (c:cs) = c:g cs
        g _ = ""

getNextKLayout :: IO String
getNextKLayout = do
    l <- getKLayout
    let kLayoutNames = map fst kLayouts
    let f (x:y:xs) = if x == l then y else f (y:xs)
        f _ = head kLayoutNames
    return $ f kLayoutNames

setKLayout :: String -> IO ()
setKLayout l = readProcess "setxkbmap" ["-v", l] [] >> return ()

cycleKLayouts :: IO ()
cycleKLayouts = setKLayout =<< getNextKLayout

回答1:


Rewriting cycleKLayouts in such a way that it has type X () and runs your command with spawn, certainly should help. I guess the problem lies in the way that cycleKLayouts runs the command. Probably in result setxkbmap doesn't have access to your environment variables, or gets forked and then terminated.

If you post the source of cycleKLayouts I probably would be able to give more specific answer.

Update:

Well, I've just tried to add this to my configuration:

((modMask, xK_a), liftIO (readProcess "setxkbmap" ["-print"] "" >>= putStrLn))

Whenever I was pressing M-a an error message "waitForProcess: does not exist (no child process)". I can't really explain a reason for that, but I guess it has to do with the way Xmonad spawns keybinded actions (probably it's a potential bug).

However, replacing readProcess to runProcessWithInput (from Xmonad.Util.Run) solved the problem completely:

 ((modMask, xK_a), liftIO (runProcessWithInput "setxkbmap" ["-print"] "" >>= putStrLn))

Try this to make sure that we catched on the same problem.



来源:https://stackoverflow.com/questions/26562522/xmonad-io-binding-not-working

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!