ChemiCalChems
ChemiCalChems

Reputation: 643

Getting double RawKeyPress events using Xinput2

So yesterday, I checked out the xinput source code in order to mimic what's being done there so I could make a keystroke listener for a project I'm making.

After checking out the source code, especially test_xi2.c, I came around with this.

#include <iostream>
#include <X11/Xlib.h>
#include <X11/extensions/XInput2.h>
#include <X11/Xutil.h>
#include <stdio.h>
#include <stdlib.h>


int main() {
    Display* display = XOpenDisplay(NULL);
    Window win;
    win = DefaultRootWindow(display);


    XIEventMask* m = new XIEventMask;

    m->deviceid = XIAllDevices;
    m->mask_len = XIMaskLen(XI_LASTEVENT);
    m->mask = (unsigned char*)calloc(m->mask_len, sizeof(char));

    XISetMask(m->mask, XI_RawKeyPress);
    XISetMask(m->mask, XI_RawKeyRelease);

    XISelectEvents(display, win, m, 1);

    XSync(display, False);

    while(true)
        {
            XEvent ev;
            XGenericEventCookie *cookie = (XGenericEventCookie*)&ev.xcookie;
            XNextEvent(display, (XEvent*)&ev);

            if (XGetEventData(display, cookie) && cookie->type == GenericEvent) {
                switch (cookie->evtype) {
                case XI_RawKeyPress: std::cout << "keystroke" << std::endl; break;
                }
            }


            XFreeEventData(display, cookie);
        }

    XDestroyWindow(display, win);

    return 0;
}

You compile this by doing g++ main.cpp -lX11 -lXi.

So, if you compare it to the original source, you'll see the only thing I don't do, apart from listening for all the other event types that are useless to me at the moment, is the check whether cookie->extension == xi_opcode (line 431 of test_xi2.c). After researching a bit, I came to the conclusion that it isn't really necessary to check whether this condition is met. xi_opcode turns out to be an extension opcode, that is queried using XQueryExtension here. I've checked on my machine, and the extension seems to always be 131, so it's not like half of the RawKeyPress events have one extension and the other half have another extension.

I really can't tell what else could be going on.

Upvotes: 0

Views: 907

Answers (1)

rubenvb
rubenvb

Reputation: 76519

It seems XIAllDevices also captures virtual "extra" devices, which in this case includes a second keyboard, which means you will get all keyboard events times 2.

Try using XIAllMasterDevices which takes together all these into one "keyboard".

Upvotes: 3

Related Questions