Xmonad中如何根据屏幕数量调整按键绑定?
解决Xmonad中根据屏幕数量动态切换按键绑定的问题
问题根源
你遇到的编译错误是因为numScreens :: X Int返回的是X monad包裹的Int值,不是纯Int类型,Haskell不允许直接将X Int和普通Int(比如4)用==比较——这两种类型不属于同一范畴,没有预定义的相等性实例。
可行方案
核心思路是:先在X monad内部提取出屏幕数量的纯Int值,再根据这个值分支执行对应的动作。下面提供两种常用实现方式:
方案1:直接修改showSet1为动态动作
如果只是需要showSet1根据屏幕数切换行为,直接把它定义为一个X monad动作,内部完成判断:
-- 假设你已经定义了abc和xyz这两个X ()类型的动作 abc :: X () abc = ... -- 你的原有实现 xyz :: X () xyz = ... -- 屏幕数非4时的替代实现 showSet1 :: X () showSet1 = do screenNum <- numScreens -- 从X monad中提取屏幕数量 if screenNum == 4 then abc else xyz -- 按键绑定列表可以保持原有纯函数形式 myKeys :: XConfig l -> [(KeyMask, KeySym), X ()] myKeys conf = [ ((modMask conf, xK_x), showSet1) -- 其他按键绑定... ]
方案2:动态生成整个按键绑定列表
如果需要根据屏幕数调整多个按键绑定,可以把myKeys改成返回X monad包裹的列表:
myKeys :: XConfig l -> X [(KeyMask, KeySym), X ()] myKeys conf = do screenNum <- numScreens let showSet1Action = if screenNum == 4 then abc else xyz return [ ((modMask conf, xK_x), showSet1Action) -- 其他需要动态调整的按键绑定... ] -- 在Xmonad配置中使用这个动态生成的按键列表 main = xmonad $ def { keys = myKeys -- 其他配置项... }
补充说明
numScreens是Xmonad提供的获取当前物理屏幕数量的标准函数,无需使用其他替代方法。- 两种方案的本质都是利用Haskell的do notation(或
>>=操作符)从X monad中提取出纯值,再进行逻辑判断——这是处理Xmonad中动态状态的标准方式。
内容的提问来源于stack exchange,提问作者schuam
相关产品推荐
相关产品推荐

