fine grained scrolling via uinput [SOLVED - mostly]

Antoine Martin antoine at nagafix.co.uk
Thu Sep 21 11:57:41 UTC 2017


(snip)

>> And it all seems to work pretty well so far. Applications like Firefox
>> can now scroll a few pixels at a time.
>>
>> Questions:
>> 1) Anything wrong with this approach?
> 
> well. on the face of it, it's fine. but remember, you're not triggering a
> behaviour directly, you're emulating a physical device with specific
> hardware properties that libinput currently treats in a specific way. Keep
> that in mind, as libinput's behaviour may change over time.
Noted.

> amongst other things, you're emulating a wheel which is handled differently
> in libinput than e.g. two-finger scrolling.
For two finger scrolling, we should be able to use a uinput touch
device, this is planned.

Mapping the multi-platform client side API events (X11, win32, macos,
javascript..) into uinput server events is going to be the "fun" part.

>> 2) what is the valid range for MOUSE_WHEEL_CLICK_COUNT?
>> If I set MOUSE_WHEEL_CLICK_COUNT too high, I get:
>> (EE) event19 - (EE) Xpra Virtual Pointer: (EE) mouse wheel click count
>> is present but invalid, using 15 degrees for angle instead instead
>> (and this error is logged twice)
> 
> see evdev_read_wheel_click_count_prop() in libinput/src/evdev.c.
> libinput assumes anything with <1 degre per click as invalid because no such
> devices currently exist (to my knowledge)
>  
>> 3) Despite setting a flat AccelProfile above, "libinput list-devices" shows:
>> Accel profiles:   flat *adaptive
>> What am I doing wrong here?
> 
> from libinput-list-devices(1)
>        An xorg.conf(5) configuration entry or Wayland compositor setting
>        may  have  changed  configurations  on  a device.  The  libinput
>        list-devices tool only shows the device's default configuration, not
>        the current configuration.
The Xorg log shows:
(**) Option "AccelProfile" "flat"
(**) Option "config_info" "udev:/sys/devices/virtual/input/input53/event20"
(II) XINPUT: Adding extended input device "Xpra Virtual Pointer" (type:
MOUSE, id 6)
(**) Option "AccelerationScheme" "none"
(**) Xpra Virtual Pointer: (accel) selected scheme none/0
(**) Xpra Virtual Pointer: (accel) acceleration factor: 2.000
(**) Xpra Virtual Pointer: (accel) acceleration threshold: 4
(..)
Despite requesting "AccelProfile" "flat", it looks like I am getting an
acceleration factor? How can I disable it so that a synthetic REL_X
event with a value X always corresponds to a motion of exactly X pixels?

$ xinput list-props 6
Device 'Xpra Virtual Pointer':
        Device Enabled (114):   1
        Coordinate Transformation Matrix (116): 1.000000, 0.000000,
0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 1.000000
        libinput Accel Speed (244):     0.000000
        libinput Accel Speed Default (245):     0.000000
        libinput Accel Profiles Available (246):        1, 1
        libinput Accel Profile Enabled (247):   0, 1
        libinput Accel Profile Enabled Default (248):   1, 0
(...)

>> 4) the first scroll event is always ignored - what can I do to fix that?
> 
> you can't. it's a long-standing XI2.1 protocol design flaw:
> http://who-t.blogspot.co.at/2012/06/xi-21-protocol-design-issues.html
It's an ugly workaround, but synthesizing a dummy REL_WHEEL event on
startup "fixes" things. (only enabled for XInput version older than 2.2
for now, in the hope that this will change)

>> 5) I tried using a udev hwdb.d rule for setting the click count, but
>> that didn't seem to have any effect:
>> cat > /lib/udev/hwdb.d/71-mouse-xpra.hwdb <<EOF
>> # allow xpra to use smooth scrolling
>> mouse:*:name:Xpra Virtual Pointer:
>>  MOUSE_WHEEL_CLICK_ANGLE=1
>>  MOUSE_WHEEL_CLICK_COUNT=360
>> EOF
>> udevadm hwdb --update
> 
> you did reboot or re-trigger the rules after that?
I thought I did.

>> Does it matter? Any reason to use this rather than the udev rule?
> 
> the effect of using udev rules and hwdb entries is the same. hwdb entries
> are easier to manage when you end up having a lot of them. I don't know
> specifically what's wrong here though, nothing immediately sticks out.
I'll stick with the plain udev rule then.

>> 6) to get the same motion as with an XTest wheel click, I'm having to
>> send REL_WHEEL=+-30, I would have thought it should be 15 instead.
>> Where did I get my maths wrong?
> 
> is that the first scroll event getting swallowed as above?
I don't think so. Will try again.

>> 7) when the uinput device is created, udev will chown it to root:input,
>> is there any way we can tell udev to just leave it alone?
>> We know the uid and gid we want to chown to, and currently we have to
>> wait for udev to do its thing then do what we really want, which is both
>> ugly and racy.
> 
> add a udev rule that sorts high enough and changes the mode. telling udev to
> leave it alone is generally harder than just overriding what it does with a
> higher-sorted rule. this can be part of your exisiting udev rule with
> MODE=...  and GROUP=...
I came up with a really ugly hack to ensure the correct uid is set when
the device is created. Look away now.

I set the "version" attribute of the uinput device to the uid desired,
and udev is configured to use a custom PROGRAM script to set the OWNER,
the script just returns the device version.

Cheers
Antoine

> 
> Cheers,
>    Peter
> 




More information about the xorg-devel mailing list