Ubuntu热键与X11 / xlib,X错误:BadAccess

3

我尝试创建一个完全基于快捷键的应用程序,我使用Xlib编写了一些代码,在CentOS 6上运行良好。当我在我们的Ubuntu(14.04)开发环境中尝试时,出现以下异常:

X Error of failed request:  BadAccess (attempt to access private resource denied)
  Major opcode of failed request:  33 (X_GrabKey)
  Serial number of failed request:  10
  Current serial number in output stream:  13

这里是代码

void* manage_hotkeys(void* arg)
    {
        Window root;
        XEvent ev;
        Display* dpy = XOpenDisplay(0);    
        char* ckeystr = "c";
        ...

        if (!dpy)
        {
            printf("Failed to get Display\n");
            exit(EXIT_FAILURE);
        }

        root = DefaultRootWindow(dpy);
        KeyCode ckey = XKeysymToKeycode(dpy, XStringToKeysym(ckeystr)); // control panel

        // grab keys
        XGrabKey(dpy, ckey, AnyModifier, root, True, GrabModeAsync, GrabModeAsync);
        ....
        while (1)
        {
            printf("Beginning of hotkey loop\n");
            XNextEvent(dpy, &ev);
            if (ev.type == KeyPress)
            {
                printf("Key press event!\n");

                if (ev.xkey.keycode == ckey)
                {
                    // stuff...
                } else if .....
            } // if
        } // while

    ...
        XUngrabKey(dpy, ckey, AnyModifier, root);
    ...

        pthread_exit(NULL);
    } // hotkeythread

我查看了其他的SO线程(比如这个),但它们似乎不适用于我,因为我正在监听单个按键(例如'c')。我不常编写C代码,所以有点生疏,选择了第一个可用的示例(至少在CentOS上),请帮助我调试。

根据我的研究,我认为Ubuntu中的某些进程已经获取了这些按键或其他东西?我该如何找出那个进程?还有其他的方法吗?我只需要获取键盘输入,而不管焦点窗口是什么,xgrabkey似乎是最简单的方法... 请帮忙。


1个回答

2
“X请求失败的错误”(也称为异常)可以通过使用XSetErrorHandler函数在您的应用程序中拦截。仅设置此错误处理程序可以完全消除意外退出。因此,实际想要的是拦截特定错误、忽略或记录它,然后使所有其他错误仍终止应用程序。这可以通过解释XErrorEvent结构来完成,例如:
// Early in your application
XSetErrorHandler( x_error_handler );

//...

int x_error_handler( Display* dpy, XErrorEvent* pErr )
{
    printf("X Error Handler called, values: %d/%lu/%d/%d/%d\n",
        pErr->type,
        pErr->serial,
        pErr->error_code,
        pErr->request_code,
        pErr->minor_code );
    if( pErr->request_code == 33 ){  // 33 (X_GrabKey)
        if( pErr->error_code == BadAccess ){
            printf("ERROR: A client attempts to grab a key/button combination already\n"
                   "        grabbed by another client. Ignoring.\n");
            return 0;
        }
    }
    exit(1);  // exit the application for all unhandled errors.
    return 0;
}

否则,仅凭这些错误值的解释无法导致确切的键组合以及哪个进程/客户端已经抓住了它,我认为。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接