albertz / mouse-scroll-wheel-acceleration-userspace

Mouse scroll wheel acceleration in user space
MIT License
130 stars 4 forks source link

Really slow scrolling results in no scrolling for some wheel encoder ticks #8

Open ElectricRCAircraftGuy opened 1 year ago

ElectricRCAircraftGuy commented 1 year ago

Actual behavior: slow scrolling results in many encoder ticks on the scroll wheel which result in no movement.

Desired behavior: really slow scrolling should result in a 1:1 scroll correlation, the same as if your tool was off.

Also, your tool should offer a way to disable the acceleration and just use a pure multiplier, so it can become a direct replacement for imwheel for those just making imwheel multiply their scroll distance per wheel encoder tick.

albertz commented 1 year ago

To clarify:

When the tool is on, the scroll speed is even slower for slow scroll speeds? Or already too fast?

What do you mean by encoder ticks?

What are your settings?

Can you start the tool with -v or -vv and post the output during such phase you are describing?

What operating system, window manager? Is this with Wayland?

Note that all this tool does (or should do) is sending out additional scroll events. All the existing natural scroll events would still be handled as well by the applications. I wonder if that behavior is somehow different in Wayland. I did not test this yet on Wayland.

Maybe there is also a problem with pynput?

Also, your tool should offer a way to disable the acceleration and just use a pure multiplier

By setting exp=0, you should get that.

The formula is:

m = user_scroll_speed * exp target_scroll_speed = user_scroll_speed m * multiplier

Note that in this setting, you cannot have your desired behavior you described earlier. Your desired behavior basically is that you do not want to have just a pure multiplier, but you want to have actual acceleration on higher scroll speeds.

ElectricRCAircraftGuy commented 1 year ago

Thanks for the quick response.

When the tool is on, the scroll speed is even slower...?

Yes. Slower.

No tool --> one encoder tick moves 1 line.

With tool on --> one encoder tick moves 1 or 0 lines. Ex: 1 line, 0 lines, 1 line, 0 lines, 1 line, 1 line, 0 lines, etc.

What do you mean by encoder ticks?

I have this mouse: logitech MX Vertical Advanced Ergonomic Mouse

It has physical "clicks" in the mouse wheel. You know--like the wheel is mechanically notched. One tick is moving one "click" or "notch" on the wheel. I am guessing that on this mouse that also corresponds to once optical quadrature encoder square wave, since I get a 1 to 1 correlation by default of one notch or tick on the wheel --> 1 line moved in scrolling.

What are your settings?

I followed your instructions here: https://askubuntu.com/a/1309000/327339 and did ./main.py -v --exp 1.

Can you start the tool with -v or -vv and post the output during such phase you are describing?

Sure:

killall imwheel  # ensure this doesn't interfere, first

cd path/to/mouse-scroll-wheel-acceleration-userspace
./main.py -v --exp 1

cmd and output:

