fsoc
fsoc

Reputation: 71

XTestFakeKeyEvent calls get swallowed

I'm trying to spoof keystrokes; to be a bit more precise: I'm replaying a number of keystrokes which should all get sent at a certain time - sometimes several at the same time (or at least as close together as reasonably possible).

Implementing this using XTestFakeKeyEvent, I've come across a problem. While what I've written so far mostly works as it is intended and sends the events at the correct time, sometimes a number of them will fail. XTestFakeKeyEvent never returns zero (which would indicate failure), but these events never seem to reach the application I'm trying to send them to. I suspect that this might be due to the frequency of calls being too high (sometimes 100+/second) as it looks like it's more prone to fail when there's a large number of keystrokes/second.

A little program to illustrate what I'm doing, incomplete and without error checks for the sake of conciseness:

// #includes ...

struct action {
    int time; // Time where this should be executed.
    int down; // Keydown or keyup?
    int code; // The VK to simulate the event for.
};

Display *display;

int nactions;           // actions array length.
struct action *actions; // Array of actions we'll want to "execute".

int main(void)
{
    display = XOpenDisplay(NULL);

    nactions = get_actions(&actions);

    int cur_time;
    int cur_i = 0;
    struct action *cur_action;

    // While there's still actions to execute.
    while (cur_i < nactions) {
        cur_time = get_time();
        cur_action = actions + cur_i;

        // For each action that is (over)due.
        while ((cur_action = actions + cur_i)->time <= cur_time) {
            cur_i++;

            XTestFakeKeyEvent(display, cur_action->code,
                cur_action->down, CurrentTime);
            XFlush(display);
        }

        // Sleep for 1ms.
        nanosleep((struct timespec[]){{0, 1000000L}}, NULL);
    }
}

I realize that the code above is very specific to my case, but I suspect that this is a broader problem - which is also why I'm asking this here.

Is there a limit to how often you can/should flush XEvents? Could the application I'm sending this to be the issue, maybe failing to read them quickly enough?

Upvotes: 3

Views: 342

Answers (1)

fsoc
fsoc

Reputation: 71

It's been a little while but after some tinkering, it turned out that my delay between key down and key up was simply too low. After setting it to 15ms the application registered the actions as keystrokes properly and (still) with very high accuracy.

I feel a little silly in retrospect, but I do feel like this might be something others could stumble over as well.

Upvotes: 3

Related Questions