UltimateHackingKeyboard / firmware

Ultimate Hacking Keyboard firmware
Other
410 stars 63 forks source link

High-resolution scrolling #741

Open rightaditya opened 5 months ago

rightaditya commented 5 months ago

This is a feature request for high-resolution scrolling via the trackball module.

Because the trackball module is (relatively) high-DPI, it should theoretically be possible for it to provide high-resolution scroll events. Changing scrollSpeedDivisor from the default of 8 to 1 sends 8 times the events, and of course the default interpretation by the OS is to scroll 8 times as much for a given physical distance.

Scroll speed can't always be adjusted sufficiently (if it can at all) to account for this; plus simply reducing scroll speed in the OS (when it's an option, that is) might not truly indicate to the OS that a fine-grained level of scrolling is possible; I'm not 100% sure on this but it even at lower scroll speeds it might still default to scrolling in larger discrete steps (e.g. never going lower than one line, even if a view can support scrolling fractions of lines).

AFAICT the "right" way to do this is to use the resolution multiplier control in the USB HID protocol (see, e.g., https://usb.org/sites/default/files/hut1_13.pdf). This functionality was developed in part by Microsoft, so it's how Windows does it, and AIUI the Linux support for high-resolution scrolling follows it as well, including some software-side conventions adopted in Windows (specifically, the 120 value assigned to a "standard" scroll detent). FWICT if a resolution multiplier is specified, the Linux kernel will just use that as a divisor for the scroll "amount", and clients that support the corresponding libinput events will handle the scroll accordingly (and there is a legacy event for those that don't).

(The only way I could find to change this value other than through the kernel—which does it via reading the resolution multiplier from the device—is using libinput-config, but that works globally and so affects all scroll devices.)

rightaditya commented 5 months ago

Just adding that I'd be happy to work on this myself, but would need some guidance as it's been ~15 years since I've done any kind of programming at this low a level (and never with USB).

mondalaci commented 5 months ago

Thanks for letting me know about the resolution multiplier control of USB! I didn't know about it. Assuming it works cross-OS, we should pick a fine-grained value that allows per-pixel scrolling and make the UHK firmware multiple scroll values accordingly.

@kareltucek Can you implement this or do we need Benedek for the USB part?

kareltucek commented 5 months ago

I fear we will need Benedek for this, as this is likely to violate the boot protocol compatibility.

mondalaci commented 5 months ago

I'm summoning @benedekkupper for a short comment about this issue. This is not a priority.

rightaditya commented 5 months ago

In case it's of use or interest: Peter Hutterer, who's been involved in the implementation of high-resolution scrolling throughout the Linux stack, has written a couple blog posts about how things work ^1.

benedekkupper commented 5 months ago

The boot protocol mode of the mouse is s farce, we should actually either disable the mouse boot support, or implement the report layout changing. Since until now noone noticed that it's broken, it's a safe bet to disable it.

Regarding the implementation it seems to me that we need to add an HID feature report to the mouse interface, with this resolution multiplier usage as the single element. The questions to clarify is:

  1. what is the supported range of this value
  2. what should be the default value
  3. how this value is used in the mouse input report calculation
  4. whether this value needs to be stored in non-volatile memory on the device, or the OS takes care of it
mondalaci commented 5 months ago

@benedekkupper I don't have solid answers, but regarding 1 to 3, can we have sensible defaults? Then we could tweak them. I don't understand question 4, so please elaborate.