keyd: Keyd's virtual pointer emits wrong button codes

This is probably not a keyd issue, but nevertheless I’m recording it here: After having updated my laptop (running Archlinux), the buttons emitted by keyd’s virtual pointer are suddenly 18, 17 and 16 (leftmouse, middlemouse, rightmouse) instead of 1, 2 and 3. I had to fix this via xinput set-button-map. Is there any explanation for this strange behaviour?

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Comments: 15 (9 by maintainers)

Commits related to this issue

Most upvoted comments

I believe BTN_0 is just a generic button event that can be used by any mouse driver

Mice and similar devices use the buttons starting with BTN_LEFT and up. BTN_0 is really a “generic numbered button” and only tablet pads use those (statistically anyway) - you shouldn’t see real-world mice with those buttons. Mind you, there’s this systemd PR which may also fix this issue here I just haven’t had the time to look at that one yet.

@herrsimon Thanks.

I did a bit of digging and was able to narrow it down to this commit in systemd:

https://github.com/systemd/systemd/commit/0855ce6772#diff-e3c18b2fc4f50acbb9f2d66a1daf229fde99a5c8785f17aa6f69e6a9c41ae2c7R261

It seems devices which are capable of emitting BTN_0 (and wheel events) are now treated as ‘tablet pads’. This seems odd to me, since I believe BTN_0 is just a generic button event that can be used by any mouse driver, but I couldn’t find any documentation which corroborates this (perhaps @whot can shed some light).

In any case, the events are currently unused in keyd, so I have removed them in 0fb86d3a9, which should solve the problem.

@rvaiya

If so, my suspicion is that some mouse detection mapping/code has changed in X/libinput

Yes, that’s what I suspect too. Something like “if your pointer device has 17 buttons, it means it’s some new iThingy and has to behave differently”.

libinput debug-events, press keyboard “shortcut” for middle-mouse-click:

— original keyd (with both loops)

-event13  TABLET_PAD_BUTTON       +39.030s	12 pressed (mode 0)
 event13  TABLET_PAD_BUTTON       +39.157s	12 released (mode 0)

— modified keyd (second loop commented out)

 event13  POINTER_BUTTON          +0.000s	BTN_MIDDLE (274) pressed, seat count: 1
 event13  POINTER_BUTTON          +0.128s	BTN_MIDDLE (274) released, seat count: 0

This fixes the issue for me:

diff --git a/src/vkbd/uinput.c b/src/vkbd/uinput.c
index b98e585..d1a9fca 100644
--- a/src/vkbd/uinput.c
+++ b/src/vkbd/uinput.c
@@ -103,7 +103,6 @@ static int create_virtual_keyboard(const char *name)
 
 static int create_virtual_pointer(const char *name)
 {
-       uint16_t code;
        struct uinput_user_dev udev = {0};
 
        int fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK | O_CLOEXEC);
@@ -126,11 +125,11 @@ static int create_virtual_pointer(const char *name)
        ioctl(fd, UI_SET_RELBIT, REL_Y);
        ioctl(fd, UI_SET_RELBIT, REL_Z);
 
-       for (code = BTN_LEFT; code <= BTN_TASK; code++)
-               ioctl(fd, UI_SET_KEYBIT, code);
-
-       for (code = BTN_0; code <= BTN_9; code++)
-               ioctl(fd, UI_SET_KEYBIT, code);
+       ioctl(fd, UI_SET_KEYBIT, BTN_LEFT);
+       ioctl(fd, UI_SET_KEYBIT, BTN_RIGHT);
+       ioctl(fd, UI_SET_KEYBIT, BTN_MIDDLE);
+       ioctl(fd, UI_SET_KEYBIT, BTN_SIDE);
+       ioctl(fd, UI_SET_KEYBIT, BTN_EXTRA);
 
        udev.id.bustype = BUS_USB;
        udev.id.vendor = 0x0FAC;