moses-palmer / pynput

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

Pynput with uinput backend in Linux sets incorrect key modifiers #568

Closed andrew-palamar closed 1 year ago

andrew-palamar commented 1 year ago

Description Trivial

keyboard.press('7')
keyboard.release('7')

leads to ALT + 7 press and release

Platform and pynput version Debian 12 Bookworm; pynput version from master branch; pynput version from debian package; Python3.11.2

To Reproduce In linux it is possible to run pynput without sudo. For that user should be in groups tty and input. And one little udev rule for /dev/uinput device.

Add user to group input to gain access to /dev/uinput and to group tty to gain access to dumpkeys

sudo usermod -a -G input $USER
sudo usermod -a -G tty $USER

Add udev rule

echo 'KERNEL=="uinput", MODE="0660", GROUP="input"' | sudo tee /etc/udev/rules.d/99-uinput.rules

Activate it!

sudo udevadm trigger

Automatically load uinput module on boot

echo "uinput" | sudo tee /etc/modules-load.d/uinput.conf

Set envs to use uinput backend

export PYNPUT_BACKEND_KEYBOARD=uinput
export PYNPUT_BACKEND_MOUSE=dummy

Run example code

from pynput.keyboard import Key, Controller

keyboard = Controller()

keyboard.press('7')
keyboard.release('7')

generates Alt_r press, then 7 press, then Alt_r release, then 7 release

dumpkeys --full-table --keys-only output

moses-palmer commented 1 year ago

Thank you for your report.

I have not tested the uinput backend in a while, and given your instructions on how to manage without root, I gave it a try. I can no longer get it to work at all; I'm currently on Ubuntu 23.04, and the last time I ran it was several versions ago.

I would very much appreciate your contributions if your research should find a solution!

andrew-palamar commented 1 year ago

Thank you for reply. This is strange that it does not work at all for you. I have one possible cause in mind. Could you tell if uinput kernel module is loaded:

lsmod | grep uinput

If no module loaded by default you could fix it like this:

echo "uinput" | sudo tee /etc/modules-load.d/uinput.conf

Currently I had to comment out lines 207 - 208 to get rid of extra modifiers. https://github.com/moses-palmer/pynput/blob/12acf84dc0f721d91a957da65311497acb664933/lib/pynput/keyboard/_uinput.py#L207

Will try to reproduce on Ubuntu 23.04 once return from vacation.

andrew-palamar commented 1 year ago

Well I have tested the reciept from my first message and I can not confirm that there are any issue on other Debian 12 installations.

It seems to work pretty good without any sudo. Probably you could add information from my first message to readme. I think it could be valuable for someone.