Discussion:
Best way to achieve very slow pointer motion? (for accessibility)
Colomban Wendling
2018-11-27 10:25:05 UTC
Permalink
Hello,

I'm working on the MATE desktop environment to try and enhance the
pointer speed user setting to allow for a very slow pointer to better
fit accessibility for people with limited motor abilities (motor
deficiencies, some elderly, etc.).

Currently, MATE is providing a setting controlling libinput's "Accel
Speed" (through the libinput X driver, which allows values in the range
[-1, 1]). This is nice and works well for most users, but is not nearly
enough to slow the mouse to the kind of levels we're talking about for
accessibility.
Note that I am *not* saying that the mouse speed, DPI or whatnot is
incorrect, just that I need to be able to *also* reach slower speeds,
while still allowing the current ones.

The question here is what is the recommended way to achieve
lower-than-normal pointer speeds? I found a few candidates, but would
like input on what is a sensible way to go, balancing what libinput
provides and a simple and powerful enough user setting:

* Use the "flat" acceleration profile for slow mode
- This works fairly well and allows for very low pointer speeds.
- The main question is: is there a sensible way to know the rough
equivalence point between the "adaptive" and "flat" profiles, so it
could be switched automatically on low value of a single "pointer speed"
setting? The idea is that we'd like to have a setting as simple as
possible yet providing sensible results for typical use cases. Ideally,
we'd have single slider controlling pointer speed that would just do the
Right Thing.

* Modifying libinput to allow for values of "Accel Speed" lower than -1
- Requires changing libinput and/or the libinput X driver (?)
- Requires using that newer version

* Kind of OT on this ML, but using the "Coordinate Transformation
Matrix" setting (which I don't think comes from libinput, but I'm not
sure yet)
- It does the job, but:
- it is trickier to use
- it isn't designed for this
- it seems to cause issues on some corner case setups (e.g. certain
Wine apps)
- it might conflict with more legitimate use of the feature, like
automatic touchscreen/tablet rotation, etc.

Are there other, more appropriate options?
Basically, what I'd like to achieve is similar to being able to set the
"Accel Speed" to a value way under -1. If there are no better options,
I can consider adding a "enable pointer acceleration" user setting which
would control whether the "adaptive" or "flat" profile is used, but I'd
like to avoid it if possible to keep the user setting simple and
understandable.

Thanks for your input,
Colomban
Peter Hutterer
2018-11-28 01:15:51 UTC
Permalink
Post by Colomban Wendling
Hello,
I'm working on the MATE desktop environment to try and enhance the
pointer speed user setting to allow for a very slow pointer to better
fit accessibility for people with limited motor abilities (motor
deficiencies, some elderly, etc.).
Currently, MATE is providing a setting controlling libinput's "Accel
Speed" (through the libinput X driver, which allows values in the range
[-1, 1]). This is nice and works well for most users, but is not nearly
enough to slow the mouse to the kind of levels we're talking about for
accessibility.
Note that I am *not* saying that the mouse speed, DPI or whatnot is
incorrect, just that I need to be able to *also* reach slower speeds,
while still allowing the current ones.
The question here is what is the recommended way to achieve
lower-than-normal pointer speeds? I found a few candidates, but would
like input on what is a sensible way to go, balancing what libinput
* Use the "flat" acceleration profile for slow mode
- This works fairly well and allows for very low pointer speeds.
- The main question is: is there a sensible way to know the rough
equivalence point between the "adaptive" and "flat" profiles, so it
could be switched automatically on low value of a single "pointer speed"
setting? The idea is that we'd like to have a setting as simple as
possible yet providing sensible results for typical use cases. Ideally,
we'd have single slider controlling pointer speed that would just do the
Right Thing.
There's no equivalence point as such, both are implementation-defined and
can be device-specific. You could figure it quite easily out using the
libinput sources, but it's bound to change at any time.
Post by Colomban Wendling
* Modifying libinput to allow for values of "Accel Speed" lower than -1
- Requires changing libinput and/or the libinput X driver (?)
- Requires using that newer version
* Kind of OT on this ML, but using the "Coordinate Transformation
Matrix" setting (which I don't think comes from libinput, but I'm not
sure yet)
- it is trickier to use
- it isn't designed for this
- it seems to cause issues on some corner case setups (e.g. certain
Wine apps)
- it might conflict with more legitimate use of the feature, like
automatic touchscreen/tablet rotation, etc.
fwiw, the matrix is handled by the server, it's not driver-specific. And
yes, it will likely conflict with some rotation but that's still a fairly
niche use-case. And afaik very few relative devices use the matrix anyway
and for your use-case touchscreens don't matter.
Post by Colomban Wendling
Are there other, more appropriate options?
Basically, what I'd like to achieve is similar to being able to set the
"Accel Speed" to a value way under -1. If there are no better options,
I can consider adding a "enable pointer acceleration" user setting which
would control whether the "adaptive" or "flat" profile is used, but I'd
like to avoid it if possible to keep the user setting simple and
understandable.
Honestly, I think you're going about it the wrong way. You want an
accessibility feature and you're looking for hacks and knobs that you can
(ab)use to get the result you want.

