Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Send keystrokes to non-active GUI application without occupying the keyboard

As the title explain, i'm trying to use the terminal to send commands as keystrokes to a GUI application that's minimized.

There is a lot of similar questions here on Stack with some great answers, but i'm having, mainly, three problems with the solutions i saw: Most of the solutions need the automated application to be the active one. Or, i can't normally use my keyboard while the script/process is running. Or worse, the solution works only on Windows OS.

I need what this person asked 2 months ago: Send keystrokes to a specific window (in background), but do something else in the meantime But i want it on Linux. I'm using Kubuntu 18.10, if that helps.

xdotool was close, but i couldn't quite get it to send the commands to a specific window or PID. It also uses "my keyboard", so i can't, for example, write an essay/code/browse online while xdotool is running. Pexpect also have this last problem.

AutoHotKey looks like it would work, but it's only for Windows and i'm trying to not use Wine. Same with pywin32.

keyboard (https://github.com/boppreh/keyboard) seems nice, but it can't send a command to a specific application. Same with PyAutoGUI.

I selected the Python tag because most of the solutions i saw use Python, but i'm open to any language.

like image 531
Bluuee Avatar asked May 08 '19 13:05

Bluuee


1 Answers

Use a nested X server to input keystrokes without changing focus or keyboard grab. Proof of concept:

Xephyr -resizeable :13
export DISPLAY=:13
xterm
xdotool type rhabarber

The Xephyr nested X server is started and will listen on local X socket 13 (whereas :0 typically identifies the currently running X server, but when multiple sessions are ran concurrently, it could be higher). Then we set DISPLAY environment variable to :13, so any X application we start will connect to Xephyr; xterm is our target application here. Using xdotool or any other tool we can send keystrokes.

As the target X server is identified through $DISPLAY, applications can be started or input events triggered from elsewhere as well. If needed, you might also run a lightweight window manager within Xephyr, e.g. to 'maximize' the application so that it fills the whole Xephyr window.

like image 76
ypnos Avatar answered Nov 07 '22 18:11

ypnos