Looking for a way to simulate keyboard and mouse input? The web is full of various guides and tutorials mentioning xdotool, a “command-line X11 automation tool.” xdotool simulates X11 input events; it can even move or resize the desktop windows.
Unfortunately, as its name implies, xdotool only works with the X11 window system. This means it cannot work in Wayland sessions due to the stricter security constraints defined by the Wayland protocol. The functionality provided by xdotool is still invaluable though. Fortunately, there is a set of utilities that provide very similar functionality as xdotool. Because it works by simulating input devices directly, evemu works in both Wayland sessions and X11 desktop sessions.
Evemu is not a drop-in replacement for xdotool, nor was it designed to be. For example, it does not have a feature similar to mousemove. Instead, evemu records device input events. Careful study of the output and modification of the sequence of events will yield the desired simulated event. This article will introduce evemu and demonstrate how it can be used to simulate input events much like xdotool does.
Installation
evemu is available in the Fedora repositories, so installation is straightforward:
sudo dnf install evemu
List devices
First, see what devices are present on the system by looking in /dev/input/by-id/ and /dev/input/by-path/. Alternatively, the evemu-describe command will enumerate events for each attached device:
$ sudo evemu-describe Available devices: /dev/input/event0: Power Button /dev/input/event1: Sleep Button /dev/input/event2: AT Translated Set 2 keyboard /dev/input/event3: ImExPS/2 Generic Explorer Mouse /dev/input/event4: VirtualBox USB Tablet /dev/input/event5: Video Bus /dev/input/event6: VirtualBox mouse integration Select the device event number [0-6]: 3 ... # Supported events: # Event type 0 (EV_SYN) # Event code 0 (SYN_REPORT) # Event code 1 (SYN_CONFIG) # Event code 2 (SYN_MT_REPORT) # Event code 3 (SYN_DROPPED) # Event code 4 ((null)) # Event code 5 ((null)) # Event code 6 ((null)) # Event code 7 ((null)) # Event code 8 ((null)) # Event code 9 ((null)) # Event code 10 ((null)) # Event code 11 ((null)) # Event code 12 ((null)) # Event code 13 ((null)) # Event code 14 ((null)) # Event code 15 (SYN_MAX) # Event type 1 (EV_KEY) # Event code 272 (BTN_LEFT) # Event code 273 (BTN_RIGHT) # Event code 274 (BTN_MIDDLE) # Event code 275 (BTN_SIDE) # Event code 276 (BTN_EXTRA) # Event type 2 (EV_REL) # Event code 0 (REL_X) # Event code 1 (REL_Y) # Event code 6 (REL_HWHEEL) # Event code 8 (REL_WHEEL) ...
Mouse
In this case, /dev/input/event3 is the mouse. Record its input events by running:
$ sudo evemu-record --autorestart=3 /dev/input/event3 /tmp/mouse ^C$
This command creates a file named /tmp/mouse.<timestamp>. After a period of 3 seconds of inactivity ( the autorestart option), a new file with a new timestamp suffix, is created. Press CTRL+C to stop the recording. Now run the recording by running evemu-play:
$ sudo evemu-play /tmp/mouse.<timestamp> ImExPS/2 Generic Explorer Mouse: /dev/input/event7 Hit enter to start replaying
The cursor should move around the screen in a pattern similar to the movement during the recording. Note that the coordinates are not relative to the desktop, instead they are relative to the input device. Movements will start from the current position of the cursor rather than the position the cursor was in during recording.
This example may seem superfluous. Using the keyboard results in more practical use cases. In fact, simulating keystrokes is easier; keyboards don’t have coordinate systems that make mouse emulation so challenging.
Keyboard
On this machine, the keyboard is /dev/input/event2. Remember that all its events can be listed out with evemu-describe /dev/input/event2. This example simulates pressing Super. In GNOME, this brings up the activities overview:
$ sudo -- bash -c 'evemu-event /dev/input/event2 --type EV_KEY --code KEY_LEFTMETA --value 1 --sync; evemu-event /dev/input/event2 --type EV_KEY --code KEY_LEFTMETA --value 0 --sync'
Notice the evemu-event command is repeated twice. The first time sets the value option set to 1. This emulates the key down event. The second time sets the value to 0. This emulates the key up event. Remember to release the key, otherwise it acts like the key is stuck pressing a key! Finally, the sync option guarantees that the keystrokes are executed in sequence.
Macro
Putting all this together, it’s fairly straightforward to create a simple bash script to launch LibreOffice Writer. The script presses the Super key, type “writer”, and press Enter. For the sake of demonstration, the script adds a pause between the keystrokes and event a typo that will be deleted using the backspace. Be sure to replace device with the keyboard device on your own machine.
#!/bin/bash device="/dev/input/event2" function press { evemu-event ${device} --type EV_KEY --code $1 --value 1 --sync evemu-event ${device} --type EV_KEY --code $1 --value 0 --sync sleep 0.2 } press KEY_LEFTMETA sleep 1 press KEY_W press KEY_R press KEY_I press KEY_T # Typo! press KEY_I press KEY_E # Let's fix that press KEY_BACKSPACE press KEY_BACKSPACE press KEY_E press KEY_R sleep 1 press KEY_ENTER
Set the execution bit with chmod and execute it (using sudo): sudo ./script.sh
Regardless of its original purpose, with some imagination, evemu can be put to some clever use: a kiosk or a live presentation, pranks on your roommates, or coupled with some hardware (like an Arduino or a micro:bit) a homemade remote control.
Mik
A nice tool, giving us power and for one more time, no GUI!
We have full blown graphical interfaces on Linux for decades and we still cannot offer a simple GUI for our tools.
It’s a shame, really….
Pat Kelly
Yes, I agree. For all of the “advancements” we keep pushing people back to the command line and scripts in this case. This should be a desktop configuration tool. gnome-control-center already has a panel for the keyboard and another one for the mouse. These panels just need to expand a bit.
Paul W. Frields
This seems hyperbolic to me. The usefulness of the command line has actually caused other GUI operating systems to start and/or expand CLI capabilities (e.g. PowerShell). In this case, clearly evemu is not aimed at average users and it’s not clear to me that a GUI would vastly increase its allure.
Steve
Agree!
Pat Kelly
Certainly the command line is useful. However there are people who do things like CAD, music composition, and other complex GUI based applications that would find the ability to easily assign their extra mouse buttons to useful functions very welcome. Many of these folks have never used the command line, and may not be interested in trying it. The ability to be more productive without becoming involved in what they might see as a bunch of computer details is what they want.
This isn’t about allure like a new game. A GUI based mouse button assignment capability would be a useful tool for such people.
Paul W. Frields
Free software is a gift culture. There are lots of things that would be useful, and every time someone provides one of them, it’s a gift. That’s been a useful thing for me to keep in mind. 😉
Pat Kelly
Yes, I fully understand. I also donate some of my time to Fedora and Gnome, but that doesn’t mean I should stop thinking about user needs and desires. Think of it like this: I’m just helping to provide an awareness of a need to the development community. I know it will depend on some a developer agreeing with it and being willing to donate some of their time to make it real. It may never happen, but it should at least be on a list of things to think about.
As for myself, as a former user of xbindkeys and xdotool, I’m happy with advent of evemu. However, I know people in the local community who I think would appreciate a GUI version.