High-res scrolling support for trackball#794
High-res scrolling support for trackball#794mondalaci merged 6 commits intoUltimateHackingKeyboard:masterfrom
Conversation
|
Thank you for your contribution! |
1 similar comment
|
Thank you for your contribution! |
|
I've added support for the high-res mode to be selectively disabled per-axis via a USB SetReport feature request, which enables support for this kind of setting via registry values in Windows. It doesn't play too well with axis locking, though. I can't think of a use case for having high-res scrolling enabled on one axis and not another, and there's really just one physical scroll device here, so IMO it'd make more sense to just have a single multiplier that applies to both wheels. This may require changing the structure of the USB descriptor. |
|
@mondalaci I figured there was no need to sign the CLA until this PR is considered ready for merging, but I can do so sooner if you need it for the CI (or just to silence the bot, lol). |
|
@rightaditya Yes, it'd make sense to sign the CLA now. A single multiplier for both axes is sufficient. |
|
Just made the change and tested it. Now on Windows, disabling high-res scrolling for a single axis via the relevant registry key only disables the OS's handling for high-res values on that axis, so scrolling on that axis becomes very sensitive (but moves in larger chunks). Disabling both axes works as expected. I can't figure who would possibly be fiddling with the registry keys to disable high-res scrolling on a single axis only, so this seems a reasonable compromise. (The two-multiplier case worked better for that case, though was still a bit janky and unnecessarily complicated the axis-locking code.) This behaviour suggests that the firmware is handling the SetReport and GetReport requests as it should, but unfortunately I can't be 100% sure without inspecting USB packet capture logs and I can't get these on Windows since I only have it installed on a USB drive and packet capture with USBPcap doesn't work when this is the case. Otherwise I think that the minimal stuff needed for this is all done. I could take a look at USB packet capture logs for macOS if desired to see if perhaps the OS is trying to activate high-res mode in some other way than expected. |
|
@rightaditya Thanks for the excellent work! We'll test this thoroughly, and @kareltucek may fine-tune the firmware in this respect. We'll follow up. |
* High-resolution mode is only enabled if a request is received to set
the feature report. This seems to be how Linux instructs a device to
use high-resolution mode (Windows needs testing still).
* Currently the actual values in the SetReport request are ignored.
This *should* be fine since this request should only be sent if the
host supports resolution multipliers. But Windows does allow
disabling high-resolution scrolling for individual axes, so the
values in the request should actually get processed. (Linux doesn't
have this functionality and, AFAICT, uses this request during
initial setup.)
* Linux's implementation is (I think) somewhat broken, so if the
values are processed, there should be an exception for the Linux
case.
* The resolution multiplier is set to 120, the maximum sensible value
(thus providing the most overall flexibility). Summands to the wheel
values are scaled by 120 to compensate. This is so that scroll events
induce the same amount of scrolling in the OS regardless of whether
high-resolution mode is used.
* Without any configuration changes this is already noticeably
smoother, but the minimum scroll value with the default
configuration for the trackball (base speed 0.5, speed 0.5, and
acceleration 1, and scroll speed divisor 8) is 7. Setting base speed
to 0.2, speed to 0.8, acceleration to 0.9, and scroll speed divisor
to 12 is reasonably similar in terms of mouse and scroll speed feel
but scrolling is smoother still (especially noticeable when
scrolling slowly). With these settings, the minimum scroll value
sent is 2. Getting it down to 1 is the smoothest possible, but it'd
be harder to get a similar mouse and scroll speed feel. Separate
speed curves for scroll vs. cursor would be useful for this (but
probably more trouble than they're worth).
Allow high-res scrolling to be selectively enabled for the two axes, as specified by the values given in the SetReport feature request. AFAIK only Windows supports this (via registry keys[^1]). Beware that disabling high-res scrolling for only one axis doesn't play too well with axis locking. I've adjusted as best as I could, but there's ultimately no getting around it: a movement with equal physical x and y displacement will have much larger values on the scaled axis. To try to adjust for this, there could be some kind of extra buffer that must be filled before scroll values are sent, but this would induce a delay before movement is seen on the high-res axis, disrupting the smooth, 1:1 (or nearly 1:1) feel provided by the higher resolution, defeating its purpose (to an extent). I think the right way to deal with this would be to change the USB descriptor for the mouse so that there's only one resolution multiplier. Because of the way resolution multipliers are scoped, I think the logical groups for the wheels would have to be removed so that a single resolution multiplier in the descriptor can apply to both wheels. At least, this is the case from my recollection of the USB HID spec. It's possible that OS drivers would take a global resolution multiplier to apply to any contained logical collections that don't themselves have a resolution multiplier specified. [^1]: [Enhanced Wheel Support in Windows](https://learn.microsoft.com/en-us/previous-versions/windows/hardware/design/dn613912(v=vs.85))
Merge the two wheels into a single logical collection in the HID mouse report descriptor so that a single resolution multiplier is used for both wheel axes together. On Windows, disabling high-resolution scrolling for a single axis via the relevant registry key will now only disable the OS's high-resolution handling, while the mouse will continue to send high-res values. This means the disabled axis will scroll very quickly but in larger chunks. Disabling high-res scrolling for both axes in the registry works as expected. It's unlikely anyone will ever want the single-axis case. For reference, handling it "properly" would require going back to separate resolution multipliers per axis (previous commit) or else adding support for different scroll speed divisors per axis.
Plus a mild refactor. On my Linux setup, this makes scrolling with the mouse scroll keys noticeably smoother in high-res scroll mode than in regular (low-res) scroll mode.
e950e20 to
f1f2038
Compare
This PR is for HID-compliant high-resolution scrolling support for the trackball. Closes #741. See this comment for notes on testing this on Linux.
TODO
SetReportrequest (will require separating X and Y high-res modes)SetReportrequests