moses-palmer / pynput

Sends virtual input commands
GNU Lesser General Public License v3.0
1.79k stars 248 forks source link

Monitoring keyboard with uinput backend does not work #408

Closed RillingDev closed 3 years ago

RillingDev commented 3 years ago

Description Using the uinput backend and running the script as root does never fire any keyboard events, both under wayland and XOrg.

Platform and pynput version

To Reproduce 1) Create a script with the example code from https://pynput.readthedocs.io/en/latest/keyboard.html#monitoring-the-keyboard 2) Start the script with root and the environment variables set to PYNPUT_BACKEND_MOUSE=dummy and PYNPUT_BACKEND_KEYBOARD=uinput 3) Input any keys 4) No logging takes place

Notes

moses-palmer commented 3 years ago

Thank you for your report.

I have not been able to reproduce your issue, but according to a post on Stackoverflow, this might be caused by X interfering, although the post talks about a Wacom device. It appears that you are running your application under X. I myself use Wayland, which might be the reason I cannot reproduce.

Have you tried running under Wayland?

RillingDev commented 3 years ago

Thank you for the response!

I did try running it under Wayland (KDE Plasma under Wayland), with the same result (no keyboard events being received).

I did however notice that keys on my mouse such as Key.media_play_pause are received and logged by the example script, unlike my keyboards events. I did not find anything in the pyinput docs regarding selectingwhich device to listen to, so I was assuming that pyinput usually should listen to all devices, is this correct?

moses-palmer commented 3 years ago

I apologise for this late reply.

pynput does not listen to all devices; given the type of listener that is requested (well, only keyboard is supported) it will iterate over all input devices and select the first one with the required capabilities (see here).

This suggests that your mouse is found before your keyboard, and since your mouse is capable of keboard events, it will unfortunately be picked.

A workaround is to provide the---for now undocumented---keyword argument uinput_device_paths. It should be a list of paths to input devices such as ['/dev/input/event0'].

RillingDev commented 3 years ago

No worries, thanks for taking the time to assist me with this issue!

I explicitly specified a list of just the keyboard path like you suggested, and it works - events are detected properly!

Apacelus commented 2 years ago

Hey, so I'm having the same issue. How does this

A workaround is to provide the---for now undocumented---keyword argument uinput_device_paths. It should be a list of paths to input devices such as ['/dev/input/event0'].

translate into a command? Like this?:

sudo env PYNPUT_BACKEND_KEYBOARD=uinput PYNPUT_BACKEND_MOUSE=dummy python3 script.py --uinput_device_paths ['/dev/input/event0']
moses-palmer commented 2 years ago

uinput_device_paths should be specified as a keyword argument to the constructor.