$ ./main.py -v --exp 1
2023-06-03 17:49:54,868 WARNING: Config /home/gabrielstaples/.config/mouse-scroll-wheel-accelerator/config.py not found
2023-06-03 17:49:57,901 INFO: scroll user vel 1.42 -> accel multiplier 1.42, cur vel Vec2(0.00, 1.42), target vel 2.02 -> scroll Vec2(0.00, 0.60)
2023-06-03 17:49:58,562 INFO: scroll user vel 1.34 -> accel multiplier 1.34, cur vel Vec2(0.00, 1.68), target vel 1.79 -> scroll Vec2(0.00, 0.11)
2023-06-03 17:50:00,543 INFO: scroll user vel 1.29 -> accel multiplier 1.29, cur vel Vec2(0.00, 1.29), target vel 1.67 -> scroll Vec2(0.00, 0.37)
2023-06-03 17:50:03,638 INFO: scroll user vel 1.49 -> accel multiplier 1.49, cur vel Vec2(0.00, 1.49), target vel 2.21 -> scroll Vec2(0.00, 0.72)
2023-06-03 17:50:04,325 INFO: scroll user vel 1.31 -> accel multiplier 1.31, cur vel Vec2(0.00, 1.63), target vel 1.72 -> scroll Vec2(0.00, 0.10)
2023-06-03 17:50:04,916 INFO: scroll user vel 1.41 -> accel multiplier 1.41, cur vel Vec2(0.00, 1.41), target vel 1.99 -> scroll Vec2(0.00, 0.58)
2023-06-03 17:50:05,453 INFO: scroll user vel 1.46 -> accel multiplier 1.46, cur vel Vec2(0.00, 1.93), target vel 2.14 -> scroll Vec2(0.00, 0.21)
2023-06-03 17:50:05,970 INFO: scroll user vel 1.48 -> accel multiplier 1.48, cur vel Vec2(0.00, 1.48), target vel 2.20 -> scroll Vec2(0.00, 0.72)
2023-06-03 17:50:06,485 INFO: scroll user vel 1.48 -> accel multiplier 1.48, cur vel Vec2(0.00, 1.97), target vel 2.20 -> scroll Vec2(0.00, 0.23)
2023-06-03 17:50:07,016 INFO: scroll user vel 1.47 -> accel multiplier 1.47, cur vel Vec2(0.00, 1.47), target vel 2.16 -> scroll Vec2(0.00, 0.69)
2023-06-03 17:50:07,534 INFO: scroll user vel 1.48 -> accel multiplier 1.48, cur vel Vec2(0.00, 1.97), target vel 2.20 -> scroll Vec2(0.00, 0.23)
2023-06-03 17:50:10,353 INFO: scroll user vel 1.46 -> accel multiplier 1.46, cur vel Vec2(0.00, 1.46), target vel 2.13 -> scroll Vec2(0.00, 0.67)
2023-06-03 17:50:10,877 INFO: scroll user vel 1.48 -> accel multiplier 1.48, cur vel Vec2(0.00, 1.96), target vel 2.18 -> scroll Vec2(0.00, 0.22)
2023-06-03 17:50:11,457 INFO: scroll user vel 1.42 -> accel multiplier 1.42, cur vel Vec2(0.00, 1.42), target vel 2.01 -> scroll Vec2(0.00, 0.60)
2023-06-03 17:50:12,033 INFO: scroll user vel 1.42 -> accel multiplier 1.42, cur vel Vec2(0.00, 1.85), target vel 2.03 -> scroll Vec2(0.00, 0.18)
2023-06-03 17:50:12,573 INFO: scroll user vel 1.46 -> accel multiplier 1.46, cur vel Vec2(0.00, 1.46), target vel 2.13 -> scroll Vec2(0.00, 0.67)
2023-06-03 17:50:13,089 INFO: scroll user vel 1.48 -> accel multiplier 1.48, cur vel Vec2(0.00, 1.97), target vel 2.20 -> scroll Vec2(0.00, 0.23)
2023-06-03 17:50:13,685 INFO: scroll user vel 1.40 -> accel multiplier 1.40, cur vel Vec2(0.00, 1.40), target vel 1.97 -> scroll Vec2(0.00, 0.57)
2023-06-03 17:50:14,223 INFO: scroll user vel 1.46 -> accel multiplier 1.46, cur vel Vec2(0.00, 1.93), target vel 2.14 -> scroll Vec2(0.00, 0.21)
2023-06-03 17:50:14,736 INFO: scroll user vel 1.49 -> accel multiplier 1.49, cur vel Vec2(0.00, 1.49), target vel 2.21 -> scroll Vec2(0.00, 0.72)
2023-06-03 17:50:15,300 INFO: scroll user vel 1.44 -> accel multiplier 1.44, cur vel Vec2(0.00, 1.88), target vel 2.06 -> scroll Vec2(0.00, 0.19)
2023-06-03 17:50:15,883 INFO: scroll user vel 1.42 -> accel multiplier 1.42, cur vel Vec2(0.00, 1.42), target vel 2.01 -> scroll Vec2(0.00, 0.59)
2023-06-03 17:50:16,455 INFO: scroll user vel 1.43 -> accel multiplier 1.43, cur vel Vec2(0.00, 1.86), target vel 2.04 -> scroll Vec2(0.00, 0.18)
2023-06-03 17:50:17,011 INFO: scroll user vel 1.44 -> accel multiplier 1.44, cur vel Vec2(0.00, 1.44), target vel 2.09 -> scroll Vec2(0.00, 0.64)
2023-06-03 17:50:17,504 INFO: scroll user vel 1.51 -> accel multiplier 1.51, cur vel Vec2(0.00, 2.02), target vel 2.27 -> scroll Vec2(0.00, 0.25)
2023-06-03 17:50:18,011 INFO: scroll user vel 1.49 -> accel multiplier 1.49, cur vel Vec2(0.00, 1.50), target vel 2.23 -> scroll Vec2(0.00, 0.73)
2023-06-03 17:50:18,590 INFO: scroll user vel 1.42 -> accel multiplier 1.42, cur vel Vec2(0.00, 1.84), target vel 2.02 -> scroll Vec2(0.00, 0.17)

Most of the time I got no movement when it printed out a line.

What operating system, window manager? Is this with Wayland?

Brand new Ubuntu 22.04.2 install. Yes, Wayland is the default window manager, and that's what I'm using right now.

