Python Program not listening to keystrokes when Active Window is External Program (LInux)

85 views Asked by At

I'm trying to have a Python program listen for keystrokes sent to a program that is launched as a subroutine (Popen).

The problem is that when the correct window is focused nothing happens. No acknowledgement that a key has been pressed. If I click off from the window to something else it works.

This listening is meant to debug a problem of not being able to send keystrokes to the program - pyautogui, pynput, keyboard, even Popen. communicate does not work. The keystrokes sent are ignored by the Python script, even if manually entered myself on the keyboard.

I'm running Retroarch through Lutris. My computer's OS is Ubuntu Linux 22.04, the display manager is Wayland. Below is the code:

from pynput import keyboard
import subprocess, time

def on_press(key):
    print(key)
    return False  # stop listener; remove this if want more keys

lutris = f'LUTRIS_SKIP_INIT=1 lutris/bin/lutris lutris:rungameid/3'
p = subprocess.Popen(lutris, shell=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE, stdin=subprocess.PIPE)
time.sleep(5)
listener = keyboard.Listener(on_press=on_press)
listener.start()  # start to listen on a separate thread
listener.join()  # remove if main thread is polling self.keys

I expect the cited block of code to wait for a keystroke, and exit once one is received.

If I have the Retroarch/Lutris window focused (active) all keystrokes are ignored.

1

There are 1 answers

1
Jens Timmerman On

Are you running on wayland or x? I can reproduce the issue in some way, on wayland I will get mous events when hovering over thunderbird, but not over firefox.

Can you fix it by setting $DISPLAY to the correct environment variable before launching lutris?

The pynput project states some platform limitations:

On Linux, pynput uses X or uinput.

When running under X, the following must be true:

  • An X server must be running.
  • The environment variable $DISPLAY must be set.

When running under uinput, the following must be true:

  • You must run your script as root, to that is has the required permissions for uinput.

The latter requirement for X means that running pynput over SSH generally will not work. To work around that, make sure to set $DISPLAY:

$ DISPLAY=:0 python -c 'import pynput'

Please note that the value DISPLAY=:0 is just an example. To find the actual value, please launch a terminal application from your desktop environment and issue the command echo $DISPLAY.

When running under Wayland, the X server emulator Xwayland will usually run, providing limited functionality. Notably, you will only receive input events from applications running under this emulator.