4

How can I get my keyboard repeat rate to apply to a hotplugged USB keyboard?

I made a udev rule to set the keyboard repeat delay and rate, /etc/udev/rules.d/99-usb-keyboard.rules with the following contents:

ACTION=="add", SUBSYSTEM=="usb", RUN+="/home/michael/bin/keyboard_settings.sh"

keyboard_settings.sh:

#!/bin/bash

# Set keyboard repeat delay and rate
xset -display :0.0 r rate 250 40

udev seems to see this, using the command udevadm test /sys/bus/usb/devices/3-2\:1.0/

read rules file: /etc/udev/rules.d/99-usb-keyboard.rules
rules contain 393216 bytes tokens (32768 * 12 bytes), 37438 bytes strings
31709 strings (264322 bytes), 28154 de-duplicated (230440 bytes), 3556 trie nodes used
IMPORT builtin 'hwdb' /lib/udev/rules.d/50-udev-default.rules:11
RUN '/home/myuser/bin/keyboard_settings.sh' /etc/udev/rules.d/99-usb-keyboard.rules:1
unable to create temporary db file '/run/udev/data/+usb:3-2:1.0.tmp': Permission denied
ACTION=add
DEVPATH=/devices/pci0000:00/0000:00:14.0/usb3/3-2/3-2:1.0
DEVTYPE=usb_interface
DRIVER=usbhid
ID_VENDOR_FROM_DATABASE=Hewlett-Packard
INTERFACE=3/1/1
MODALIAS=usb:v03F0p0325d0102dc00dsc00dp00ic03isc01ip01in00
PRODUCT=3f0/325/102
SUBSYSTEM=usb
TYPE=0/0/0
USEC_INITIALIZED=4145997461
run: '/home/myuser/bin/keyboard_settings.sh'

And yet, this doesn't actually change the repeat rate. The laptop keyboard has the correct settings, but the external USB keyboard does not. Is Xorg overwriting the settings after the udev rule is applied? How can I find out?

I get this in the Xorg.0.log, indicating that X11 is fussing with things, but none of the rules in /usr/share/X11/xorg.conf.d/ do anything to keyboards.

[164570.705] (II) config/udev: Adding input device Lite-On Technology Corp. HP Basic USB Keyboard (/dev/input/event6)
[164570.705] (**) Lite-On Technology Corp. HP Basic USB Keyboard: Applying InputClass "evdev keyboard catchall"
[164570.705] (**) Lite-On Technology Corp. HP Basic USB Keyboard: Applying InputClass "Keyboard Defaults"
[164570.705] (II) Using input driver 'evdev' for 'Lite-On Technology Corp. HP Basic USB Keyboard'
[164570.705] (**) Lite-On Technology Corp. HP Basic USB Keyboard: always reports core events
[164570.705] (**) evdev: Lite-On Technology Corp. HP Basic USB Keyboard: Device: "/dev/input/event6"
[164570.705] (--) evdev: Lite-On Technology Corp. HP Basic USB Keyboard: Vendor 0x3f0 Product 0x325
[164570.705] (--) evdev: Lite-On Technology Corp. HP Basic USB Keyboard: Found keys
[164570.705] (II) evdev: Lite-On Technology Corp. HP Basic USB Keyboard: Configuring as keyboard
[164570.705] (**) Option "config_info" "udev:/sys/devices/pci0000:00/0000:00:14.0/usb3/3-2/3-2:1.0/input/input34/event6"
[164570.705] (II) XINPUT: Adding extended input device "Lite-On Technology Corp. HP Basic USB Keyboard" (type: KEYBOARD, id 11)
[164570.705] (**) Option "xkb_rules" "evdev"
[164570.705] (**) Option "xkb_model" "pc105"
[164570.705] (**) Option "xkb_layout" "us"
1

2 Answers 2

1

So finally after digging around the net for one year I got it working today.

Source: https://newbedev.com/udev-rule-to-auto-load-keyboard-layout-when-usb-keyboard-plugged-in

xset is an X11 program. So you'll have to hardcode the DISPLAY and XAUTHORITY env variables.

Basically the workaround is to run the script in background with a short delay. So udev can activate the keyboard before you xset the keyboard. In the solution mentioned above the udev calls a script which in turn calls a second script in the background which then calls xset. In fact this can be shortened to one script.

/home/michael/bin/keyboard_settings.sh

#!/usr/bin/env bash

(
    sleep 1

    DISPLAY=":0.0"
    XAUTHORITY="/home/your-profile/.Xauthority"
    export DISPLAY XAUTHORITY

    xset r rate 250 50
) &
0
0

Do NOT use udev for that.


NOTICE: the following only works in recent versions of Xorg, see this change from 2020.

With an older Xorg, you can use the -ardelay and -arinterval command line options; if you're using xdm, you can add those options to /etc/X11/xdm/Xservers.

If you're using gdm3 (which is using a hardwired Xorg command line) I can only feel for you.


Just use a xorg.conf snippet and set the repeat rate there.

% cat /etc/X11/xorg.conf.d/99-keyboard.conf
Section "InputClass"
        Identifier "system-keyboard"
        MatchIsKeyboard "on"
        # Option "XkbLayout"  set in /etc/default/keyboard
        # Option "XkbOptions" ditto
        Option "AutoRepeat" "250 50"
EndSection
3
  • I know about the kind of the udev workaround. I know it's dirty. But basically: why one does not have to use udev?
    – codekandis
    Sep 21, 2021 at 5:44
  • Haven't you answered yourself that question? Because a) it's racy -- you have to sleep 1 second (hoping that udevd won't kill your script until then, as it should), b) it's brittle -- you have to hardwire the user and the display, and assume that only a single xserver is running and c) it's dirty -- you're running as root code that has no business running as root. Sep 21, 2021 at 16:14
  • Practically everything is better than using a udev rule for that -- including nasty kludges like tail -f /var/log/Xorg.0 | awk /XINPUT/ or replacing /usr/bin/Xorg with a wrapper that calls the Xserver with those -ardelay and -arinterval options. I'll write a more complete Q&A about all this when I got time.\ Sep 21, 2021 at 16:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.