포커스가있는 창이나 포인터의 위치에 관계없이 모든 들어오는 키 누름 이벤트를 기록하고 싶습니다.X 포커스가있는 창에 관계없이 X 키 프레스/릴리스 이벤트
현재 포커스가있는 키 눌림 이벤트를 캡처해야하는 샘플 코드를 작성했습니다.
#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;
}
키보드를 캡처 한 응용 프로그램이 키보드 이벤트를 이미 가지고있을 수 있으므로 XGrabKeyboard를 호출하여 키보드를 캡처합니다. 위에서 언급 한 코드로 키보드를 잡을 수 있지만 while 루프 내부의 키보드에있는 키에 대해 KeyPress 또는 KeyRelease 이벤트를 수신 할 수 없습니다. 내가 이벤트를 수신 할 수 없기 때문에 코드에서 누락 된 것이 있습니까? 어떤 도움을 주셔서 감사합니다.
최종 목표는 포커스가있는 창에 관계없이 화면에서 주요 프레스 이벤트를 캡처하는 것입니다. 나는 코드를 읽을 수 있도록 포커스가있는 창만 샘플 코드를 제공했습니다. 나는 XQueryTree를 사용하여 모든 윈도우를 얻고 위에 주어진 동일한 로직을 적용하여 예상 된 결과를 얻는다.
왜 다음 이벤트 하위 시스템을 사용하지? –
이벤트 하위 시스템에 대해 자세히 설명해 주시겠습니까? KeyPressMask, KeyReleaseMask를 XSelectInput에 대한 호출에서 캡처 할 이벤트로 지정했습니다. 감사합니다 –
Ignacio Vazquez-Abrams는 리눅스 커널 입력 서브 시스템을 가리키며'/ dev/input /'의 문자 장치를 통해 접근 할 수 있습니다. X를 완전히 무시하고 커널에서 직접 HID 이벤트를 가져 오지만 루트 권한도 필요합니다. –