Note that all this tool does (or should do) is sending out additional scroll events. All the existing natural scroll events would still be handled as well by the applications. I wonder if that behavior is somehow different in Wayland. I did not test this yet on Wayland.

I'm pretty sure I saw the same behavior on X11 too.

Maybe there is also a problem with pynput?

Could be.

Also, your tool should offer a way to disable the acceleration and just use a pure multiplier

By setting exp=0, you should get that.

The formula is:

m = user_scroll_speed * exp target_scroll_speed = user_scroll_speed m * multiplier

Note that in this setting, you cannot have your desired behavior you described earlier. Your desired behavior basically is that you do not want to have just a pure multiplier, but you want to have actual acceleration on higher scroll speeds.

With this: ./main.py -v --exp 0 --multiplier 2, I now get a 1:1 correlation: 1 line scrolled for every 1 mouse wheel "tick"--similar to having the tool off.

Some output:

$ ./main.py -v --exp 0 --multiplier 2
2023-06-03 17:53:13,425 WARNING: Config /home/gabrielstaples/.config/mouse-scroll-wheel-accelerator/config.py not found
2023-06-03 17:53:17,505 INFO: scroll user vel 1.32 -> accel multiplier 2.00, cur vel Vec2(0.00, 1.32), target vel 2.64 -> scroll Vec2(0.00, 1.32)
2023-06-03 17:53:18,103 INFO: scroll user vel 1.40 -> accel multiplier 2.00, cur vel Vec2(0.00, 1.81), target vel 2.80 -> scroll Vec2(0.00, 1.00)
2023-06-03 17:53:18,720 INFO: scroll user vel 1.38 -> accel multiplier 2.00, cur vel Vec2(0.00, 1.77), target vel 2.77 -> scroll Vec2(0.00, 1.00)
2023-06-03 17:53:19,349 INFO: scroll user vel 1.37 -> accel multiplier 2.00, cur vel Vec2(0.00, 1.75), target vel 2.74 -> scroll Vec2(0.00, 1.00)
2023-06-03 17:53:19,969 INFO: scroll user vel 1.38 -> accel multiplier 2.00, cur vel Vec2(0.00, 1.76), target vel 2.76 -> scroll Vec2(0.00, 1.00)
2023-06-03 17:53:20,571 INFO: scroll user vel 1.40 -> accel multiplier 2.00, cur vel Vec2(0.00, 1.80), target vel 2.80 -> scroll Vec2(0.00, 1.00)
2023-06-03 17:53:21,213 INFO: scroll user vel 1.36 -> accel multiplier 2.00, cur vel Vec2(0.00, 1.72), target vel 2.72 -> scroll Vec2(0.00, 1.00)
2023-06-03 17:53:21,857 INFO: scroll user vel 1.36 -> accel multiplier 2.00, cur vel Vec2(0.00, 1.71), target vel 2.71 -> scroll Vec2(0.00, 1.00)
2023-06-03 17:53:22,542 INFO: scroll user vel 1.32 -> accel multiplier 2.00, cur vel Vec2(0.00, 1.63), target vel 2.63 -> scroll Vec2(0.00, 1.00)
2023-06-03 17:53:23,225 INFO: scroll user vel 1.32 -> accel multiplier 2.00, cur vel Vec2(0.00, 1.64), target vel 2.63 -> scroll Vec2(0.00, 1.00)
2023-06-03 17:53:23,919 INFO: scroll user vel 1.31 -> accel multiplier 2.00, cur vel Vec2(0.00, 1.61), target vel 2.61 -> scroll Vec2(0.00, 1.00)
2023-06-03 17:53:24,514 INFO: scroll user vel 1.40 -> accel multiplier 2.00, cur vel Vec2(0.00, 1.81), target vel 2.81 -> scroll Vec2(0.00, 1.00)
2023-06-03 17:53:25,170 INFO: scroll user vel 1.34 -> accel multiplier 2.00, cur vel Vec2(0.00, 1.69), target vel 2.69 -> scroll Vec2(0.00, 1.00)
2023-06-03 17:53:25,762 INFO: scroll user vel 1.41 -> accel multiplier 2.00, cur vel Vec2(0.00, 1.82), target vel 2.82 -> scroll Vec2(0.00, 1.00)
2023-06-03 17:53:26,196 INFO: scroll user vel 1.57 -> accel multiplier 2.00, cur vel Vec2(0.00, 2.13), target vel 3.13 -> scroll Vec2(0.00, 1.00)
2023-06-03 17:53:26,229 INFO: scroll user vel 2.50 -> accel multiplier 2.00, cur vel Vec2(0.00, 4.01), target vel 5.00 -> scroll Vec2(0.00, 0.99)

