Как использовать использовать XNextEvent, XPeekEvent и XPutBackEvent - PullRequest
1 голос
/ 24 октября 2019

Я пытаюсь разработать небольшое приложение для Linux для выполнения измерений непосредственно на экране, т. Е. Для измерения расстояний и углов в изображениях, документах и ​​т. Д.

С этой целью меня вдохновило Как слушатьдля событий мыши в Linux? и думал, что я мог бы использовать XNextEvent или XPeekEvent и, возможно, XPutBackEvent. Эта программа хорошо реагирует на события мыши, но поскольку она использует XNextEvent, корзина останавливается там, и событие не отправляется в целевое окно, и мышь становится бесполезной, и если я использую XPutBackEvent, то же событие возвращается снова. Чтобы это исправить, я заменил XNextEvent на XPeekEvent, который должен отправлять событие вверх по лестнице. Это не помогло, но усугубило ситуацию, послав бесконечный поток одного и того же события, и фильтрация одинаковых событий тоже не помогла.

Заранее благодарен за любой совет, чтобы решить эту проблему.


Проблема в основном в том, что события не исчезают, и я не знаю, как от них избавиться, чтобы можно было использовать мышь. Код ниже скопирован из Как прослушивать события мыши в Linux? и несколько изменен.

#include <stdio.h>
#include <X11/Xlib.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
char *key_name[] = {
    "first",
    "second (or middle)",
    "third",
    "fourth",  // :D
    "fivth"    // :|
};

int main(int argc, char **argv)
{
    Display *display;
    XEvent xevent,oldevent;
    Window window;
        long unsigned int buttontime=0;
    if( (display = XOpenDisplay(NULL)) == NULL )
        return -1;


    window = DefaultRootWindow(display);
    XAllowEvents(display, AsyncBoth, CurrentTime);

    XGrabPointer(display, 
                 window,
                 1, 
                 //PointerMotionMask | 
                 ButtonPressMask | ButtonReleaseMask , 
                 GrabModeAsync,
                 GrabModeAsync, 
                 None,
                 None,
                 CurrentTime);
    while(1)
     {
        XNextEvent(display, &xevent);
        //XPeekEvent(display, &xevent);
        switch (xevent.type) {
            /*case MotionNotify:
                printf("Mouse move      : [%d, %d]\n", xevent.xmotion.x_root, xevent.xmotion.y_root);
                break;*/
            case ButtonPress:
                //if ((buttontime <= xevent.xbutton.time))
                    {
                printf("Button pressed  : %s\n", key_name[xevent.xbutton.button - 1]);
                printf("timevent %lu\n",xevent.xbutton.time);
                printf("timeold %lu\n",buttontime);
                buttontime = xevent.xbutton.time;
                buttontime++;
              }
                break;
            case ButtonRelease:
                printf("Button released : %s\n", key_name[xevent.xbutton.button - 1]);
                break;
        }
       // XPutBackEvent(display, &xevent);
        sleep(1);
    }

    return 0;
}
...