【问题标题】:Excluding some keys from XGrabKeyboard从 XGrabKeyboard 中排除一些键
【发布时间】:2010-09-26 12:47:21
【问题描述】:

考虑一个应用程序,它希望在获得焦点时抓住键盘,以便捕获所有窗口管理器命令(Alt+F4 等)进行处理。现在,这有一个缺点,即用户在抓住键盘时无法通过键盘切换到另一个应用程序或虚拟桌面。我想要一个用户定义的组合键白名单(例如,用于切换虚拟桌面的组合键),这些组合键被排除在抓取之外。

我可以想到两种可能的方法。当一个列入白名单的关键事件到达时,要么

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

任何人都可以填写这些空白吗?还有其他建议吗?

如果没有办法从抓取中排除按键,我想我将不得不接受一个“退出键”,它在按下时会松开键盘。不过,用户必须同时按下这两个按钮,然后按下窗口管理器命令,这不是很好。

【问题讨论】:

    标签: keyboard x11 xlib


    【解决方案1】:

    我不认为有办法做到这一点。没有一种机制能完全按照您的需要工作。

    方法 1 类似于窗口管理器在决定不拦截点击或按键时所做的事情。但是,WM 在特定键上使用“被动”抓取(XGrabKey=passive XGrabKeyboard=active),然后是 XAllowEvents()。 XAllowEvents() 不适用于 XGrabKeyboard()。此外,当您使用其中一种重播模式进行 XAllowEvents 时,重播事件会绕过具有原始抓取的窗口及其所有父窗口上的所有被动抓取。 WM 的抓取将在根窗口上,该窗口始终是父窗口,因此无法重播到根窗口,我能说得最好。无论如何,对每一个可能的键都执行 XGrabKey 会有点变态。

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

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

    需要注意的是,我不知道 XKB 和 XInput2 可以做的所有疯狂的事情,所以也许这些扩展中有一些东西。

    无论如何,据我所知,您必须满足于“退出键”,尽管最终 X 服务器和/或窗口管理器规范具有“VMWare/VNC 类型的东西意识, “这在短期内对你没有帮助。例如,EWMH 规范扩展可以像 vnc/vmware/stuff-like 的新 _NET_WM_WINDOW_TYPE 一样简单,并且窗口管理器可以减少其键绑定或向它们添加额外的修饰符,或者当该窗口被聚焦时。

    【讨论】:

    • 我担心我会得到这样的答案。我敢肯定,如果可能的话,我会看到一个可以做到这一点的软件。但是,感谢您将我指向 XInput 2,我现在正在查看它,它似乎确实有获取输入设备的新方法。将运行一些测试,看看它是否使这成为可能
    • 原来这样的事情“可能安排在 XI2.1”,根据谷歌的说法,这似乎还不存在。然而,新的 WM 提示听起来并不是一个坏主意,因此我开始在 freedesktop.org wm-spec 列表上进行一些讨论。 mail.gnome.org/archives/wm-spec-list/2010-September/thread.html
    猜你喜欢
    • 2019-05-12
    • 1970-01-01
    • 1970-01-01
    • 2016-07-05
    • 2010-11-28
    • 2016-04-20
    • 1970-01-01
    • 1970-01-01
    • 2023-03-14
    相关资源
    最近更新 更多