3

我想记录所有传入的按键事件,无论哪个窗口处于焦点或指针在哪里。我已经编写了示例代码,它应该捕获当前窗口的按键事件(见下文)。为了保持我的代码可读性,我只给出了焦点窗口的示例代码。由于我的最终目标是捕获屏幕上的按键事件,而不考虑焦点所在的窗口,因此我计划用于XQueryTree获取所有 Windows 并应用相同的逻辑。

我打电话XGrabKeyboard来捕捉键盘,因为焦点窗口可能已经在捕捉键盘事件。使用我的示例代码,我可以抓取键盘,但无法接收循环内任何键盘键的事件KeyPressKeyReleasewhile

我在代码中遗漏了什么以允许我接收事件?

示例代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <locale.h>
#include <stdint.h>
#include <stdarg.h>
#include <errno.h>
#include <pthread.h>
#include <X11/Xlib.h>
#include <X11/Xos.h>
#include <X11/Xfuncs.h>
#include <X11/Xutil.h>

#include <X11/Xatom.h>
int _invalid_window_handler(Display *dsp, XErrorEvent *err) {
    return 0;
}

int main() 
{
    Display *display = XOpenDisplay(NULL); 
    int iError;
    KeySym k;
    int revert_to;
    Window window;
    XEvent event;
    Time time;
    XSetErrorHandler(_invalid_window_handler);
    XGetInputFocus(display, &window, &revert_to);
    XSelectInput(display, window, KeyPressMask | KeyReleaseMask );
    iError = XGrabKeyboard(display, window,
                          KeyPressMask | KeyReleaseMask,
                          GrabModeAsync,
                          GrabModeAsync,
                          CurrentTime); 
    if (iError != GrabSuccess && iError == AlreadyGrabbed) {
        XUngrabPointer(display, CurrentTime);
        XFlush(display);
        printf("Already Grabbed\n");    
    } else if (iError == GrabSuccess) {
        printf("Grabbed\n");
    }
    while(1) {
          XNextEvent(display,&event);
          switch (event.type) {
              case KeyPress : printf("Key Pressed\n"); break;
              case KeyRelease : printf("Key Released\n"); break;
              case EnterNotify : printf("Enter\n"); break;
          }
    }
    XCloseDisplay(display);
    return 0;
}
4

1 回答 1

1

XGrabKeyboard 的参数 3 是引用手册页:

owner_events :指定一个布尔值,指示是否要像往常一样报告键盘事件。

所以应该是真或假,而不是事件掩码。

于 2013-03-18T13:44:12.093 回答