Can't figure out setting keycodes with udev


I’ve got a new laptop - MSI Delta 15 - and I’m trying to get all the keys on the keyboard to work so I can bind things to them. A handful of keys generate no keycodes (as shown with showkey -k). I got their scancodes from dmesg logging. I can bind them properly with setkeycodes, but it seems like the “proper” way to do this permanently is with udev. But when I set up /etc/udev/hwdb.d/60-keyboard.hwdb.db with my rules, I can’t get the codes to work.

I’ve done system-hwdb update, and udevadm trigger, and I’ve even rebooted. My first guess is that my pattern isn’t matching. BUT, if I run udevadm info keyboard-device, it lists out the rules that I think I added.

Where am I going wrong?

Here’s my /etc config file:


And the output of udevadm info:

$ sudo udevadm info /dev/input/by-path/platform-i8042-serio-0-event-kbd
P: /devices/platform/i8042/serio0/input/input3/event3
M: event3
R: 3
U: input
D: c 13:67
N: input/event3
L: 0
S: input/by-path/platform-i8042-serio-0-event-kbd
E: DEVPATH=/devices/platform/i8042/serio0/input/input3/event3
E: DEVNAME=/dev/input/event3
E: KEYBOARD_KEY_e00e=kbdillumtoggle
E: KEYBOARD_KEY_e011=lockscreen
E: KEYBOARD_KEY_e071=micmute
E: KEYBOARD_KEY_e072=rotate_display
E: ID_BUS=i8042
E: ID_SERIAL=noserial
E: ID_PATH=platform-i8042-serio-0
E: ID_PATH_TAG=platform-i8042-serio-0
E: LIBINPUT_DEVICE_GROUP=11/1/1:isa0060/serio0
E: DEVLINKS=/dev/input/by-path/platform-i8042-serio-0-event-kbd
E: TAGS=:power-switch:
E: CURRENT_TAGS=:power-switch:

So clearly the code I wrote is loading, but it isn’t turning into actual scancode to keycode translations in the way that setkeycodes does. Where am I going wrong?

It’s worth noting one odd (to me) thing. When I look at devices with evemu-describe, it lists two different devices that seem to be keyboard-related:

  • /dev/input/event3:  AT Translated Set 2 keyboard
  • /dev/input/event8:  MSI WMI hotkeys

The keyboard event number is always three, the hotkeys number changes with reboots. Is this all normal? All the keys I have that don’t work are “hotkeys”.


As I know udev rules is a bad way… does it even work properly? Look here:

showkey is IMO horrible and doesn’t detect all keys. I’d use evtest (see the link below), if the keys don’t show in the keyboard event file then try the other.

That should be /etc/udev/hwdb.d/60-keyboard.hwdb, though I don’t know if it matters.

Try commenting one out.

Better yet try with evdev:atkbd:dmi:* which will match any AT keyboard. You can always refine it later, but you’re unlikely to have any more AT keyboards, if you plug one in it’ll be USB.

Since it’s an internal keyboard you should be able to use the systemd service here and forget about udev.


Why is it a bad way?

The rules can be awkward and you need exactly 1 space for indentation, but AFAIK it does work. It’s below xorg and the console so it works for both, and is applied every time the device is detected.

1 Like

I guess it is just a lack of knowledge since I rarely play with keycodes. However seems you are well versed here. Go ahead :slight_smile:

1 Like

I wish. :slight_smile:

I’ve just dabbled a couple of times, still lots of holes in my knowledge. Making a prototype USB keyboard helped, it forced me to read a lot. Unfortunately the documentation is a bit sparse at times, and often out of date.

1 Like

showkeys was working as advertised. Relying on dmesg output for scancodes turned out to be the problem evtest reported correct scancodes. The dmesg output was sort of correct. Or I should say related to reality: It seems that where dmesg was reporting e0NN, the real scancode reported by evtest was just NN+0x80.

Just a typo in this post; I had it right in real life.

The first line I had was matching fine.

I knew I could make that work, since “setkeycodes” worked (interesting that the values in dmesg worked in setkeycodes command but not in udev). But my interest, and the reason I considered udev the “right” way is so that I can contribute code to systemd hwdb such that other later MSI Delta 15 linux users (if any) will end up with a more correct keyboard configuration with no tinkering required.

Now I just have to figure out how to submit changes like that

Random note: I had lockscreen above but the proper linux name for that key should be screenlock.

I was also happy to see that (as I suspected) getting the proper linux codes in caused the Xorg events to show up properly, even though the translation between linux and Xorg keycodes remains a mystery, poorly described in all documentation I’ve seen.

Some of these keys are being used in ways that aren’t useful. e.g. the keyboard backlight for this keyboard does not respond properly whatever Manjaro is trying to do to toggle the keyboard backlight. Luckilly I found some code someone wrote to talk to the keyboard RGB. So I can come up with a janky solution now to use the keyboard illum key (previously not working) to run a program to do stuff. Unfortunately it isn’t a proper solution that wlll automatically benefit other users of the same laptop.

Thanks for the help!

1 Like

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.