考虑一个需要集中注意力时抓住键盘以便捕获所有窗口管理器命令(Alt + F4和诸如此类)以进行处理的应用程序。现在,这具有一个缺点,即用户在握住键盘时无法通过键盘切换到另一个应用程序或虚拟桌面。我希望有一个用户定义的按键组合白名单(例如,用于切换虚拟桌面的按键组合),该白名单不包含在抓取中。
我可以想到两种可能的方法。当列入白名单的关键事件到达时,
以某种方式告诉X继续照常处理它。听起来这是一种更自然的方法,但是我找不到方法,或者
松开键盘,然后手动将事件重新发送到窗口管理器进行处理,但是我不知道将事件发送到哪里(根窗口?),或者这是否可行。
谁能填补这些空白?还有其他建议吗?
如果没有办法从按键中排除按键,我想我必须要有一个“退出键”,当按下该键时会取消键盘的锁定。但是,用户必须同时按一下,然后再按窗口管理器命令,这不太好。
最佳答案
我认为没有办法。没有一种机制可以完全满足您的需要。
如果窗口管理器决定不拦截例如单击或按键,则方法1类似于窗口管理器。但是,WM在特定键(XGrabKey =被动XGrabKeyboard = active)上使用“被动”抓取,然后在XAllowEvents()上使用。 XAllowEvents()与XGrabKeyboard()不兼容。同样,当您使用一种重播模式进行XAllowEvents时,重播事件会绕过具有原始抓取的窗口及其所有父窗口上的所有被动抓取。 WM的抓取将在根窗口中进行,而根窗口将始终是父窗口,因此,据我所知,无法重播到根窗口。无论如何,对每个可能的键执行XGrabKey都是一种心理选择。
方法2可能存在不良的竞争条件问题,因为在重新发送之前可以处理其他键和鼠标事件,因此您需要重新排序键并将事件发送到破坏的窗口和其他混乱情况。此外,也没有发送键事件的好方法。 XSendEvent()被许多客户端忽略(它在允许的情况下设置send_event标志)。可以使用XTest扩展名,但可以在生产X服务器上将其禁用,但仍然存在竞争状况问题。
您可能需要的是协议扩展,使您可以在GrabKeyboard之后执行AllowEvents(mode = ReplayKeyboard),而无需绕过父窗口的被动抓取。
一个警告是,我不知道XKB和XInput2可以完成所有疯狂的工作,因此这些扩展中可能有某些东西。
无论如何,据我所知,您必须满足“转义键”的要求,尽管最终使X服务器和/或窗口管理器规范具有“ VMWare / VNC-type-thing意识”可能会很好,在短期内对您没有帮助。 EWMH规范扩展可以像针对vnc / vmware / stuff-like的新_NET_WM_WINDOW_TYPE一样简单,例如,窗口管理器可以减少其键绑定或为它们添加额外的修饰符,或者在该窗口聚焦时添加一些修饰符。