bushrat
Posts: 65
Joined: Mon Mar 05, 2012 8:35 pm

uinput Key Repeat

Sun May 26, 2013 6:24 am

Ok, I'll get straight to the point, uinput doesn't do key repeating, and it's very annoying.

Basically, I've been using 2 bits of software, pikeyd (https://github.com/mmoller2k/pikeyd) and python-uinput (https://github.com/tuomasjjrasanen/python-uinput) both of which are completely unrelated, except for 3 things, both are used for simulating key press events, use uinput and neither can repeat keys.

As far as I and MMoller2k can tell, our separate bits of software, 1 in python and the other in C cannot repeat keys, even thou nothing says they shouldn't.

And I guess what I'm asking is if there is a bug in uinput or both our bits of software. I can't vouch for my C friend, but my python script is so simple I cant see what could go wrong.

Code: Select all

import uinput
import time

fake_gpio = 0 #No Signal

events = (uinput.KEY_X, uinput.KEY_H, uinput.KEY_E, uinput.KEY_L, uinput.KEY_O)
device = uinput.Device(events)

def press(key):
        device.emit(key, 1)
        time.sleep(0.08)
        device.emit(key, 0)
        return 0

fake_gpio = 1 #Signal
cycle = 0
while fake_gpio:
        if cycle == 0:
                press(uinput.KEY_X)
                time.sleep(0.3)
        elif cycle == 30:
                fake_gpio = 0 #No Signal
                cycle = 0
                break
        else:
                press(uinput.KEY_X)
        cycle += 1

press(uinput.KEY_H)
press(uinput.KEY_E)
press(uinput.KEY_L)
press(uinput.KEY_L)
press(uinput.KEY_O)
For anyone wanting to test this for themselves, download python-uinput and run this code:

Code: Select all

import uinput
import time

events = (uinput.KEY_X, uinput.KEY_H, uinput.KEY_E, uinput.KEY_L, uinput.KEY_O)
device = uinput.Device(events)

device.emit(uinput.KEY_X, 1)
time.sleep(2)
device.emit(uinput.KEY_X, 0)
This should hold down the 'X' key for 2 seconds, but merely presses it once.

Can anyone please help, this issue has been driving me loopy for the last week or so.

Insane Laughter of a psychopath > :lol:

bushrat
Posts: 65
Joined: Mon Mar 05, 2012 8:35 pm

Re: uinput Key Repeat

Mon May 27, 2013 7:32 am

Does anyone have any idea about what's going on? :?:

bushrat
Posts: 65
Joined: Mon Mar 05, 2012 8:35 pm

Re: uinput Key Repeat

Wed May 29, 2013 7:56 am

I believe the term is "bump"

Blagus
Posts: 1
Joined: Sat Nov 12, 2016 3:38 pm

Re: uinput Key Repeat

Sat Nov 12, 2016 3:53 pm

I apologize for posting in this ancient thread, but since it's the first result when googling this problem, I must post a solution here.

I had the same problem, and after reading uinput's documentation, I found that this is the key event initialization issue.
Basically, this document tells that EV_REP must be set if we want the repeat property:
After opening the device the program should set the input device parameters(keyboard event, mouse event, etc) using the ioctl() function. The following example is given for keyboard parameters:

example:
ioctl (out_fd, UI_SET_EVBIT, EV_KEY);
ioctl (out_fd, UI_SET_EVBIT, EV_REP);

The EV_KEY and EV_REP informs the uinput driver as the event is keyboard event and the key value contains the key repetation property.
As you might have guessed, python-uinput, or, more precisely libsuinput, does not set this. So I made a small patch for python-uinput package which will enable the repeat property if the defined event is EV_KEY:

Code: Select all

diff --git a/libsuinput/src/suinput.c b/libsuinput/src/suinput.c
index 8d5fb71..4fa643a 100644
--- a/libsuinput/src/suinput.c
+++ b/libsuinput/src/suinput.c
@@ -179,6 +179,10 @@ int suinput_enable_event(int uinput_fd, uint16_t ev_type, uint16_t ev_code)
                 return -1;
         }

+        if (ev_type == EV_KEY) {
+                ioctl(uinput_fd, UI_SET_EVBIT, EV_REP);
+        }
+
         switch (ev_type) {
         case EV_KEY:
                 io = UI_SET_KEYBIT;
This will enable key repeat on our events, and the behavior is exactly what you are used to: a small delay between first and second key press, followed by the constant repetition.

Return to “Raspberry Pi OS”