다음 코드를 기반으로 모든 키보드 입력을 캡처하려고합니다.이 답변. 실제 키 입력 캡처가 제대로 작동합니다. 그러나 Linux Mint Cinnamon에서 코드를 실행하면 다른 문제가 발생합니다.
- 마우스를 사용하여 창을 끌거나 크기를 조정할 수 없습니다.
- xed 및 nemo 메뉴 표시줄(파일, 보기 등)에서 옵션을 클릭하면 하위 메뉴 옵션이 표시되지 않습니다.
- 시작 메뉴를 클릭하면 앱 목록이 표시되지만 초점은 그 뒤에 있는 창에 유지되므로 앱 목록의 항목을 가리키거나 스크롤하거나 클릭할 수 없습니다.
다음은 간단하지만 기능적인 코드 버전입니다. 원인을 .NET StructureNotifyMask
에 이벤트 마스크가 있는 것으로 좁혔습니다 XSelectInput
. 이 이벤트 마스크가 없으면 위의 문제는 발생하지 않습니다. 하지만 이는 창이 매핑될 때 프로그램에 알리지 않으므로 캡처가 작동하지 않는다는 의미이기도 합니다.
위의 문제 없이 캡처 작업을 시작하려면 어떻게 해야 합니까? XSelectInput
프로그램이 키 누르기 및 릴리스 이벤트 마스크만으로 매핑된 알림을 받은 후 1초를 추가해 보았습니다 . 그러나 이것은 문제를 해결하지 못하는 것 같습니다.
#include <X11/Xlib.h> #include <X11/keysym.h> #include <stdio.h> 정수 메인() { 디스플레이*디스플레이; 창, 루트창; XEvent 이벤트; KeySym 탈출; 디스플레이 = XOpenDisplay(NULL); rootwindow = DefaultRootWindow(display); window = XCreateWindow(표시, 루트 창, -99, -99, 1, 1, /* x, y, 너비, 높이*/ 0, 0, InputOnly, /* 테두리, 깊이, 클래스*/ CopyFromParent, /* 비전*/ 0, 비어 있음) /* 값 마스크 및 속성*/ XSelectInput(display, window, StructureNotifyMask | KeyPressMask | KeyReleaseMask); XMapWindow(표시, 창); 하다 { XNextEvent(display,&event); while(event.type != MapNotify); XGrabKeyboard(Display,Window,False,GrabModeAsync,GrabModeAsync,CurrentTime); escape = XKeysymToKeycode(display, XK_Escape); printf("\n종료하려면 ESC를 누르세요.\n\n"); fflush(표준 출력); 그리고 (1){ XNextEvent(display,&event); if (event.type == KeyPress) { printf("키: 키 코드 %u 상태 %u\n", event.xkey.keycode, event.xkey.state); fflush(표준 출력); } 기타 if (event.type == KeyRelease) { printf("KeyRelease: 키 코드 %u 상태 %u\n", event.xkey.keycode, event.xkey.state); fflush(표준 출력); if (event.xkey.keycode == 이스케이프) 나머지; } 다른 { printf("이벤트 유형 %d\n", event.type); fflush(표준 출력); } } XUngrabKeyboard(표시, 현재 시간); XDestroyWindow(디스플레이, 창); XCloseDisplay(디스플레이); 0을 반환합니다. }
답변1
영구적인 것을 만들 수는 없습니다 XGrabKeyboard
. 이러한 종류의 가져오기는 일부 상호 작용이 진행되는 동안 일시적으로만 사용할 수 있습니다.
잡기를 계속 누르고 있으면 잡기가 필요한 다른 모든 기능(예: 언급한 WM 작업)이 작동하지 않습니다.