XGrabKeyboard仅在程序运行时阻止键盘

时间:2013-02-03 18:42:51

标签: c++ linux qt x11

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

2 个答案:

答案 0 :(得分:0)

来自man XGetKeyboard

  

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

这是设计上的。否则,键盘可能被一个已经失效的应用程序无限期地抓住,用户不会理解。当然,窗口仍然可见(它是根窗口),但显示连接已关闭,因此基本原理是相同的。

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

答案 1 :(得分:0)

Quoth the manual

  

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

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

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

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