this post was submitted on 25 Mar 2025
9 points (100.0% liked)

Python

6981 readers
7 users here now

Welcome to the Python community on the programming.dev Lemmy instance!

πŸ“… Events

PastNovember 2023

October 2023

July 2023

August 2023

September 2023

🐍 Python project:
πŸ’“ Python Community:
✨ Python Ecosystem:
🌌 Fediverse
Communities
Projects
Feeds

founded 2 years ago
MODERATORS
 

I have a rather large Python script that I use as basically a replacement for autohotkey. It uses pynput for keyboard and mouse control - and at least on Windows, it works exactly how I expect.

I recently started dual-booting with Linux and have been trying to get the script to work here as well. It does work but with mixed results - in particular, I found that pynput has bizarrely wrong output for special characters, in a way that's both consistent and inconsistent.

The simplest possible case I found that reproduces the error is this script:

import time
from pynput import keyboard

# Sleep statement is just to give time to move the mouse cursor to a text input field
time.sleep(2)

my_kb = keyboard.Controller()

text = 'πŸ†' # Eggplant emoji
my_kb.type(text)

time.sleep(1)

text = 'π•₯𝕖𝕀π•₯' # blackboard bold test
my_kb.type(text)

time.sleep(1)

text = '𝐭𝐞𝐬𝐭' # bold test
my_kb.type(text)

When I run that script right now, it produces the output "πŸ†π•₯π•₯𝕀π•₯𝐭𝐭𝐬𝐭". And if I run it again, it'll produce the same output. And if I change the eggplant emoji to something else, like the regular character 'A', it will still produce the same output (specifically "Aπ•₯π•₯𝕀π•₯𝐭𝐭𝐬𝐭"). But... If I log out and log back in, then the output changes to something else that's still wrong, but differently. For example, when I changed the eggplant to a regular 'A', then relogged, the output became "Aπ•₯𝕖𝕖π•₯𝐭𝐞𝐞𝐭". And then that wrong output will keep being the same wrong output until I log out and back in again. If the test strings don't change, then the incorrect outputs don't change on relog - but if they do, then they do.

In the larger script, errors seemed to chain together somehow - like if I produced an eggplant emoji, then tried to write blackboard bold test, I would get "πŸ†π•–π•€πŸ†". This is despite verifying just before running the pynput.keyboard.Controller.type function that what it was about to type was correct. The issue also happens if I type it character-by-character with press and release functions.

I am very new to Linux. I'm on Linux Mint. I'm running this in a python3 venv that just has pynput and two other external libraries installed. ChatGPT thinks the issue might be related to X11. The issue does not occur at all on Windows, using the exact same code. On Linux there seems to be no issues with typing regular text, just special characters.

you are viewing a single comment's thread
view the rest of the comments
[–] [email protected] 4 points 1 week ago (5 children)

v1.8.1 was release on 2025-03-17

So pynput is being maintained. BUT there are current 155 open issues and 23 PRs. This means nothing besides this is a popular package.

v1.8.1 Changes

  • Remove incorrectly merged line for the Xorg backend. Thanks to sphh!
  • Let events know about the new injected parameter. Thanks to phpjunkie420!

Mentioned that a PR dealt with a Xorg backend issue. Don't know if this addresses your particular issue.

What pynput version do you have in your venv?

Run this command please to get the package version

python -m pip list | grep pynput

Can understand your issue report would be buried in all the other issues. So help there might not come within a timely manner.

The next step would be to create a pytest file to be able to repeat the tests, rather than run them each time manually. Obviously logging in and out is not possible. But it's probably also completely unnecessary.

I use Xorg and Linux. Competent enough with pytest (author of pytest-logging-strict).

Before roll up my sleeves want you to confirm v1.8.1 still has this issue.

[–] [email protected] 2 points 1 week ago (4 children)

Hey! Sorry for the very late reply. I've been checking the thread regularly and I swear just a few hours ago (when I made the cross-posts) it was still at 0 replies. I'm gonna blame federation issues.

The command you provided does indicate I'm on pynput 1.8.1, so I can confirm v1.8.1 has the issue.

[–] [email protected] 2 points 1 week ago (3 children)

Took two days to think about your original post. Was thinking, hmmm this package and trouble you are having are both fresh and interesting.

Remote controlling both the mouse and keyboard seems worthy to spend time trying it out.

[–] [email protected] 1 points 1 week ago (1 children)

I agree and appreciate it. I've been trying to figure it out myself but feel a bit out of my element.

What I've found is that in pynput's keyboard's _xorg.py file, the Controller class's self._keyboard_mapping seems to map some different keycodes to the same value, and that seems to correlate exactly with the errors I'm seeing. I haven't figured out why yet. I got to thinking it had something to do with the register function in the _resolve_borrowing function but I forget why and I'm too tired to continue for now. I'll continue tomorrow though.

[–] [email protected] 1 points 1 week ago

_util/xorg_keysyms.py

Contains mapping of keysym to unicode str

type this into the terminal, it'll open up a small window. With the window in focus, type.

xev -event keyboard

type 1

From xev

keysym 0x31, 1

Corresponding entry in pynput._util.xorg_keysyms.SYMBOLS

'1': (0x0031, u'\u0031'),

so the hex is minimum four places. So 0031 instead of 0x31

From xev

keysym 0xac9, trademark

Corresponding entry in pynput._util.xorg_keysyms.SYMBOLS

'trademark': (0x0ac9, u'\u2122'),

From xev

type in nuke radiation emoji

keysym 0x1002622, U2622 bytes: (e2 98 a2) "☒"

So three bytes instead of one or two bytes

From xev

(keysym 0x7c, bar)
1 bytes: (7c) "|"

Corresponding entry in pynput._util.xorg_keysyms.SYMBOLS

'bar': (0x007c, u'\u007C'),

load more comments (1 replies)
load more comments (1 replies)
load more comments (1 replies)