Skip to content

evdev: add new high performance button invoked scrolling mode

Paul Ausbeck requested to merge ausbeck/libinput:signedscrolling into main

This patch contains a new button invoked scrolling mode optimized for use with 5 button mice. The preferred invokation button is the thumb button, BTN_SIDE in evdev parlance. The initial direction of motion of the mouse following press of the invoking button sets the scroll axis and the sign of the subsequent scroll reports. Once set the axis and sign of the scroll reports can only be changed by releasing and re-pressing the invocation button. This scheme allows for arbitrarily long scroll distances without lifting and replacing the mouse.

Only one axis is active for scrolling at a time. The preferred scroll motion is circular, but any type of mouse motion is acceptable. The distance scrolled is proportional to the manhattan distance moved by the mouse. The dynamic range is expanded non-linearly based on movement velocity such that the +-2^8 input range of mouse motion reports is expanded to a +-2^16 range of scroll reports. The scheme takes maximum advantage of the precision of the mouse, both arbitrarily slow and quite fast scrolling are accommodated. The performance of the mode is such that the scroll thumb is only needed for reference, it need never be "touched".

The mode is optimized for y axis use. The y axis is preferred in that axis determination happens more easily for the y axis than for the x axis. This is accomplished by creating a wider movement cone for y axis selection than for x axis selection. Also, x axis selection can only begin following a delay, now 250ms, from button press, whereas y axis selection is immediate with as little dead/wasted movement as possible. The reason for this asymmetry is personal. I find that when I am reflexively using the mode I may move the mouse more to the left than I am intending, particularly while I am simultaneously pressing the button and starting motion. This behavior can result in x axis selection when y axis is intended. Since I almost never scroll the x axis, I solved the problem by heavily preferring the y axis. The more deliberate criteria for selecting the x axis do not bother me at all. Of course I could have defeated x axis selection entirely, but after significant use of the mode I find the current setup to be almost foolproof for the y axis while still allowing x selection without using up another button.

The mode is optimized for the internet browsing use case, following hyperlinks and scrolling the resulting pages. Care is taken to assure that the user is not confused by overloading the scroll modal button with any other action. Once the new mode is assigned to a button, that button cannot be used for any other purpose. Therefore, those that are used to using mouse buttons 4 and 5 for their historical design use, browsing forward and backward, may not initially take to the new mode. However, patience might be rewarded sooner than one would think. At least for some, the new mode easily becomes intuitive and automatic. And since scrolling is performed far more frequently on modern systems than browsing forward and backward, the increased efficiency of entering the scrolling mode more than pays for the loss of button browsing behavior.

I've not before submitted code to the libinput project. Therefore I have limited the changes to a single source file, evdev.c. Also, I have conditioned the submitted changes so that the new mode is only operational on devices that have the udev environment variable LIBINPUT_SIGNED_SCROLL defined with a value of "1". An example udev rule to add such an environment variable to a Microsoft 5-Button Mouse with IntelliEye follows:

ACTION=="add|change", KERNEL=="event[0-9]*", ENV{ID_VENDOR_ID}=="045e", \
ENV{ID_MODEL_ID}=="0039", ENV{LIBINPUT_SIGNED_SCROLL}="1"

I don't really know how to go about getting this change incorporated into the libinput project. I've attempted to make the change in such a way as to not interfere with any existing functionality. Further, I've made the new functionality available only via the above not easily discoverable incantation. In this way I'm hoping to get the change incorporated into the main project so that others can somewhat easily try out the new mode. Once people are comfortable that the new mode doesn't break anything, the next step would be to make it more publicly usable via changes further libinput changes plus changes to xorg-xf86-input-libinput and/or the similar? wayland input driver.

Signed-off-by: Paul Ausbeck paula@alumni.cse.ucsc.edu

Edited by Peter Hutterer

Merge request reports