Sending fake keypress events to an X11 window
This C++ example code will send a cursor-down event to the currently focussed window. It can easily be modified to send other key events. It would be a good starting point to write a virtual keyboard or remote control application.
// Send a fake keystroke event to an X window.
// by Adam Pierce - http://www.doctort.org/adam/
// This is public domain software. It is free to use by anyone for any purpose.
#include <X11/Xlib.h>
#include <X11/keysym.h>
// The key code to be sent.
// A full list of available codes can be found in /usr/include/X11/keysymdef.h
#define KEYCODE XK_Down
// Function to create a keyboard event
XKeyEvent createKeyEvent(Display *display, Window &win,
Window &winRoot, bool press,
int keycode, int modifiers)
{
XKeyEvent event;
event.display = display;
event.window = win;
event.root = winRoot;
event.subwindow = None;
event.time = CurrentTime;
event.x = 1;
event.y = 1;
event.x_root = 1;
event.y_root = 1;
event.same_screen = True;
event.keycode = XKeysymToKeycode(display, keycode);
event.state = modifiers;
if(press)
event.type = KeyPress;
else
event.type = KeyRelease;
return event;
}
main()
{
// Obtain the X11 display.
Display *display = XOpenDisplay(0);
if(display == NULL)
return -1;
// Get the root window for the current display.
Window winRoot = XDefaultRootWindow(display);
// Find the window which has the current keyboard focus.
Window winFocus;
int revert;
XGetInputFocus(display, &winFocus, &revert);
// Send a fake key press event to the window.
XKeyEvent event = createKeyEvent(display, winFocus, winRoot, true, KEYCODE, 0);
XSendEvent(event.display, event.window, True, KeyPressMask, (XEvent *)&event);
// Send a fake key release event to the window.
event = createKeyEvent(display, winFocus, winRoot, false, KEYCODE, 0);
XSendEvent(event.display, event.window, True, KeyPressMask, (XEvent *)&event);
// Done.
XCloseDisplay(display);
return 0;
}
To compile it, you need to type this:
g++ -o XFakeKey XFakeKey.cpp -L/usr/X11R6/lib -lX11

It is very good and very simple to understand example.
YES!!!
Finally I found what I looked for (I almost 7 hours searching the web for this little example!).
Adam Pierce - you are my hero!!!
Thanks Thanks Thanks
:) ;)
Thank you all for the positive comments. I also spent hours trying to find something like this and ended up having to write it myself.
It’s nice example.
Brilliant, I have thought for ages that there must be a way to do this programmatically but had real trouble finding it actually written out somewhere online.
Thanks a lot.
Excellent example. However, one thing should be noted:
I found out you have to request the focus window for every new key event you send
getfocus(), keypress(), keyrelease() will not work
while
getfocus(), keypress(), getfocus(), keyrelease() works perfectly.
nice! i searched 10 hours for something like this in QT4, but now i use this.
Thanks, just what I needed!
How about hotkeys like CTRL+L. How can I simulate it?
Try setting the “modifiers” parameter of the createKeyEvent function with values like XK_Shift_L or XK_Meta_L. See /usr/include/X11/keysymdef.h for a list of possible values.
FYI for those who don’t know, you can run ‘xev’ in a terminal to get keycodes - it opens a small window while it runs, then information on all keypresses are output to the terminal. For example: I typed “hi”
KeyPress event, serial 23, synthetic NO, window 0×4c00001,
root 0×59, subw 0×0, time 153093161, (423,461), root:(424,491),
state 0×10, keycode 43 (keysym 0×68, h), same_screen YES,
XLookupString gives 1 bytes: (68) “h”
XmbLookupString gives 1 bytes: (68) “h”
XFilterEvent returns: False
KeyRelease event, serial 26, synthetic NO, window 0×4c00001,
root 0×59, subw 0×0, time 153093232, (423,461), root:(424,491),
state 0×10, keycode 43 (keysym 0×68, h), same_screen YES,
XLookupString gives 1 bytes: (68) “h”
XFilterEvent returns: False
KeyPress event, serial 26, synthetic NO, window 0×4c00001,
root 0×59, subw 0×0, time 153093374, (423,461), root:(424,491),
state 0×10, keycode 31 (keysym 0×69, i), same_screen YES,
XLookupString gives 1 bytes: (69) “i”
XmbLookupString gives 1 bytes: (69) “i”
XFilterEvent returns: False
KeyRelease event, serial 26, synthetic NO, window 0×4c00001,
root 0×59, subw 0×0, time 153093434, (423,461), root:(424,491),
state 0×10, keycode 31 (keysym 0×69, i), same_screen YES,
XLookupString gives 1 bytes: (69) “i”
XFilterEvent returns: False
So, keycode 43 is ‘h’ and 31 is ‘i’ - *on my keyboard*. It may or may not be different for you.. I’m not really sure.
In any case, this should help a lot. I’ve been having troubles with Super and CTRL getting stuck on this new laptop somehow, so maybe I can use this to force a key-release…
Wow! Thanks Adam! This is invaluable. I just used XFakeKey to talk to my “headless firefox” inside of xvfb. The down clicks are working, the screenshots are changing!! Very exciting.
This has got me one step closer. But what I need is to be able to do is set keyboard focus on an already open window (in this case firefox), and then hit a key. how do you change window focus? I’ve Googled and not found a simple way yet. Oh and I’m trying to do it in Ruby but if you point me to a lib or just a C example I’ll probly find a method to bind to it.
Thanks and fine work Adam