代码之家  ›  专栏  ›  技术社区  ›  Matti Virkkunen

从XGrabKeyboard中排除一些键

  •  5
  • Matti Virkkunen  · 技术社区  · 14 年前

    考虑一个应用程序,它需要在聚焦时抓住键盘,以便捕获所有用于处理的窗口管理器命令(alt+f4和whatnot)。现在,这有一个缺点,即当用户抓取键盘时,无法通过键盘切换到另一个应用程序或虚拟桌面。我想有一个用户定义的白名单的组合键(例如,用于切换虚拟桌面的组合键)是从抓取排除。

    我可以想到两种可能的方法。当白名单中的关键事件到达时,或者

    1. 不知怎么地告诉X继续像往常一样处理它。这听起来是一种更自然的方式,但我找不到这样做的方法,或者
    2. 取消键盘的链接,然后手动将事件重新发送到窗口管理器进行处理,但是我不知道将其发送到何处(根窗口?)或者这是否可行。

    有人能填这些空白吗?还有什么建议吗?

    如果没有办法将按键排除在抓取之外,我想我必须满足于有一个“退出键”,当按下时它会取消键盘的锁定。但是,用户必须同时按下这两个按钮,然后再按下窗口管理器命令,这并不是很好。

    1 回复  |  直到 14 年前
        1
  •  4
  •   Havoc P    14 年前

    我觉得没有办法。所有的机制都无法满足您的需要。

    例如,方法1是窗口管理器在决定不截获单击或键时所做的事情。但是,WM使用“被动”抓取特定的键(xgrabkey=passive xgrabkeyboard=active),然后使用xallowevents()。XallowEvents()不适用于XGrabKeyboard()。此外,当您允许事件具有重播模式之一时,重播事件将绕过具有原始抓取的窗口及其所有父窗口上的所有被动抓取。wm的抓取将在根窗口上,而根窗口始终是父窗口,因此无法重放到根窗口,我只能说。不管怎样,对每一把可能的钥匙进行xgrabkey操作都有点神经病。

    方法2会有不好的竞争条件问题,因为在重新发送之前可以处理其他键和鼠标事件,所以您需要重新排序键,并将事件发送到被破坏的窗口和其他混乱中。此外,没有好的方法发送一个关键事件。xsendEvent()被许多客户机忽略(它在允许这样做的事件中设置了send_事件标志)。可以使用Xtest扩展,但可以在生产X服务器上禁用,并且仍然存在争用条件问题。

    您可能需要的是一个协议扩展,允许您在抓取键盘之后执行allowEvents(模式=replayKeyboard),而不绕过父窗口上的被动抓取。

    一个警告是,我不知道XKB和Xinput2可以做什么,所以这些扩展中可能有一些内容。

    不管怎样,据我所知,您必须满足于“escape key”,尽管对于X服务器和/或窗口管理器规范来说,最终拥有“vmware/vnc类型的东西意识”可能是件好事,但短期内这对您没有帮助。EWMH规范扩展可以像VNC/vmware/之类的新的“net-wm-window”类型一样简单,窗口管理器可以减少其键绑定,或者在窗口聚焦时为它们添加额外的修改器,例如。