Bug 29905 - acceleration for mouse wheel
Summary: acceleration for mouse wheel
Status: REOPENED
Alias: None
Product: xorg
Classification: Unclassified
Component: Server/General (show other bugs)
Version: unspecified
Hardware: All All
: medium enhancement
Assignee: Xorg Project Team
QA Contact: Xorg Project Team
URL:
Whiteboard: 2012BRB_Reviewed
Keywords: patch
Depends on:
Blocks:
 
Reported: 2010-08-31 06:15 UTC by Albert Zeyer
Modified: 2017-06-27 09:16 UTC (History)
7 users (show)

See Also:
i915 platform:
i915 features:


Attachments
mouse wheel acceleration patch - rev1 (16.53 KB, patch)
2010-09-01 20:40 UTC, Albert Zeyer
no flags Details | Splinter Review
mouse wheel acceleration patch - rev2 (16.64 KB, patch)
2010-09-02 09:05 UTC, Albert Zeyer
no flags Details | Splinter Review

Note You need to log in before you can comment on or make changes to this bug.
Description Albert Zeyer 2010-08-31 06:15:03 UTC
It would be nice to have acceleration for the mouse wheel.

Report on Launchpad: https://bugs.launchpad.net/ubuntu/+source/meta-kde/+bug/619403
Comment 1 Albert Zeyer 2010-08-31 06:31:11 UTC
I am trying right now to implement this myself.

As I am not that used to the Xorg sources, this is what I want to do in xf86-input-mouse:

* Add some attributes in the _MouseDevRec struct (in fx86OSmouse.h) which are about the acceleration properties.
* In MouseCommonOptions in mouse.c, I am adding some additional handling to read those acceleration attributes.
* At some point in the input handling in mouse.c, add that acceleration handling (at what point exactly?). I plan to just throw out multiple button 4,5 press events.

Please give some comments about how to do it right.
Comment 2 Albert Zeyer 2010-08-31 06:35:14 UTC
Or probably it is better to add those properties to mousePrivRec (in mousePriv.h).
Comment 3 Julien Cristau 2010-08-31 06:36:33 UTC
As far as X is concerned mouse wheel is a couple of buttons, so I'm not sure what acceleration would mean there.  This sounds like it should be implemented in clients.  In any case moving to evdev as you probably don't want to be doing that in the mouse driver anyway.
Comment 4 Albert Zeyer 2010-09-01 20:29:37 UTC
Ok, I am in the middle of a progress here. I am trying to optimise it a bit further. But I will attach my current progress so far so you can review it and give some comments because I actually have the problem that sometimes (mostly after I restart xinit on a running Xserver), somehow the device property names are messed up or at least xinput shows this:


az@acompneu 1275 (~) %xinput list-props 8
Device 'Microsoft Microsoft IntelliMouse® Explorer':
	NumLock (119):	1
	left_ptr (241):		... of unknown type _DBUS_SESSION_BUS_SELECTION_az_9797c07820e7488abd822c644c1f55a4

	_DBUS_SESSION_BUS_ADDRESS (243):	0
	_DBUS_SESSION_BUS_PID (244):	0
	KDE_FULL_SESSION (245):		... of unknown type _DBUS_SESSION_BUS_SELECTION_az_9797c07820e7488abd822c644c1f55a4

	KDE_SESSION_VERSION (246):		... of unknown type _DBUS_SESSION_BUS_SELECTION_az_9797c07820e7488abd822c644c1f55a4

	WM_PROTOCOLS (247):		... of unknown type _DBUS_SESSION_BUS_SELECTION_az_9797c07820e7488abd822c644c1f55a4

	Evdev Reopen Attempts (226):	10
	Evdev Axis Inversion (227):	0, 0
	Evdev Axes Swap (229):	0
	_NET_WM_CONTEXT_HELP (251):	"LevelFive" (127), "AltGr" (128)
	_NET_WM_SYNC_REQUEST (252):	"Alt" (120), "LevelThree" (121), "LAlt" (122), "RAlt" (123), "RControl" (124), "LControl" (125), "ScrollLock" (126), "_KDE_SPLASH_PROGRESS" (239), "WM_LOCALE_NAME" (240), "_XKB_RULES_NAMES" (238), "_XKB_RULES_NAMES" (238), "_XKB_RULES_NAMES" (238), "_XKB_RULES_NAMES" (238)
	Evdev Middle Button Emulation (230):	2
	Evdev Middle Button Timeout (231):	50
	Evdev Wheel Emulation (232):	0
	Evdev Wheel Emulation Axes (233):	0, 0, 4, 5
	Evdev Wheel Emulation Inertia (234):	10
	Evdev Wheel Emulation Timeout (235):	200
	Evdev Wheel Emulation Button (236):	4
	Evdev Drag Lock Buttons (237):	0


