moses-palmer / pynput

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

`keyboard.type` with `keyboard.GlobalHotKeys` is typing some other chars and creates side effects #472

Open jd-solanki opened 2 years ago

jd-solanki commented 2 years ago

Description Hi,

I have a simple script which types back what I feed to it. Problem is if I tell it to print string 59y#d/8^Pw/ewh%& it print 59y#d/8^Pw/5. Moreover, I tell to print 59y#d/8^Pw/ it still prints the same 59y#d/8^Pw/5 🤯

Platform and pynput version

  System:
    OS: Linux 5.15 Ubuntu 22.04 LTS 22.04 LTS (Jammy Jellyfish)
    CPU: (6) x64 Intel(R) Core(TM) i5-9400F CPU @ 2.90GHz
    Memory: 956.66 MB / 7.71 GB
    Container: Yes
    Shell: 0.12.1 - /home/jd/.xonsh/.venv/bin/xonsh
name         : pynput
version      : 1.7.6
description  : Monitor and control user input devices

dependencies
 - evdev >=1.3
 - pyobjc-framework-ApplicationServices >=8.0
 - pyobjc-framework-Quartz >=8.0
 - python-xlib >=0.17
 - six *

To Reproduce

#! /home/jd/Rachana/.venv/bin/python3
from pynput import keyboard

class Writer:
    def __init__(self, text: str):
        self.text = text
        self.keyboard = keyboard.Controller()

        with keyboard.GlobalHotKeys(
            {"<ctrl>+/": self.on_press_right}, suppress=True
        ) as h:
            self.listener = h
            h.join()

    def on_press_right(self):
        # self.keyboard.type(self.text)
        # self.keyboard.type("59y#d/8^Pw/ewh%&")
        self.keyboard.type("59y#d/8^Pw/")
        self.listener.stop()

Writer("59y#d/8^Pw/ewh%&")

Side Effects self.listener.stop() is not stopping the listener.

I also tried printing the characters one by one but still the same issue:

for char in "59y#d/8^Pw/":
    # Also tried time.sleep but no lock 😢 
    self.keyboard.type(char)
moses-palmer commented 2 years ago

Thank you for your report.

This is probably caused by the fact that although Controller.type appears to be a simple procedure outputting characters, it has to do a lot behind the scenes, some of which modifies system global state

When I run your script on my computer (Ubuntu 22.04, Wayland session, testing in Chrome running under XWayland) it does print the expected string, so this behaviour seems to be system dependent. Perhaps a keyboard layout issue, or an XWayland / XOrg proper issue?

NikZapp commented 1 year ago

Same issue appears even when using keyboard.type() or keyboard.press() The issue gets worse over time as characters get replaced more and more. Before only one key was wrong, now its two. Same version, running debian 11