3
我想記錄所有傳入的按鍵事件,無論哪個窗口處於焦點或指針所在的位置。我寫了一些示例代碼,它應該捕獲當前焦點窗口的按鍵事件(請參見下文)。爲了保持我的代碼的可讀性,我僅爲焦點窗口提供了示例代碼。由於我的最終目標是捕獲屏幕上的關鍵新聞事件,而不考慮窗口焦點,我打算使用XQueryTree
獲取所有Windows並應用相同的邏輯。爲什麼我無法從循環中捕獲這些KeyPress/KeyRelease事件?
我打電話XGrabKeyboard
捕捉鍵盤,作爲焦點的窗口可能已經抓住了鍵盤事件。使用我的示例代碼,我可以抓住鍵盤,但無法接收while
循環內任何鍵盤按鍵的KeyPress
或KeyRelease
事件。
什麼我的代碼所缺少讓我接收的事件?
示例代碼:
#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;
}