jfedor2 / hid-remapper

USB input remapping dongle
Other
1.11k stars 135 forks source link

Scroll Acceleration / Momentum #24

Open ciphan opened 2 years ago

ciphan commented 2 years ago

I really want to use a trackball in each hand - one dedicated to mousing and one dedicated to scrolling. I want the ball movement from the "scrolling hand" to act like scrolling on a touch screen with precise control for small and slow movements and with the ability to "flick" the ball and let the physical momentum transfer to momentum in the on screen scroll event. KensingtonWorks's TrackScroll in combination with a very tweaked SmoothScroll configuration gets really close but TrackScroll emulates a regular scroll wheel and so lacks the precise scrolling and I really like the idea of a hardware solution anyway.

With this project, although I'm sure I read that you have implemented precise scrolling it does not seem to act that way for me - it seems like normal scroll wheel emulation - and as it currently does not have scroll momentum I loose the momentum provided by TrackScroll.

In any case, I see the potential in hid-remapper. Do you think this dream can eventually be realized through this project? If so, please let me know if there is anything I can do to help it along.

jfedor2 commented 2 years ago

Personally I don't like acceleration, I want my inputs 1:1, which is why this feature never got priority. But of course I can see how some people might want it, for scrolling or just regular cursor movement. We should be able to implement it in some generic configurable fashion.

"Momentum", or inertial scrolling, is a bit tricky. It works really well on touchscreens and touchpads, because they know when your finger is touching the screen and when it is lifted. With this information it's possible to only apply it when the user expects it and do a normal stop otherwise. With a regular mouse or trackball we don't have this information and therefore we don't know what the user intended to do. I'd expect it to feel "floaty" if we gave it inertia all the time. Maybe it would be fine for scrolling.

itsnoteasy commented 3 weeks ago

Personally I don't like acceleration, I want my inputs 1:1, which is why this feature never got priority. But of course I can see how some people might want it, for scrolling or just regular cursor movement. We should be able to implement it in some generic configurable fashion.

"Momentum", or inertial scrolling, is a bit tricky. It works really well on touchscreens and touchpads, because they know when your finger is touching the screen and when it is lifted. With this information it's possible to only apply it when the user expects it and do a normal stop otherwise. With a regular mouse or trackball we don't have this information and therefore we don't know what the user intended to do. I'd expect it to feel "floaty" if we gave it inertia all the time. Maybe it would be fine for scrolling.

I have a diy mouse project that i partially contributed to. I wrote some code for the wheel acceleration but since it was in avr c it's too spaghetti like for use here.

however i liked the gentle acceleration curve. it was based on the slope of line equation, y=ax+c so i think i measured the time between sequential scroll events, and if they were shorter than a constant, then that time would be plugged into the equation as one of the variables. then the output would be anywhere between 4 to 16 times as large in practice.

although it sounds unweildy it was very controllable. i'm not sure how long a period of time 15 is, it's based on loops in the code. It's possibly 15 milliseconds. here's the code i used

      if (whl_time < 15) {
        rev = 15 - whl_time;
        rev = (rev >> 2) + 4;
        stack = stack - rev;

this code subtracts the period between the scroll events from the constant 15 in order to start producing a variable for the formula that becomes larger the faster the wheel is turned.

then the formula uses a bitshift operator to multiply the variable by 2, then by 2 again, then add 4. the stack variable relates to counting loops for timing purposes, not really relevant here.

the output of the formula, the variable rev is used to multiply by the number of scroll events in a recent defined period of time in order to produce faster movement. not true acceleration due to gravity since that works on squares but its nice all the same.