donniebreve / touchcursor-linux

TouchCursor style keyboard remapping for Linux.
GNU General Public License v2.0
133 stars 28 forks source link

Populate the virtual dev with only valid keybits #39

Closed NeKJ closed 2 years ago

NeKJ commented 2 years ago

This fixes the issue where keyboard stops working under Gnome 41 (with wayland).

The cause is that Gnome gets the virtual dev from logind, but logind has not recognized the virtual dev and it doesn't include it in its available input devices and it returns a ENODEV error:

gnome-shell[5643]: Could not open device /dev/input/event256: GDBus.Error:System.Error.ENODEV: No such device

Probably, the reason is because the virtual device contains keybits that are unusual and unrelated to keyboard keys (e.g., BTN_MOUSE, BTN_JOYSTICK, BTN_DPAD_UP, BTN_GEAR_DOWN, BTN_TOOL_PEN, BTN_TRIGGER_HAPPY and many others) and this can be verified by using devadm info /dev/input/event256 where it includes the ID_INPUT_MOUSE=1 property along with the ID_INPUT_KEYBOARD=1 which is confusing and unexpected.

In order to avoid this miscategorization, this fix sets only the common keyboard keybits to the virtual device (all keybits up to what the kernel defines as KEY_INTERESTING (see linux/input.h) which happens to be KEY_MUTE in kernel 5.10. This is probably the most common and compatible keybit set expected for a keyboard to have. Using this keybit set, the keyboard is successfully recognized as a keyboard and the erroneous ID_INPUT_MOUSE=1 property is gone and is finally working fine under Gnome (wayland). I don't expect this to create any issues because it includes almost all possible keys a keyboard can have.

NeKJ commented 2 years ago

Unfortunately you can't easily "iterate" through preprocessor macros as they turn out to be just values in the runtime. So the only way to make sure that you get what you want is to hard-code each keybit value (macro) one by one. I think that is a bad approach, and that's why I used the "KEY_MIN_INTERESTING" which I assume is meant to signify the highest value that are interesting for keyboards. I may, be wrong though, but the documentation is lacking and I don't have that much experience with it.

However, by looking at the higher valued macros, none seem to be keyboard related or interesting.

NeKJ commented 2 years ago

The best solution would be to replicate one by one the keybits of the actual keyboard. But I didn't find a way to iterate through them. If someone knows how to do it, please do.

Adda0 commented 2 years ago

Yeah, exactly. Therefore, this is somewhat tricky to resolve universally for different kinds of keyboards. And I agree that the KEY_MIN_INTERESTING should suffice. I might try to find more about this particular define (and similar defines) and its supposed purpose to see which would work the best for us. For example, from what you have written about your error message, I suppose your system is OK with key events up to 8 bits (values 0 to 255), therefore the first value to return error is 256. So, out of curiosity, would for example 255 work for your setup as well?

NeKJ commented 2 years ago

I did some trial and error and found that with my system it works up to and including the KEY_ROTATE_LOCK_TOGGLE (hex 0x231 or dec 561). Once I add the next macro define KEY_BUTTONCONFIG (hex 0x240 dec 576), the error ENODEV happens.

I tried up to 572 decimal and it works, at 573 the error starts to happen.

Therefore the conclusions are:

1) The issue is not caused if the virtual device includes BTN_MOUSE, BTNDPAD* and other keybits, unrelated to keyboard keys 2) The issue is not caused if the udevadm info output includes the ID_INPUT_MOUSE=1

So it remains a mystery what are the exact "criteria" that the logind/systemd include or not an input_device regarding the keybits that supports.

We probably could ask the systemd team what are the criteria, or we could ourselves dig into the code of systemd/logind etc and find out exactly what are they. However, I don't want to spend any more time on this. including all keybits up to KEY_ROTATE_LOCK_TOGGLE is way good enough for me.

Adda0 commented 2 years ago

OK, thank you for all the work so far. That is truly an interesting and important piece of information. I find your conclusions sound. However, this complicates things even more. I hope we will be able to find more about this problem. So far, as TouchCursor works for you, even if slightly modified, we will keep the PR opened until we find out more or decide to merge the current changes.

Thinking about it now, the 572 works for you now, but it did not work earlier? Because 572 was there from the start. Therefore, without any changes, the code works for you at the moment?

donniebreve commented 2 years ago

// (I used to have < KEY_MAX here, but that seems to be causing issues?)

At one point I ran into an issue where the virtual device couldn't be created if I included keys up to KEY_MAX. I am also using gnome, but I don't think wayland/xorg make a difference here. 572 came from iterating down from KEY_MAX (767) until things started working again. I am not sure what the underlying cause is.

There was an issue created to output mouse buttons, so I don't like the idea of removing all mouse buttons to get the virtual device to identify as a keyboard only.

This is what I get when I set up to KEY_MAX: key_max_error

This is what I get when I set up to 572: 572_success

If anyone decides to try debugging this, I suggest attaching a second keyboard, as your configured keyboard will be captured but won't produce output.

NeKJ commented 2 years ago

Oh I think that I must have made a mistake here. I was running an older version as it seems where the KEY_MAX were used. So yeah, you are right with the current < 572, it works. So this pull request isn't needed. So I close it. Thanks for your time and effort on this.