With this setting, I get usually 10x as many lines moved, but it still feels bad and glitchy. What I don't like is that if I pause, wait a couple seconds, then go to scroll again, my first few mouse wheel "ticks" have zero affect again, and if I switch directions, my first mouse wheel "tick" in the opposite direction has no effect.

$ ./main.py -v --exp 0 --multiplier 10
2023-06-03 17:54:50,364 WARNING: Config /home/gabrielstaples/.config/mouse-scroll-wheel-accelerator/config.py not found
2023-06-03 17:54:53,107 INFO: scroll user vel 1.39 -> accel multiplier 10.00, cur vel Vec2(0.00, 1.39), target vel 13.88 -> scroll Vec2(0.00, 12.49)
2023-06-03 17:54:53,770 INFO: scroll user vel 1.34 -> accel multiplier 10.00, cur vel Vec2(0.00, 5.61), target vel 13.36 -> scroll Vec2(0.00, 7.76)
2023-06-03 17:54:54,347 INFO: scroll user vel 1.42 -> accel multiplier 10.00, cur vel Vec2(0.00, 4.91), target vel 14.23 -> scroll Vec2(0.00, 9.33)
2023-06-03 17:54:54,974 INFO: scroll user vel 1.37 -> accel multiplier 10.00, cur vel Vec2(0.00, 4.86), target vel 13.73 -> scroll Vec2(0.00, 8.87)
2023-06-03 17:54:55,550 INFO: scroll user vel 1.42 -> accel multiplier 10.00, cur vel Vec2(0.00, 5.39), target vel 14.25 -> scroll Vec2(0.00, 8.86)
2023-06-03 17:54:57,151 INFO: scroll user vel 1.25 -> accel multiplier 10.00, cur vel Vec2(0.00, -1.25), target vel 12.52 -> scroll Vec2(0.00, -11.27)
2023-06-03 17:54:57,779 INFO: scroll user vel 1.37 -> accel multiplier 10.00, cur vel Vec2(0.00, -5.65), target vel 13.72 -> scroll Vec2(0.00, -8.07)
2023-06-03 17:54:58,343 INFO: scroll user vel 1.44 -> accel multiplier 10.00, cur vel Vec2(0.00, -5.04), target vel 14.37 -> scroll Vec2(0.00, -9.33)
2023-06-03 17:54:58,829 INFO: scroll user vel 1.51 -> accel multiplier 10.00, cur vel Vec2(0.00, -6.26), target vel 15.13 -> scroll Vec2(0.00, -8.88)
2023-06-03 17:54:59,305 INFO: scroll user vel 1.56 -> accel multiplier 10.00, cur vel Vec2(0.00, -6.87), target vel 15.62 -> scroll Vec2(0.00, -8.76)
2023-06-03 17:54:59,708 INFO: scroll user vel 1.72 -> accel multiplier 10.00, cur vel Vec2(0.00, -8.42), target vel 17.18 -> scroll Vec2(0.00, -8.76)
2023-06-03 17:55:00,102 INFO: scroll user vel 1.81 -> accel multiplier 10.00, cur vel Vec2(0.00, -9.33), target vel 18.10 -> scroll Vec2(0.00, -8.77)
2023-06-03 17:55:00,501 INFO: scroll user vel 1.81 -> accel multiplier 10.00, cur vel Vec2(0.00, -9.32), target vel 18.09 -> scroll Vec2(0.00, -8.77)
2023-06-03 17:55:00,901 INFO: scroll user vel 1.80 -> accel multiplier 10.00, cur vel Vec2(0.00, -9.24), target vel 18.01 -> scroll Vec2(0.00, -8.76)
2023-06-03 17:55:01,384 INFO: scroll user vel 1.63 -> accel multiplier 10.00, cur vel Vec2(0.00, -7.58), target vel 16.33 -> scroll Vec2(0.00, -8.75)
2023-06-03 17:55:01,504 INFO: scroll user vel 2.28 -> accel multiplier 10.00, cur vel Vec2(0.00, -14.07), target vel 22.76 -> scroll Vec2(0.00, -8.69)
2023-06-03 17:55:04,058 INFO: scroll user vel 1.36 -> accel multiplier 10.00, cur vel Vec2(0.00, 1.36), target vel 13.63 -> scroll Vec2(0.00, 12.27)
2023-06-03 17:55:04,852 INFO: scroll user vel 1.21 -> accel multiplier 10.00, cur vel Vec2(0.00, 3.89), target vel 12.06 -> scroll Vec2(0.00, 8.17)
2023-06-03 17:55:05,556 INFO: scroll user vel 1.30 -> accel multiplier 10.00, cur vel Vec2(0.00, 3.77), target vel 12.96 -> scroll Vec2(0.00, 9.19)
2023-06-03 17:55:07,497 INFO: scroll user vel 1.13 -> accel multiplier 10.00, cur vel Vec2(0.00, 1.13), target vel 11.30 -> scroll Vec2(0.00, 10.17)
2023-06-03 17:55:08,140 INFO: scroll user vel 1.36 -> accel multiplier 10.00, cur vel Vec2(0.00, 5.11), target vel 13.56 -> scroll Vec2(0.00, 8.45)
2023-06-03 17:55:11,801 INFO: scroll user vel 1.10 -> accel multiplier 10.00, cur vel Vec2(0.00, 1.10), target vel 11.04 -> scroll Vec2(0.00, 9.93)

