19

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.

Bluuee
  • 193
  • 1
  • 7
  • How do you plan on getting the keystrokes to send? Have you thought about creating your own process that runs and, when requested, makes calls to `xdotool key --window windowId `? This way, xdotool doesn't hold up your keyboard because it's only running when you want to send a keystroke. – Tyler Marshall May 15 '19 at 20:54
  • 1
    `xdotool key --window windowId ` doesn't solve the problem of this question, the person who asked want to write an essay/code/browse online while the script runs, and xdotool need to focus on the window that will receive the keystroke. On windows there is the "user32.dll" which does that, but this person is searching something for Linux. – Lucas Araújo May 16 '19 at 01:02
  • Maybe try: https://github.com/tuomasjjrasanen/python-uinput . From a quick glance, this doesn't do what you want it to, *however* the frame work for sending keystrokes in linux is all there, so it is certainly a place to start – Recessive May 16 '19 at 05:23
  • 2
    If the target application can be run in a separate X session, then it could be always in focus, and xdotool would work if ran from the same X session – Tim May 16 '19 at 23:11
  • 1
    @Tim Can u elaborate how that would work, and how to do that? – Lucas Araújo May 17 '19 at 12:05
  • Run the application and the script that sends keystrokes inside a Virtual Machine. Detach from said Virtual Machine. –  May 17 '19 at 12:38
  • 1
    [Autohotkey Equivalent?](https://unix.stackexchange.com/q/165124) – Smart Manoj May 20 '19 at 11:51
  • You don't need a virtual machine to run an X server within an X window, you can use Xephyr for that. – ypnos May 21 '19 at 14:08

1 Answers1

5

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.

ypnos
  • 50,202
  • 14
  • 95
  • 141