2

我正在编写一个代码来获取按下的键并阻止键盘输入。示例:如果按下 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;
        }
    }
}
4

2 回答 2

1

来自man XGetKeyboard

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

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

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

于 2013-02-03T18:53:44.513 回答
1

Quoth手册

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

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

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

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

于 2013-02-03T19:30:41.400 回答