xmonad io绑定不起作用

时间:2014-10-25 12:45:25

标签: haskell xmonad

我的~/.xmonad/xmonad.hs文件中的一个关键绑定是:

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

所以,我尝试使用这个模式来制作一个循环键盘布局的绑定。我有cycleKLayouts :: IO (),从ghci开始运行时效果很好。然后,我写道:

((modMask, xK_minus), io cycleKLayouts)

这个编译很好,但是当我尝试键时,唯一发生的事情是当前终端和鼠标所在的终端(两个术语)都会闪烁。这与未绑定密钥的情况不同,后者只是将字母传递给应用程序。

我还尝试了liftIO而不是io,结果相同。我也有直接spawn绑定:

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

有效,但提供了不同的行为。 (cycleKLayouts在某些时候运行setxkbmap


修改: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 个答案:

答案 0 :(得分:2)

cycleKLayouts类型重写X ()并使用spawn运行命令,当然应该有所帮助。我想问题在于cycleKLayouts运行命令的方式。结果setxkbmap可能无法访问您的环境变量,或者分叉然后终止。

如果您发布cycleKLayouts的来源,我可能会提供更具体的答案。

更新

好吧,我刚尝试将其添加到我的配置中:

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

每当我按M-a时出现错误消息&#34; waitForProcess:不存在(没有子进程)&#34;。我无法解释其中的原因,但我想这与Xmonad产生键绑定操作的方式有关(可能它是一个潜在的错误)。

但是,将readProcess替换为runProcessWithInput(来自Xmonad.Util.Run)可以完全解决问题:

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

尝试这一点以确保我们抓住了同样的问题。