0

I'm trying to listen to pointer motion events on an already created window (not by me), so first I got the window id using xwininfo and hardcoded it for testing, I tested it with different windows ids and for some windows it worked and for others it didn't.

alacritty window id: not working mpv window id: working

Compile with: gcc pointermotion.c -o pointermotion -lxcb

#include <assert.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <xcb/xcb.h>
#include <xcb/xproto.h>

int
main(int argc, char **argv) {
    xcb_connection_t *connection;
    xcb_generic_event_t *ev;
    xcb_motion_notify_event_t *mnev;
    xcb_get_window_attributes_cookie_t cookie;
    xcb_get_window_attributes_reply_t *reply;
    xcb_window_t window;

    connection = xcb_connect(NULL, NULL);
    window = 0x3000002;

    xcb_change_window_attributes(connection, window, XCB_CW_EVENT_MASK, (const uint32_t [1]) { XCB_EVENT_MASK_POINTER_MOTION });
    xcb_flush(connection);

    cookie = xcb_get_window_attributes_unchecked(connection, window);
    reply = xcb_get_window_attributes_reply(connection, cookie, NULL);

    assert(reply->your_event_mask == XCB_EVENT_MASK_POINTER_MOTION);

    free(reply);

    while (1) {
        while ((ev = xcb_poll_for_event(connection))) {
            switch (ev->response_type & ~0x80) {
                case XCB_MOTION_NOTIFY:
                    mnev = (xcb_motion_notify_event_t *)(ev);
                    printf("%d, %d\n", mnev->event_x, mnev->event_y);
                    break;
                default:
                    break;
            }

            free(ev);
        }
    }

    return 0;
}
alpheratz
  • 1
  • 1
  • It is possible that the window you are using to subscribe is entirely covered by its child window, and that child window has a client that selected pointer motion events. – n. m. could be an AI Apr 20 '22 at 16:08
  • totally guessing here, I know nothing about xcb, but calls to raw `free` look suspicious to me. In my experience working with 3rd party libraries, if there's an allocate function (eg, `xcb_get_window_attributes_reply`), there's usually a corresponding `free` function (eg, `xcb_free_reply(reply)`. Are you sure you should be calling raw `free` on `reply` and `ev`? – yano Apr 20 '22 at 16:11
  • You could take a peek at the source code for xev. – Allan Wind Apr 20 '22 at 16:46
  • @n.1.8e9-where's-my-sharem. I tried setting the event mask for every window, traversing the tree from the root window but I got the same results. – alpheratz Apr 20 '22 at 18:36
  • 1
    @yano it is rare but thats the only way to do it . From `xproto.h`: "The returned value must be freed by the caller using free() – alpheratz Apr 20 '22 at 18:40
  • @AllanWind xev is written using Xlib, I ran `xev -id 0x3000002` but no pointer motion event was ever logged so no point in looking at xev source (I did). – alpheratz Apr 20 '22 at 18:43
  • @alpheratz did you try run xev without -id? Maybe you have the wrong id? I am definitely getting pointer events (MotionNotify, BUttonPress, ButtonRelease etc) on it's window. – Allan Wind Apr 20 '22 at 18:46
  • @AllanWind motion events are shown when I move the cursor over the xev window (the one with the black square), but I'm not getting pointer motion events when I do the same thing over an Alacritty/Chrome window – alpheratz Apr 20 '22 at 19:07
  • Apparently this is a known issue, there are several related questions e.g. [one](https://stackoverflow.com/questions/28578220/process-receiving-x11-selectionnotify-event-xev-doesnt-show-the-event-why-is) [two](https://stackoverflow.com/questions/30032416/xcb-not-receiving-motion-notify-events-on-all-windows) – n. m. could be an AI Apr 20 '22 at 19:25

0 Answers0