skip to Main Content

I’ve been trying for a while to achieve this but I can’t.
XNextEvent is never called.
I’m using Ubuntu 22.04.
This is the code I have so far.
I want to print both clicks and mouse moves.
I’ve tried using XAllowEvents, XGrabPointer it won’t work. Why?

#include <stdio.h>
#include <X11/Xlib.h>

char *key_name[] = {
    "first",
    "second (or middle)",
    "third",
    "fourth",  // :D
    "fivth"    // :|
};

int main(int argc, char **argv)
{
    Display *display;
    XEvent xevent;
    Window window;

    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);

        switch (xevent.type) {
            case MotionNotify:
                printf("Mouse move      : [%d, %d]n", xevent.xmotion.x_root, xevent.xmotion.y_root);
                break;
            case ButtonPress:
                printf("Button pressed  : %sn", key_name[xevent.xbutton.button - 1]);
                break;
            case ButtonRelease:
                printf("Button released : %sn", key_name[xevent.xbutton.button - 1]);
                break;
        }
    }

    return 0;
}

2

Answers


  1. Chosen as BEST ANSWER

    We don't recieve nothing when calling XNextEvent because This is not how X11 windowing system works.

    The key point is:

    The source of the event is the viewable window that the pointer is in.

    I do not create a window, therefore my program doesn't receive keyboard events. Even if i'd created window, it has to have focus :

    The window used by the X server to report these events depends on the window's position in the window hierarchy and whether any intervening window prohibits the generation of these events.

    The "hack" i'm using is reading /dev/input/eventX which is the place where Linux saves the logs of mouse and from there I can choose which event i'm interested in and do the logic. To get even more information I did use x11 lib using XQueryPointer to get the window where the pointer is at only when i'm interested in knowing that ex: user makes a click.


  2. XSelectInput is your friend.

    There are two ways to select the events you want reported to your client application. One way is to set the event_mask member of the XSetWindowAttributes structure when you call XCreateWindow and XChangeWindowAttributes. Another way is to use XSelectInput.

    The functions you’re looking for to obtain window informations are XQueryTree or XQueryPointer. See also the complete list: Obtaining Window Information.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search