Originally published 2009-11-08 00:00:00

Sending Keystrokes to Applications in Linux (Programatically)

Lately I've been using the Awesome window manager, a simple dynamic window manager based on dwm. It's great, but it seems to fight with imwheel, which I've long used to map my mouse's thumb buttons to page-up and page-down. I wondered: why is there no reasonable imwheel alternative?

I tried xrebind and xnee, but it wasn't easy to get either to do what I wanted. I realized that Awesome has a built-in mouse binding support, but doesn't have a way to send keystrokes to client applications. So, I ended up figuring out a little C program that sends a keystroke to the focused client, and telling Awesome to run the program with the appropriate argument when the mouse thumb buttons are pressed.

Here's the C code:

#include <X11/extensions/XTest.h>

int main(int argc, char **argv) {
    int keycode;
    Display *dpy = XOpenDisplay(NULL);
    if (!dpy) return 1;

    keycode = atoi(argv[1]);
    
    XTestFakeKeyEvent(dpy, keycode, 0, CurrentTime);
    XCloseDisplay(dpy);
    return 0;
}

And here's the Awesome config:

mouse
{
        client
        {
            button = "8"
            command = "spawn"
            arg = "exec /home/adam/.local/bin/sendkey 117"
        }
        client
        {
            button = "9"
            command = "spawn"
            arg = "exec /home/adam/.local/bin/sendkey 112"
        }
}

Perhaps someone else will find this useful (or integrate it into Awesome).