alacritty / alacritty

A cross-platform, OpenGL terminal emulator.
https://alacritty.org
Apache License 2.0
55.91k stars 3k forks source link

Allow adjusting scroll sensitivity #2869

Open lewisthompson opened 4 years ago

lewisthompson commented 4 years ago

This is likely a re-open of: https://github.com/jwilm/alacritty/issues/622. I'm running macOS 10.15 Catalina & Alacritty 0.3.3 from homebrew.

I moved from iTerm2 -> Alacritty + tmux. Scrolling is not as responsive in my new setup as it was in iTerm2. Until now I had assumed this was tmux but further investigation shows the issue to lie in Alacritty.

  1. In iTerm2 if I scroll my scrollwheel extremely slowly iTerm2 reflects this scrolling (this is true if I run tmux with the same config in iTerm2)
  2. In Alacritty I need to make more exaggerated scroll movements for single lines to be scrolled

I ran alacritty with --show-events and these are the scrolling lines:

[2019-10-11 14:25] [INFO] glutin event: WindowEvent { window_id: WindowId(Id(140210026559312)), event: MouseWheel { device_id: DeviceId(DeviceId), delta: LineDelta(0.0, 0.1000061), phase: Moved, modifiers: ModifiersState { shift: false, ctrl: false, alt: false, logo: false } } }
[2019-10-11 14:25] [INFO] glutin event: DeviceEvent { device_id: DeviceId(DeviceId), event: MouseWheel { delta: LineDelta(0.0, 0.1000061) } }
[2019-10-11 14:25] [INFO] glutin event: WindowEvent { window_id: WindowId(Id(140210026559312)), event: MouseWheel { device_id: DeviceId(DeviceId), delta: LineDelta(0.0, 0.1000061), phase: Moved, modifiers: ModifiersState { shift: false, ctrl: false, alt: false, logo: false } } }
[2019-10-11 14:25] [INFO] glutin event: DeviceEvent { device_id: DeviceId(DeviceId), event: MouseWheel { delta: LineDelta(0.0, 0.1000061) } }
[2019-10-11 14:25] [INFO] glutin event: WindowEvent { window_id: WindowId(Id(140210026559312)), event: MouseWheel { device_id: DeviceId(DeviceId), delta: LineDelta(0.0, 0.1000061), phase: Moved, modifiers: ModifiersState { shift: false, ctrl: false, alt: false, logo: false } } }
[2019-10-11 14:25] [INFO] glutin event: DeviceEvent { device_id: DeviceId(DeviceId), event: MouseWheel { delta: LineDelta(0.0, 0.1000061) } }
[2019-10-11 14:25] [INFO] glutin event: WindowEvent { window_id: WindowId(Id(140210026559312)), event: MouseWheel { device_id: DeviceId(DeviceId), delta: LineDelta(0.0, 0.1000061), phase: Moved, modifiers: ModifiersState { shift: false, ctrl: false, alt: false, logo: false } } }
[2019-10-11 14:25] [INFO] glutin event: DeviceEvent { device_id: DeviceId(DeviceId), event: MouseWheel { delta: LineDelta(0.0, 0.1000061) } }
[2019-10-11 14:25] [INFO] glutin event: WindowEvent { window_id: WindowId(Id(140210026559312)), event: MouseWheel { device_id: DeviceId(DeviceId), delta: LineDelta(0.0, 0.1000061), phase: Moved, modifiers: ModifiersState { shift: false, ctrl: false, alt: false, logo: false } } }
[2019-10-11 14:25] [INFO] glutin event: DeviceEvent { device_id: DeviceId(DeviceId), event: MouseWheel { delta: LineDelta(0.0, 0.1000061) } }
[2019-10-11 14:25] [INFO] glutin event: WindowEvent { window_id: WindowId(Id(140210026559312)), event: MouseWheel { device_id: DeviceId(DeviceId), delta: LineDelta(0.0, 0.1000061), phase: Moved, modifiers: ModifiersState { shift: false, ctrl: false, alt: false, logo: false } } }
[2019-10-11 14:25] [INFO] glutin event: DeviceEvent { device_id: DeviceId(DeviceId), event: MouseWheel { delta: LineDelta(0.0, 0.1000061) } }
[2019-10-11 14:25] [INFO] glutin event: WindowEvent { window_id: WindowId(Id(140210026559312)), event: MouseWheel { device_id: DeviceId(DeviceId), delta: LineDelta(0.0, 0.1000061), phase: Moved, modifiers: ModifiersState { shift: false, ctrl: false, alt: false, logo: false } } }
[2019-10-11 14:25] [INFO] glutin event: DeviceEvent { device_id: DeviceId(DeviceId), event: MouseWheel { delta: LineDelta(0.0, 0.1000061) } }
[2019-10-11 14:25] [INFO] glutin event: WindowEvent { window_id: WindowId(Id(140210026559312)), event: MouseWheel { device_id: DeviceId(DeviceId), delta: LineDelta(0.0, 0.1000061), phase: Moved, modifiers: ModifiersState { shift: false, ctrl: false, alt: false, logo: false } } }
[2019-10-11 14:25] [INFO] glutin event: DeviceEvent { device_id: DeviceId(DeviceId), event: MouseWheel { delta: LineDelta(0.0, 0.1000061) } }