The side-effect of this is that you make life miserable for both sides. Any
change in libinput could break whatever knobs you find and you're forcing
libinput to maintain behaviour that wasn't intended to work this way,
possibly blocking improvements.

You should be looking at it this way: how do I get this *feature* into the
compositor. libinput's purpose is to abstract the hardware but there are
several things it leaves to the compositor and the toolkits. This would be
one of them. Pointer slowdown can easily be handled by the compositor since
it already controls the pointer position (libinput merely provides
suggested relative deltas). Figure out what other features you'd need and
how to integrate them. And *integrate* them.

Cheers,
Peter

PS: yes, obviously this is dependend on Wayland because in X the server
controls the pointer and you're mostly out of luck.
Colomban Wendling
2018-11-28 15:14:43 UTC
Permalink
Post by Peter Hutterer
Post by Colomban Wendling
[…]
* Use the "flat" acceleration profile for slow mode
- This works fairly well and allows for very low pointer speeds.
- The main question is: is there a sensible way to know the rough
equivalence point between the "adaptive" and "flat" profiles, so it
could be switched automatically on low value of a single "pointer speed"
setting? The idea is that we'd like to have a setting as simple as
possible yet providing sensible results for typical use cases. Ideally,
we'd have single slider controlling pointer speed that would just do the
Right Thing.
There's no equivalence point as such, both are implementation-defined and
can be device-specific. You could figure it quite easily out using the
libinput sources, but it's bound to change at any time.
That's what I though, having seen the acceleration functions graphs.
Post by Peter Hutterer
fwiw, the matrix is handled by the server, it's not driver-specific. And
yes, it will likely conflict with some rotation but that's still a fairly
niche use-case. And afaik very few relative devices use the matrix anyway
and for your use-case touchscreens don't matter.
But as you say below, that would clearly be abusing a feature, and a
tricky at that even.
Post by Peter Hutterer
Post by Colomban Wendling
Are there other, more appropriate options?
Basically, what I'd like to achieve is similar to being able to set the
"Accel Speed" to a value way under -1. If there are no better options,
I can consider adding a "enable pointer acceleration" user setting which
would control whether the "adaptive" or "flat" profile is used, but I'd
like to avoid it if possible to keep the user setting simple and
understandable.
Honestly, I think you're going about it the wrong way. You want an
accessibility feature and you're looking for hacks and knobs that you can
(ab)use to get the result you want.
The side-effect of this is that you make life miserable for both sides. Any
change in libinput could break whatever knobs you find and you're forcing
libinput to maintain behaviour that wasn't intended to work this way,
possibly blocking improvements.
That's the reason I'm asking: because I don't feel great about the
current options I found.
Post by Peter Hutterer
You should be looking at it this way: how do I get this *feature* into the
compositor. libinput's purpose is to abstract the hardware but there are
several things it leaves to the compositor and the toolkits. This would be
one of them. Pointer slowdown can easily be handled by the compositor since
it already controls the pointer position (libinput merely provides
suggested relative deltas). Figure out what other features you'd need and
how to integrate them. And *integrate* them.
Ok yeah that makes sense, which was more or less the intent of my second
proposition of modifying libinput. But I indeed slightly misunderstood
the Accel Speed setting, and kind of what is or isn't libinput's to handle.
Now I read your post, I have to agree that something at a higher level
than libinput can do what I need, and then just might be a better place
for it.

Unfortunately, due to the current state of things, I cannot reasonably
expect to be able to rely on Wayland soon; there is work going on to get
MATE to work with it, but it's definitely not gonna be in any kind of
usable state soon. So I would need a solution working under X -- but if
this isn't a generic solution, ultimately I'd need a Wayland solution as
well.
Post by Peter Hutterer
PS: yes, obviously this is dependend on Wayland because in X the server
controls the pointer and you're mostly out of luck.
Well, this "only" suggests I would need a way to do that with X in the
meantime. What about a multiplication factor in xf86-input-libinput?
Older/other input drivers used to provide things like "Device Accel
Constant Deceleration"/"Device Accel Adaptive Deceleration", and
although I'm not really sure what they technically do, they provide
something that works for the use-case at hand -- but yeah, I might be
abusing something again.

Would such a parameter be acceptable for X, or could you point me to a
better place for this if not?

Thank you,
Colomban

Loading...