I think I might one day try to use pynput myself and write a new tool from scratch. If you can address these concerns, of course I'll never need to do that. I think your tool is a great start, and you have an excellent readme, and made me aware of pynput, but I find its response to not be what I desire. It feels glitchy and doesn't respond "right." I think it should never have a case where a mouse wheel tick doesn't result in at least the minimum, baseline movement that would occur if the tool was off.

ElectricRCAircraftGuy commented 1 year ago

Note: the following is a separate issue from this issue, and the notes above.

pynput works only partially in Wayland

Check this out!: I just confirmed there is also a separate problem with pynput. When running the Wayland window manager on Ubuntu 22.04, pynput can detect scroll wheel movements in Chrome just fine, but not in other programs such as the gnome-terminal, or Sublime Text.

Here is a small Python test program I just wrote:

# modified from here: https://pypi.org/project/pynput/

from pynput import mouse

def on_scroll(x, y, dx, dy):
    print('Scrolled {}; (x, y)=({:4d}, {:4d}); (dx, dy)={}'.format(
        'down' if dy < 0 else 'up  ',
        x, y,
        (dx, dy),
    ))

# block the main thread, listening
# Collect events until released
with mouse.Listener(
        on_scroll=on_scroll) as listener:
    listener.join()

And here is some sample output, which only prints a line when scrolling in Chrome, but not in my terminal nor in Sublime Text:

$ ./pynput_mouse_wheel.py
Scrolled down; (x, y)=(4625, 1695); (dx, dy)=(0, -1)
Scrolled down; (x, y)=(4625, 1695); (dx, dy)=(0, -1)
Scrolled down; (x, y)=(4625, 1695); (dx, dy)=(0, -1)
Scrolled down; (x, y)=(4625, 1695); (dx, dy)=(0, -1)
Scrolled down; (x, y)=(4625, 1695); (dx, dy)=(0, -1)
Scrolled down; (x, y)=(4625, 1695); (dx, dy)=(0, -1)
Scrolled down; (x, y)=(4625, 1695); (dx, dy)=(0, -1)
Scrolled down; (x, y)=(4625, 1695); (dx, dy)=(0, -1)
Scrolled up  ; (x, y)=(4505, 1698); (dx, dy)=(0, 1)
Scrolled up  ; (x, y)=(4505, 1698); (dx, dy)=(0, 1)
Scrolled up  ; (x, y)=(4505, 1698); (dx, dy)=(0, 1)
Scrolled up  ; (x, y)=(4505, 1698); (dx, dy)=(0, 1)
Scrolled up  ; (x, y)=(4505, 1698); (dx, dy)=(0, 1)
Scrolled up  ; (x, y)=(4505, 1698); (dx, dy)=(0, 1)
Scrolled up  ; (x, y)=(4505, 1698); (dx, dy)=(0, 1)
Scrolled down; (x, y)=(4505, 1698); (dx, dy)=(0, -1)
Scrolled down; (x, y)=(4505, 1698); (dx, dy)=(0, -1)
Scrolled down; (x, y)=(4505, 1698); (dx, dy)=(0, -1)

but it works fully in X11

But in the X11 Window manager, it works fully. My same program above is able to detect mouse scroll wheel movements in all programs, including Chrome, the terminal it's running in, Sublime Text, etc. That's a big difference and definitely a problem in Wayland!

See also

  1. I just cross-linked to this post in my answer here: https://askubuntu.com/a/991680/327339
albertz commented 1 year ago

In https://github.com/moses-palmer/pynput/issues/555 and in the pynput doc, it is mentioned that it might work when you run it as root. Then it would use the uinput library as backend. Otherwise, it only seems to work for apps running through XWayland, because the security model of Wayland prevents pynput from working otherwise.