【问题标题】:XGrabKeyboard only blocks the keyboard while the program is runningXGrabKeyboard 仅在程序运行时阻止键盘
【发布时间】:2013-01-18 12:20:00
【问题描述】:

我正在编写代码来获取按下的键并阻止键盘输入。示例:如果按下 Super_L 或 Super_R 键,阻止它们打开应用程序菜单。该代码在程序打开时工作,但当程序关闭时,密钥被发送到系统。示例:如果用户在程序运行时按下 Super_L 键没有任何反应,但当程序关闭时,Ubuntu 应用程序菜单会自动打开。我该如何解决这个问题?

void hook()
{
    Display *dpy = XOpenDisplay(0);
    XEvent ev;

    if(!dpy)
    {
        qDebug() << "Error";
        return;
    }

    XGrabKeyboard(dpy, DefaultRootWindow(dpy), false, GrabModeAsync, GrabModeAsync, CurrentTime);

    forever
    {
        XNextEvent(dpy, &ev);
        switch (ev.type)
        {
        case KeyPress:
            qDebug() << "KeyPress" << XKeysymToString(XKeycodeToKeysym(dpy, ev.xkey.keycode, 0));
            break;
        case KeyRelease:
            qDebug() << "KeyRelease" << XKeysymToString(XKeycodeToKeysym(dpy, ev.xkey.keycode, 0));
            break;
        }
    }
}

【问题讨论】:

    标签: c++ linux qt x11


    【解决方案1】:

    Qthe manual:

    当 X 服务器与客户端的连接被关闭时 显式调用 XCloseDisplay() 或由退出的进程 X 服务器执行以下自动操作:

    • 它否认客户拥有的所有选择(请参阅XSetSelectionOwner())。
    • 如果客户端主动抓住了指针或键盘,它将执行XUngrabPointer()XUngrabKeyboard()
    • 如果客户端已经抓取了服务器,它会执行XUngrabServer()
    • 它会释放客户端所做的所有被动抓取。

    Grabs 由客户请求并授予客户。在抓取期间,所有相关事件都将传递给抓取客户端。没有客户,就没有抢。

    我看不出这里有什么要解决的。如果您希望某项功能正常工作,请确保实现它的应用程序正在运行。

    【讨论】:

      【解决方案2】:

      来自man XGetKeyboard

      如果活动键盘抓取的事件窗口变得不可见,X 服务器会自动执行 UngrabKeyboard 请求。

      这是设计使然。否则,键盘可能会被一个已失效的应用程序无限期地抓住,而用户不会对此感到满意。当然,窗口仍然是可见的(它是根窗口)但是显示连接是关闭的,所以基本原理是一样的。

      如果您的应用程序在关闭后仍需要保持抓取...那么,您将不得不留在后台而不实际退出。

      【讨论】:

      • Ok "如果活动键盘抓取的事件窗口变得不可见,X 服务器会自动执行 UngrabKeyboard 请求。"但是为什么程序运行时按下的键会在程序关闭时触发?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-02-04
      • 2017-02-18
      • 1970-01-01
      • 2012-08-27
      • 1970-01-01
      • 1970-01-01
      • 2022-01-04
      相关资源
      最近更新 更多