Keyboard 从键盘中排除一些键

Keyboard 从键盘中排除一些键,keyboard,x11,xlib,Keyboard,X11,Xlib,考虑一个应用程序,在该应用程序中,为了捕获所有窗口管理器命令(Alt+F4和诸如此类)进行处理,需要在聚焦时抓取键盘。现在,这有一个缺点,即当抓取键盘时,用户无法通过键盘切换到另一个应用程序或虚拟桌面。我希望有一个用户定义的组合键白名单(比如,切换虚拟桌面的组合键),这些组合键被排除在抓取之外 我可以想出两种可能的方法。当白名单上的密钥事件到达时 以某种方式告诉X继续像往常一样处理它。这听起来像是一种更自然的方法,但我找不到一种方法,或者 解开键盘并手动将事件重新发送到窗口管理器进行处理,但是我

考虑一个应用程序,在该应用程序中,为了捕获所有窗口管理器命令(Alt+F4和诸如此类)进行处理,需要在聚焦时抓取键盘。现在,这有一个缺点,即当抓取键盘时,用户无法通过键盘切换到另一个应用程序或虚拟桌面。我希望有一个用户定义的组合键白名单(比如,切换虚拟桌面的组合键),这些组合键被排除在抓取之外

我可以想出两种可能的方法。当白名单上的密钥事件到达时

  • 以某种方式告诉X继续像往常一样处理它。这听起来像是一种更自然的方法,但我找不到一种方法,或者
  • 解开键盘并手动将事件重新发送到窗口管理器进行处理,但是我不知道将其发送到哪里(根窗口?),或者这是否可行
  • 有人能把这些空白填一下吗?还有其他建议吗


    如果没有办法从抓取中排除键,我想我将不得不接受一个“退出键”,当按下该键时,它会解除键盘的抓取。不过,用户必须同时按下这两个键,然后再按下窗口管理器命令,这就没那么好了。

    我认为没有办法做到这一点。没有一种机制能像你所需要的那样工作

    方法1是窗口管理器在决定不截获单击或键(例如)时所做的工作。但是,WM在特定键上使用“被动”抓取(XGrabKey=被动XGrabKeyboard=主动),然后使用XAllowEvents()。XAllowEvents()不适用于XGrabKeyboard()。此外,当您使用其中一种重播模式对事件进行XAllowEvents时,重播的事件将绕过具有原始抓取的窗口及其所有父窗口上的所有被动抓取。WM的抓取将在根窗口上,这将始终是一个父窗口,因此没有办法重播到根窗口,最好我可以告诉你。在每一个可能的钥匙上使用XGrabKey无论如何都会有点神经病

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

    您可能需要的是一个协议扩展,它允许您在GrabKeyboard之后执行AllowEvents(mode=ReplayKeyboard),而无需绕过父窗口上的被动Grab

    需要注意的是,我不知道XKB和XInput2可以完成的所有工作,所以这些扩展中可能有一些东西


    无论如何,据我所知,您必须满足于“escape key”,尽管X服务器和/或Windows manager规格最终可能会有“VMWare/VNC类型的东西感知”,但这在短期内对您没有帮助。EWMH规范扩展可以像vnc/vmware/之类的新的_NET_WM_WINDOW_类型一样简单,窗口管理器可以减少其键绑定,或者在该窗口被聚焦时为其添加额外的修改器或其他内容。

    我担心我会得到这样的答案。如果可能的话,我肯定会看到一个软件可以做到这一点。不过,感谢您将我引向XInput 2,我现在正在看它,它似乎有了抓取输入设备的新方法。我们将运行一些测试,看看这是否可行。结果表明,类似的东西“可能计划在XI2.1中使用”,根据谷歌的说法,它似乎还不存在。然而,新的WM提示听起来并不是个坏主意,所以我在freedesktop.org WM规范列表上开始了一些讨论。