StructureNotifyMask 会干扰 Linux Mint 上的其他窗口

StructureNotifyMask 会干扰 Linux Mint 上的其他窗口

我正在尝试根据以下代码捕获所有键盘输入这个答案。实际的按键捕获工作正常。然而,在 Linux Mint Cinnamon 上运行代码会导致其他问题:

  1. 我无法使用鼠标拖动任何窗口或调整其大小
  2. 单击 xed 和 nemo 菜单栏中的选项(文件、视图等...)不会显示子菜单选项
  3. 单击开始菜单会显示应用程序列表,但焦点由其后面的窗口保留,因此我无法悬停、滚动或单击应用程序列表中的项目。

下面是代码的简化但实用的版本。我已将原因缩小到StructureNotifyMask中存在事件掩码XSelectInput。如果没有该事件掩码,则不会出现上述问题。但这也意味着当窗口被映射时程序不会收到通知,因此捕获不起作用。

如何在不出现上述任何问题的情况下开始捕获工作?我尝试XSelectInput在程序收到仅具有按键和释放事件掩码的映射通知后添加一秒钟。然而,这似乎并不能解决问题。

#include <X11/Xlib.h>
#include <X11/keysym.h>
#include <stdio.h>

int main()
{
    显示*显示;
    窗口window、rootwindow;
    XEvent事件;
    KeySym 转义;

    显示 = XOpenDisplay(NULL);
    rootwindow = DefaultRootWindow(显示);
    窗口 = XCreateWindow(显示, 根窗口,
                           -99, -99, 1, 1, /* x, y, 宽度, 高度 */
                           0, 0, InputOnly, /* 边框、深度、类 */
                           CopyFromParent, /* 视觉 */
                           0、空); /* 值掩码和属性 */

    XSelectInput(显示、窗口、StructureNotifyMask | KeyPressMask | KeyReleaseMask);    

    XMapWindow(显示,窗口);

    做 {
        XNextEvent(显示,&事件);
    while (event.type != MapNotify);

    XGrabKeyboard(显示、窗口、False、GrabModeAsync、GrabModeAsync、CurrentTime);

    转义 = XKeysymToKeycode(显示, XK_Escape);
    printf("\n按 ESC 退出。\n\n");
    fflush(标准输出);

    而(1){

        XNextEvent(显示,&事件);

        if (event.type == KeyPress) {
            printf("按键:按键代码 %u 状态 %u\n", event.xkey.keycode, event.xkey.state);
            fflush(标准输出);

        } 别的
        if (event.type == KeyRelease) {

            printf("KeyRelease: 键码 %u 状态 %u\n", event.xkey.keycode, event.xkey.state);
            fflush(标准输出);

            if (event.xkey.keycode == escape)
                休息;
        } 别的 {

            printf("事件​​类型 %d\n", event.type);
            fflush(标准输出);
        }
    }

    XUngrabKeyboard(显示,当前时间);

    XDestroyWindow(显示, 窗口);
    X关闭显示(显示);
    返回0;
}

答案1

你不能做一个永久的XGrabKeyboard。只要某种交互正在进行,这种抓取就只能暂时使用。

如果你继续按住抓取,所有其他需要抓取的功能(比如你提到的 WM 操作)将无法工作。

相关内容