Not one of these MouseWheel events resulted in any scrolling activity. By comparison if I make the more aggressive scroll events scrolling does take place (I also see an Awakened line which I assume is the scrolling taking place?):

[2019-10-11 14:29] [INFO] glutin event: WindowEvent { window_id: WindowId(Id(140269829034832)), event: MouseWheel { device_id: DeviceId(DeviceId), delta: LineDelta(0.0, 2.9938812), phase: Moved, modifiers: ModifiersState { shift: false, ctrl: false, alt: false, logo: false } } }
[2019-10-11 14:29] [INFO] glutin event: DeviceEvent { device_id: DeviceId(DeviceId), event: MouseWheel { delta: LineDelta(0.0, 2.9938812) } }
[2019-10-11 14:29] [INFO] glutin event: Awakened
[2019-10-11 14:29] [INFO] glutin event: WindowEvent { window_id: WindowId(Id(140269829034832)), event: MouseWheel { device_id: DeviceId(DeviceId), delta: LineDelta(0.0, 4.4611664), phase: Moved, modifiers: ModifiersState { shift: false, ctrl: false, alt: false, logo: false } } }
[2019-10-11 14:29] [INFO] glutin event: DeviceEvent { device_id: DeviceId(DeviceId), event: MouseWheel { delta: LineDelta(0.0, 4.4611664) } }
[2019-10-11 14:29] [INFO] glutin event: Awakened
[2019-10-11 14:29] [INFO] glutin event: Awakened

I'd like to be able to configure Alacritty such that for every single MouseWheel event results in scrolling activity.

lewisthompson commented 4 years ago

Just to clarify: as things behave currently in Alacritty it is extremely difficult for me to reliably scroll up a single or specific number of lines so I end up scrolling up too much, then scrolling down too much, etc. until I get it "just right" ;)

lewisthompson commented 4 years ago

So in alacritty/src/input.rs the MouseScrollDelta::LineDelta handler assigns new_scroll_px directly from lines received from glutin.

I get exactly the behaviour I expect/want by basically taking the max of 1 or -1 and the passed lines.

Unfortunately I'm not in a position where I am able to send a PR, much as I might like to.

chrisduerr commented 4 years ago

Back when I looked into this, my conclusion was that this was because of the awful decision of macOS to use scrolling acceleration for the mouse wheel instead of just the touchpad.

As a result, scrolling slower means there will be significantly less line changes than when scrolling faster, even if it's the same amount of distance with the wheel. You can see that when looking at your output, (slow delta of 0.1 vs fast delta of 4+).

Alacritty already tries to adjust for this, by taking the line delta below 1.0, storing it and scrolling by one line as soon as the accumulated delta increases above 1.0.

So I'm mostly curious about that change you're suggesting. I'm not sure why you're unable to send a PR, but could you post a diff maybe? I don't quite understand what you're talking about. If you're talking about always scrolling by at least 1 line, that won't work especially with touchpads.

chrisduerr commented 4 years ago

Without a code example it's hard to make any judgements, but the only way I can understand your suggestion would be something like this:

let lines = if lines < 0.0 { min(lines, -1.0) } else { max(lines, 1.0) };
let new_scroll_px = lines * self.ctx.size_info().cell_height;

If that really is what you mean, then it creates issues with trackpads. Since trackpads usually send only very small increments and expects bigger movements to be used to move faster. This is why we sum up these incremental values and wait until we've got enough to make up for an entire line. This way we can make sure things are tracked appropriately, which works very well with trackpads and allows for very small movements to slowly scroll the terminal.

The issue here is macOS. All other platforms would never get the ridiculous idea to have mouse acceleration on mouse wheels, however macOS decided that it would be a good idea. So when scrolling it sends tiny incremental updates unless you're scrolling quickly enough. Unfortunately, I don't even think there's a way to turn this off anymore and it has driven me absolutely crazy in various different applications.

As far as I can tell, there's no good way to fix this without impacting everyone else who makes use of this working as expected.

lewisthompson commented 4 years ago

Apologies for delay responding - yes, this is pretty much the little change that I made.

At least on macOS with scrolling configured to work like this I get great responsiveness on both my scroll wheel & mb MBP trackpad. Neither is too sensitive and it roughly matches the behaviour I was experiencing using iTerm2.

I have about three different scroll-wheel mice at home that I will try out tonight and verify they still behave reasonably. Obviously this isn't definitive but, if these all work maybe it would make sense to consider making this behaviour default for macOS?

lewisthompson commented 4 years ago

So I tested with:

Logitech M705 Logitech MX Master Anker Vertical Mouse RollerMouse Red Wireless MBP internal trackpad

In all cases scrolling is smooth, it's possible to scroll just one line (and they line up with clicks on wheels), etc.

chrisduerr commented 4 years ago

In all cases scrolling is smooth, it's possible to scroll just one line (and they line up with clicks on wheels), etc.

I've tested this change myself before, it definitely breaks touchpads, mice are not the issue.

anandijain commented 4 years ago

This may not be helpful, but one feature that I've found helpful in vscode is the use of a mod key for increased scrolling speed.

I'm thinking that maybe if a mod key is being held, scroll is say, 3 lines/tick, instead of 1.

nixpulvis commented 4 years ago

I'm wondering if it makes any sense to try and allow configuring this as a "binding", or a separate setting. I know there's some desire to have binding actions that take arguments. For example, an IncreaseFontSize(2) or something like that.

Just a thought, since it would require a little moving of things around in the code.

kchibisov commented 4 years ago

I'm wondering if it makes any sense to try and allow configuring this as a "binding", or a separate setting. I know there's some desire to have binding actions that take arguments. For example, an IncreaseFontSize(2) or something like that.

Just bind it twice.

NickeZ commented 3 weeks ago

Even with scroll speed set to highest setting, the line delta is still 0.1, so it takes like 10 scroll events to actually scroll. The same issue is not present in the built in terminal.

Does anyone have a good workaround, or do I need to patch alacritty?

edit:

Scrolling with the touchpad produces events like this:

[77.206220834s] [INFO ] [alacritty] winit event: DeviceEvent { device_id: DeviceId(DeviceId), event: MouseWheel { delta: PixelDelta(PhysicalPosition { x: 0.0, y: 1.0 }) } }
[77.206236542s] [INFO ] [alacritty] winit event: WindowEvent { window_id: WindowId(WindowId(5330981744)), event: MouseWheel { device_id: DeviceId(DeviceId), delta: PixelDelta(PhysicalPosition { x: 0.0, y: 1.0 }), phase: Moved } }

Whereas scrolling with the mouse produces this:

[85.097983792s] [INFO ] [alacritty] winit event: DeviceEvent { device_id: DeviceId(DeviceId), event: MouseWheel { delta: LineDelta(0.0, -0.1000061) } }
[85.098093125s] [INFO ] [alacritty] winit event: WindowEvent { window_id: WindowId(WindowId(5330981744)), event: MouseWheel { device_id: DeviceId(DeviceId), delta: LineDelta(0.0, -0.1000061), phase: Moved } }

There seem to be special handling of the touchpad to round up to 1/-1. Is that the case? Why can't we do the same for the mouse?