StructureNotifyMask가 Linux Mint의 다른 창을 방해합니다.

StructureNotifyMask가 Linux Mint의 다른 창을 방해합니다.

다음 코드를 기반으로 모든 키보드 입력을 캡처하려고합니다.이 답변. 실제 키 입력 캡처가 제대로 작동합니다. 그러나 Linux Mint Cinnamon에서 코드를 실행하면 다른 문제가 발생합니다.

  1. 마우스를 사용하여 창을 끌거나 크기를 조정할 수 없습니다.
  2. xed 및 nemo 메뉴 표시줄(파일, 보기 등)에서 옵션을 클릭하면 하위 메뉴 옵션이 표시되지 않습니다.
  3. 시작 메뉴를 클릭하면 앱 목록이 표시되지만 초점은 그 뒤에 있는 창에 유지되므로 앱 목록의 항목을 가리키거나 스크롤하거나 클릭할 수 없습니다.

다음은 간단하지만 기능적인 코드 버전입니다. 원인을 .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 작업)이 작동하지 않습니다.

관련 정보