It looks a lot like some memory is messed up. I already tried to debug with valgrind but I didn't see anything related (a whole bunch of other messages show up there, so I also might have missed it).

Another thing which makes the debuggin a bit complicated: Most applications seem to scroll already for one event by multiple pixel; about 20 pixel in Chrome. And I have set it to the minimum possible value in the KDE settings (not sure if Chrome takes those or has its own settings). That makes the debugging quite hard because the scrolling is soon pretty much too fast.
Comment 5 Albert Zeyer 2010-09-01 20:40:33 UTC
Created attachment 38377 [details] [review]
mouse wheel acceleration patch - rev1
Comment 6 Denis Dzyubenko 2010-09-02 04:58:53 UTC
just added me to the CC. Sounds like a good idea to have acceleration.
Comment 7 Albert Zeyer 2010-09-02 06:57:26 UTC
Comment on attachment 38377 [details] [review]
mouse wheel acceleration patch - rev1

Note that this patch is already outdated. I have posted a new version to the mailinglist. I am not sure if I will keep updating the patch also here, so please watch out for the patch on the mailinglist.
Comment 8 Albert Zeyer 2010-09-02 08:49:48 UTC
good values to play with: speed-multiplier: 100, max-speed: 20
Comment 9 Albert Zeyer 2010-09-02 09:05:40 UTC
Created attachment 38386 [details] [review]
mouse wheel acceleration patch - rev2
Comment 10 Jeremy Huddleston Sequoia 2011-10-09 03:57:54 UTC
Can you please send your patches to xorg-devel for review.  Please rebase them 
on top of current git master if appropriate.  Thanks.
Comment 11 erick 2012-02-07 15:40:33 UTC
Don't work for xorg-server-1.11.4 :( Please fix it.
Comment 12 Claudius Ellsel 2016-09-23 11:44:46 UTC
Any updates on this?
Comment 13 Peter Hutterer 2016-09-23 12:20:38 UTC
i guess the only update is a WONTFIX, given that this has been languishing for 6 years now. input stuff like this is moving to libinput anyway, and I don't think I'll implement mouse wheel acceleration there either.
Comment 14 Claudius Ellsel 2016-09-24 08:13:28 UTC
Alright. It is a bit sad though that apparently no developer seems to be interested in making Linux competitive with the two other big operating systems in this case.
Comment 15 Adam Goode 2017-01-05 17:13:10 UTC
I am interested in doing a libinput-based wheel acceleration.

Peter: are you opposed to libinput mouse wheel acceleration in general, or are you open to patches there? I think it could fit in cleanly.
Comment 16 Peter Hutterer 2017-01-05 22:40:49 UTC
Adam: I'm really hesitant to put it into libinput because I'm not sure the problem scope is well understood (at least by me) and what the actual point of it is. So far it's been a "would be nice" but - at least these days :) - we require a bit more information about use-cases and precise behaviours.

libinput provides two values for wheels: physical degrees and concrete steps, so for most events on most mice you get a (15°, 1 step) tuple. There is no room for acceleration there, if anything the acceleration would have to be in the xf86-input-libinput driver. There we recently added a patch to adjust the scroll distance based on the angle (see Bug 92772) so a wheel can now produce smooth scrolling for XI2 clients.

But as for any actual acceleration, someone (you? :) would have to come up with a good plan of what the actual use-case is to solve and how to solve it. Not necessarily with code at first but at least to get a good idea of what's happening. And of course we'll need buy-in from the bigger desktop environments.
Comment 17 main.haarp 2017-01-05 23:19:21 UTC
(In reply to Peter Hutterer from comment #16)
> Adam: I'm really hesitant to put it into libinput because I'm not sure the
> problem scope is well understood (at least by me) and what the actual point
> of it is. So far it's been a "would be nice" but - at least these days :) -
> we require a bit more information about use-cases and precise behaviours.
> 

At least from my corner of mouse usage, the problem is that X has no scroll distance multiplier like Windows does. Scrolling is slow.

Some applications have their own mechanisms to deal with that, like Firefox's hidden about:config preferences, or extensions for Chrome. Or you can also try to hack something together with imwheel.

If it's a touchpad, you can reduce the distance needed to send one "scroll event". This makes scrolling faster, but also less accurate and more error-prone.

Obviously none of these solutions are very good.

The future is going towards smooth scrolling, which is an incredible experience. But while it's buttery smooth, it still doesn't solve the problem of configurable scroll speed/distance.

Configurable acceleration on the input device driver level would solve this nicely. You could have fast scrolling when you need it, and even still retain slow but precise scrolling when you don't.
Comment 18 Claudius Ellsel 2017-01-06 11:05:29 UTC
To explain my understanding of acceleration:

The mouse wheel has a certain amount of lines that are scrolled with each scroll. This is often called "scroll speed"

An acceleration would increase/decrease the scroll speed dynamically based on how often the wheel scrolls in a certain amount of time. So if I rotate the wheel fast also the speed is increased meaning one also needs to rotate the wheel as often as one would need to if scrolling slower. I think this is the usecase - accuracy or speed in scrolling can be delivered as needed.

I am not sure, whether there is also something like scroll speed implemented. At least KDE offers a setting for it.

So if speed is implemented one can implement "acceleration" as something that changes the speed. Also I'd suggest a changeable value how strong the acceleration will be.
Comment 19 Albert Zeyer 2017-01-06 11:20:16 UTC
(In reply to Peter Hutterer from comment #16)
> Adam: I'm really hesitant to put it into libinput because I'm not sure the
> problem scope is well understood (at least by me) and what the actual point
> of it is. So far it's been a "would be nice" but - at least these days :) -
> we require a bit more information about use-cases and precise behaviours.

I'm not exactly sure why the point is not clear.

You can make the same argument for normal mouse cursor movement, where mouse cursor acceleration is a pretty standard thing. And I think it makes even more sense for mouse wheel scrolling than it does for mouse cursor movement.

In all cases, you want to be able to make precise movements, as precise as what the application allows (pixel based or line based but e.g. for scrolling a list, I think a nicer experience is pixel based in all cases). So this requires that the minimum possible scroll/movement speed greater zero is as low as possible (e.g. 1 pixel).

Also, you would want to make the movement/scrolling as fast as possible. For mouse cursor movement, this might be less of a problem because the screen is usually of finite size and usually not so big anyway. That is why I think it is even more important for scrolling than for cursor movement. The scroll area can usually be much larger (e.g. a whole book) or even be infinite and you might want to skip over huge parts at once.

By acceleration, you solve this nicely as this dynamically adapts the speed. It will be slow if you move slowly but it can be as fast as you want.
Comment 20 Peter Hutterer 2017-01-09 05:01:37 UTC
(In reply to main.haarp from comment #17)
> Configurable acceleration on the input device driver level would solve this
> nicely. You could have fast scrolling when you need it, and even still
> retain slow but precise scrolling when you don't.

I feel this is solving the wrong problem. If the document is long enough that scrolling acceleration is needed, the application (or toolkit) should honor that and provide the appropriate methods - that may include acceleration.
libinput sits too low to have the semantic awareness here. For example, scrolling events during alt-tab switch between applications but libinput doesn't know that, it merely forwards the hardware events.

This is also the reason why libinput doesn't do kinetic scrolling, it merely forwards enough information that a caller can implement it accurately.


(In reply to Albert Zeyer from comment #19)
> You can make the same argument for normal mouse cursor movement, where mouse
> cursor acceleration is a pretty standard thing. And I think it makes even
> more sense for mouse wheel scrolling than it does for mouse cursor movement.

yes, but we've had multiple decades of pointer acceleration being a thing. mouse wheel acceleration is less ubiquitous, which is why we should review the reasons for doing it.

> Also, you would want to make the movement/scrolling as fast as possible. For
> mouse cursor movement, this might be less of a problem because the screen is
> usually of finite size and usually not so big anyway. That is why I think it
> is even more important for scrolling than for cursor movement. The scroll
> area can usually be much larger (e.g. a whole book) or even be infinite and
> you might want to skip over huge parts at once.

judging by the general push towards touch-sensitive interfaces in the industry and the interfaces feeding back into old-style interfaces, it seems a better solution here would be to have kinetic scrolling on the scroll wheel. Which I think enlightenment already does.
Comment 21 main.haarp 2017-01-09 09:22:23 UTC
(In reply to Peter Hutterer from comment #20)
> (In reply to main.haarp from comment #17)
> If the document is long enough
> that scrolling acceleration is needed, the application (or toolkit) should
> honor that and provide the appropriate methods - that may include
> acceleration.
> libinput sits too low to have the semantic awareness here. For example,
> scrolling events during alt-tab switch between applications but libinput
> doesn't know that, it merely forwards the hardware events.

You have a point there, libinput will always lack the semantic awareness and thus not provide an ideal solution.

But I'll have to disagree. In an ideal world, you can offload acceleration to the app/toolkit. But since we have tons of legacy applications or developers unaware or unwilling to implement acceleration, they'll never receive the benefits. And even if they implement it, you get lots of duplicated efforts and functionality between apps.

If  acceleration depends on the toolkit/application, I fear it'll remain a toy for select applications on modern distros only.
Comment 22 Claudius Ellsel 2017-01-09 09:44:17 UTC
So if handling this in libinput causes problems, maybe there is a different central place where to implement it.
How do Windows or MacOS handle this, as it is probably working without issues there?
Comment 23 Peter Hutterer 2017-01-09 21:50:37 UTC
(In reply to main.haarp from comment #21)
> If  acceleration depends on the toolkit/application, I fear it'll remain a
> toy for select applications on modern distros only.

it's a thin line between adding these features for legacy applications and screwing things up for new applications that could do it better themselves. the worst mistake we made along these lines was kinetic scrolling in the synaptics driver, in addition to the various bugs it also made it impossible for clients to implement it properly themselves. something like wheel acceleration would be the same, it is transparent to the point that it makes smart acceleration in a client virtually impossible.


(In reply to Claudius Ellsel from comment #22)
> So if handling this in libinput causes problems, maybe there is a different
> central place where to implement it.
> How do Windows or MacOS handle this, as it is probably working without
> issues there?

Win/MacOS have less toolkits to worry about *and* they control almost the whole stack :)
it'd be possible to add it as additional data in libinput but then you still require the compositor to pass the data on. Which requires a) updates to the software and b) a wayland protocol to send that data on which again requires a), so legacy applications are still out in the void.
Comment 24 Abdurrahim 2017-02-01 23:49:43 UTC
I am surprised how much ignorant one can get. When I saw won't fix I see why linux wont making any progress. Now I see why there are so much forks on Linux no one can stand this much ignorance.

Let me correct one thing here:

"Win/MacOS have less toolkits to worry about *and* they control almost the whole stack :)"

Totally wrong. This shows how big ignorant you are getting. Just check how real-world works: http://www.neuber.com/taskmanager/process/ipoint.exe.html

Just thinking about explain of Unix philosophy to "Linux" developer especially who works on X11 what I admired most says this blown my mind away so I registered and wanted to make records for history so maybe someone in next gen would understand that all were not ignorant.....

Ok let me give you one of the best rules about Unix philosophy maybe it may cleanse your ignorance: Rule of modularity. If you cannot maintain all you simply modularize it. If you cant handle mouse driver accelaration leave it modularized. If you still don't have idea or don't understand with example I gave on Windows and best rule about Unix don't try to understand either....
Comment 25 Abdurrahim 2017-02-01 23:49:43 UTC
I am surprised how much ignorant one can get. When I saw won't fix I see why linux wont making any progress. Now I see why there are so much forks on Linux no one can stand this much ignorance.

Let me correct one thing here:

"Win/MacOS have less toolkits to worry about *and* they control almost the whole stack :)"

Totally wrong. This shows how big ignorant you are getting. Just check how real-world works: http://www.neuber.com/taskmanager/process/ipoint.exe.html

Just thinking about explain of Unix philosophy to "Linux" developer especially who works on X11 what I admired most says this blown my mind away so I registered and wanted to make records for history so maybe someone in next gen would understand that all were not ignorant.....

Ok let me give you one of the best rules about Unix philosophy maybe it may cleanse your ignorance: Rule of modularity. If you cannot maintain all you simply modularize it. If you cant handle mouse driver accelaration leave it modularized. If you still don't have idea or don't understand with example I gave on Windows and best rule about Unix don't try to understand either....
Comment 26 Adam Goode 2017-05-21 19:38:55 UTC
(In reply to Peter Hutterer from comment #16)
> Adam: I'm really hesitant to put it into libinput because I'm not sure the
> problem scope is well understood (at least by me) and what the actual point
> of it is. So far it's been a "would be nice" but - at least these days :) -
> we require a bit more information about use-cases and precise behaviours.
> 
> libinput provides two values for wheels: physical degrees and concrete
> steps, so for most events on most mice you get a (15°, 1 step) tuple. There
> is no room for acceleration there, if anything the acceleration would have
> to be in the xf86-input-libinput driver. There we recently added a patch to
> adjust the scroll distance based on the angle (see Bug 92772) so a wheel can
> now produce smooth scrolling for XI2 clients.
> 
> But as for any actual acceleration, someone (you? :) would have to come up
> with a good plan of what the actual use-case is to solve and how to solve
> it. Not necessarily with code at first but at least to get a good idea of
> what's happening. And of course we'll need buy-in from the bigger desktop
> environments.

I've been thinking a bit about this. Let me start with this proposal (I can open a new bug if we want to continue this).

Use case:
- Scrolling through a long document is slow with a mouse wheel

Prior work showing benefits of wheel acceleration:
- macOS
- Chrome OS

Requirements:
- Don't break anything
- Require minimum changes from clients

Proposal:
- Mouse wheel acceleration at the libinput level, only for mouse wheels
- Do no acceleration on values returned from libinput_event_pointer_get_axis_value_discrete, this keeps the promise in the API of reporting "physical mouse wheel clicks" and keeps us from needing to implement a new "get unaccelerated" API
- Ensure that legacy X wheel events (pre-XI2.1) are not accelerated

Open questions:
- Does this cover enough clients without breaking things? Chrome and Firefox support XI2.1, so this would accelerate those programs.
- Under X or XWayland, is it possible to accelerate XI2.1 events but not the legacy events? Or are the legacy events generated automatically?
- Or is it ok to accelerate legacy X wheel events? emacs has scroll acceleration already, and other clients may as well.


Again, I can open another bug if this seems reasonable. I don't want this to continue in a WONTFIX bug :)
Comment 27 erick 2017-05-26 02:57:40 UTC
I would like see this fixed. I don't know why the people don't see it this like a problem.
Comment 28 Albert Zeyer 2017-05-26 07:59:55 UTC
First thing, I would reopen this bug report (remove the WONTFIX) - it really doesn't matter if it's not clear yet where to implement this.

On the topic at where to implement this:

Conceptually, mouse scroll wheel acceleration is really the same thing as mouse cursor movement acceleration. That's why I think it would make most sense to implement at the same place, like I did in my initial implementation.

Note that while I'm not sure if my initial implementation was the most optimal way to implement this, it actually worked great, in all applications. The only thing which optionally could have made it even better would be if the applications all would do pixel-based scrolling and not more, but even if the applications behave just like they do, line-based scrolling or whatever other scrolling behavior, they don't need to know and they should not need to know about any underlying mouse scroll wheel acceleration. Just like they also should not need to know about mouse cursor move acceleration.

Maybe 3D games are an exception, which would want to disable mouse cursor move acceleration because they use the mouse cursor movement in a different way. The same argument might be true for mouse scroll wheel acceleration. This is again an argument that mouse scroll wheel acceleration should be handled in the same way as mouse cursor move acceleration.

I don't exactly understand why we are not looking at MacOSX how and at what level it is implemented there. It is a solved problem on MacOSX and works great. So about any question like at what level to implement it, why not do it like it's done on MacOSX?
So, I did some research on this, and here are some links, or keywords to look at and search for:
https://gist.github.com/svoisen/5215826
kCGScrollWheelEventIsContinuous
https://chromium.googlesource.com/chromium/src/+/68ac3a05284cd246589a38843f2ba5b20ed5db72%5E!/
https://codereview.chromium.org/42607
https://bugs.webkit.org/show_bug.cgi?id=24813
https://github.com/adobe/webkit/blob/master/Source/WebCore/platform/mac/WebCoreSystemInterface.mm
https://bugs.webkit.org/show_bug.cgi?id=45155
http://trac.webkit.org/changeset/66812/webkit
https://github.com/aosm/IOHIDFamily/blob/d36f126e5b8d3183a037c453df7feedaba874553/IOHIDSystem/IOKit/hidsystem/IOHIPointing.h
https://github.com/aosm/IOHIDFamily/blob/d36f126e5b8d3183a037c453df7feedaba874553/IOHIDSystem/IOHIPointing.cpp
https://stackoverflow.com/questions/44196338/where-is-mouse-cursor-movement

So, I guess the implementation of the main logic of the scroll acceleration can be found in that file IOHIPointing.cpp.
You even find that the pointer (mouse cursor) and (scroll) wheel share the same structure to handle the acceleration:

struct IOHIPointing::ExpansionData
{
    UInt32      scrollType;

    ScrollAccelInfo * scrollWheelInfo;
    ScrollAccelInfo * scrollPointerInfo;
...
}
Comment 29 Albert Zeyer 2017-06-27 09:16:49 UTC
As there are no objections against reopening this (actually no response at all), I'm reopening now.


Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct.