Bug 97813 - slow mouse movement on bluetooth mouse (but not when connected over USB)
Summary: slow mouse movement on bluetooth mouse (but not when connected over USB)
Status: RESOLVED FIXED
Alias: None
Product: Wayland
Classification: Unclassified
Component: libinput (show other bugs)
Version: unspecified
Hardware: x86-64 (AMD64) Linux (All)
: medium normal
Assignee: Peter Hutterer
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-09-15 07:52 UTC by CircleCode
Modified: 2018-09-04 04:19 UTC (History)
3 users (show)

See Also:
i915 platform:
i915 features:


Attachments
evemu-record output for a 100mm movement on the x axis (bluetooth) (9.36 KB, text/plain)
2016-09-15 07:53 UTC, CircleCode
Details
evemu-record output for a 100mm movement on the x axis (usb) (62.17 KB, text/plain)
2016-09-15 07:55 UTC, CircleCode
Details
gnuplot of the velocity of the pointer from the two recordings (18.35 KB, image/png)
2016-11-03 00:52 UTC, Peter Hutterer
Details
acceleration factor for the two recordings (4.90 KB, image/png)
2016-11-03 00:54 UTC, Peter Hutterer
Details
diff for the debug printf (446 bytes, patch)
2016-11-03 01:06 UTC, Peter Hutterer
Details | Splinter Review
mouse-dpi-tool for usb (1.03 KB, text/plain)
2016-11-03 09:08 UTC, CircleCode
Details
mouse-dpi-tool for bluetooth (1.03 KB, text/plain)
2016-11-03 09:11 UTC, CircleCode
Details
udevadm info -a for the bluetooth device (1.10 KB, text/plain)
2016-11-03 11:29 UTC, CircleCode
Details

Description CircleCode 2016-09-15 07:52:41 UTC
I own a ThinkPad X1 Wireless Touch Mouse (http://shop.lenovo.com/us/en/itemdetails/4X30K40903/460/0E80436C80A748E6AA76791FC42C9CA3),
  connected through bluetooth

the mouse movement on screen is really slow compared to the physical distance.
Comment 1 CircleCode 2016-09-15 07:53:33 UTC
Created attachment 126534 [details]
evemu-record output for a 100mm movement on the x axis (bluetooth)
Comment 2 CircleCode 2016-09-15 07:55:31 UTC
Created attachment 126535 [details]
evemu-record output for a 100mm movement on the x axis (usb)

while connected through the usb dongle, the movement is correct. Here is the evemu-record output for the same movement
Comment 3 Peter Hutterer 2016-09-19 00:14:07 UTC
For the archive and as a reminder to myself: the bluetooth events are 70ms apart, there's a high chance this messes with the acceleration and causes the slow movement
Comment 4 Peter Hutterer 2016-11-02 11:21:52 UTC
somewhat related (and because zubzub just mentioned this on IRC): could there be some interference or otherwise bad reception with the receiver? I'd expect it to be less regular in that case but it may be worth a try
Comment 5 Peter Hutterer 2016-11-03 00:52:20 UTC
Created attachment 127709 [details]
gnuplot of the velocity of the pointer from the two recordings

Augmented the libinput accel code with a printf and then ran gnuplot over it. 
What I printed was timestamps for each event and the calculated velocity in units/ms.

This image shows the two velocities compared, the recordings are roughly the same length over time so it overlays nicely. What you can see clearly is that the velocity when over bluetooth is a fraction of that over USB. This is the cause for the slowness - the mouse simply sends us less mickeys.

btw, it's not caused by any internal timeouts happening because of the 70ms between events, I checked for that.

What happens when you run the mouse-dpi-tool over bluetooth vs usb? What resolution does it show?
Comment 6 Peter Hutterer 2016-11-03 00:54:47 UTC
Created attachment 127710 [details]
acceleration factor for the two recordings

The acceleration factor applied to the motion for the events in the recordings. On the bluetooth (slow) mouse the factor is practically always 1, so no acceleration is applied, the device is too slow to trigger acceleration.
The usb one is maxed out at 2 for a lot of the time or has some factor applied, it's almost never 1. This is a direct consequence of the calculated speed but it amplifies the different feel, the fast movement is accelerated and thus feels even faster, the slow movement isn't and thus feels slower.
Comment 7 Peter Hutterer 2016-11-03 01:06:12 UTC
Created attachment 127711 [details] [review]
diff for the debug printf

This was the printf used, then run against the two evemu recordings. Just storing it here so it's easy to reproduce the data.
Comment 8 CircleCode 2016-11-03 09:08:59 UTC
Created attachment 127714 [details]
mouse-dpi-tool for usb

The covered distance is ~240mm.
This gives
- a covered distance of 8558 units
- a resolution of 905,72
- a frequency of 287.8Hz
Comment 9 CircleCode 2016-11-03 09:11:17 UTC
Created attachment 127715 [details]
mouse-dpi-tool for bluetooth


The covered distance is ~240mm.
This gives
- a covered distance of 1062 units
- a resolution of 112.395
- a frequency of 14.4Hz
Comment 10 Peter Hutterer 2016-11-03 09:33:32 UTC
yep, that would do it. pop this hwdb entry into /etc/udev/hwdb.d/99-x1-mouse.hwdb

mouse:bluetooth:v17efp6088:name:ThinkPad X1 Mouse:
 MOUSE_DPI=120@14

then run sudo udevadm hwdb --update, sudo udevadm test /sys/class/input/event20. Check if the MOUSE_DPI property shows up, if so, restart X and see what changes.
Comment 11 CircleCode 2016-11-03 10:23:28 UTC
the entry is seen by systemd-hwdb query "mouse:bluetooth:v17efp6088:name:ThinkPad X1 Mouse:" but not applied by udevadm test

seems we are facing another bug, currently investigating on it with grawity on irc (#systemd), but I'm afraid it will go beyond my capacities…
Comment 12 CircleCode 2016-11-03 11:29:49 UTC
Created attachment 127716 [details]
udevadm info -a for the bluetooth device

for the archive, investigations showed that ID_BUS is not defined

This is probably related to something in 60-persistent-input.rules, and to the lack of SUBSYSTEMS=="bluetooth" in the output of udevadm info -a

Note: adding an explicit rule
ATTRS{name}=="ThinkPad X1 Mouse", ENV{ID_BUS}="bluetooth", GOTO="persistent_input_end"
to 60-persistent-input.rules
made MOUSE_DPI to appear in the output of udevadm test

Then a restart increased mouse speed (but it is not as fluent as while connected through usb dongle)
Comment 13 Peter Hutterer 2016-11-04 01:26:35 UTC
(In reply to CircleCode from comment #12)
> Created attachment 127716 [details]
> udevadm info -a for the bluetooth device
> 
> for the archive, investigations showed that ID_BUS is not defined
> 
> This is probably related to something in 60-persistent-input.rules, and to
> the lack of SUBSYSTEMS=="bluetooth" in the output of udevadm info -a

please file a bug for that against systemd. this should be fixed there so we don't run into this with other devices. relying on ID_BUS is somewhat important :)


> Note: adding an explicit rule
> ATTRS{name}=="ThinkPad X1 Mouse", ENV{ID_BUS}="bluetooth",
> GOTO="persistent_input_end"
> to 60-persistent-input.rules
> made MOUSE_DPI to appear in the output of udevadm test
> 
> Then a restart increased mouse speed (but it is not as fluent as while
> connected through usb dongle)

Given the huge delay between events, I'm not sure we can do much about that. 70ms is quite big, I can't remember what the delay is where humans notice it, but I'm sure it's below 70ms. out of interest, did you try the evdev driver - does this work better? and have you tried it under windows by any chance?
Comment 14 CircleCode 2016-11-04 09:05:55 UTC
> please file a bug for that against systemd. this should be fixed there so we don't
> run into this with other devices. relying on ID_BUS is somewhat important :)

Done in https://github.com/systemd/systemd/issues/4566

> Given the huge delay between events, I'm not sure we can do much about that. 70ms is quite big,
> I can't remember what the delay is where humans notice it, but I'm sure it's below 70ms.
> out of interest, did you try the evdev driver - does this work better?

Not tried it yet, will give it a try

> and have you tried it under windows by any chance?

yes, it works very fluently under windows 10, so I suppose there is something different there…
Do you know if one can measure something under windows to catch the differences?
Comment 15 Peter Hutterer 2017-01-10 01:21:35 UTC
did the evdev driver work at all? I don't know what you could do under windows to catch the difference, sorry. Short of a USB and bluetooth sniffer anyway.

if the evdev driver works, we know this is a libinput issue, otherwise there isn't much we can do beyond that DPI entry, and that is now in systemd hands.
Comment 16 CircleCode 2017-01-12 10:03:26 UTC
I tried the evdev driver with the following xorg.conf.d file:
--8<-------------------------
Section "InputClass"
        Identifier "X1 mouse"
	MatchProduct "X1"
	Driver "evdev"
EndSection 
------------------------->8--

the results are the following:

- with libinput driver, the command `xinput --list --short` shows `ThinkPad X1 Mouse` under `Virtual core pointer` AND `Virtual core keyboard` (with 2 different ids), while it appears only under `Virtual core pointer` with evdev driver

- with evdev driver, the mouse is quite as slow as with libinput

- with evdev driver, `xinput --list-props` lists a lot of "unknown" buttons

Should I do some more tests?
Comment 17 Peter Hutterer 2017-01-13 01:11:37 UTC
nope, that's all that's needed, thanks. libinput splits devices that have pointer and keyboard capabilities into two X devices (which works around a few bugs in the server). evdev doesn't do that, so having only one device is expected. See bug 92896.

the unknown buttons doesn't matter either, they're just for decorative purposes, I don't think anything uses button labels.


I'm gonna have to close this one as fixed. There is the hwdb entry that at least improves things but with the 70ms delay we can't make it as smooth as on USB. The systemd issue is unrelated to libinput. Beyond that, i don't know what else to do, we simply don't have enough data to make this perfect.

The only option we have is a custom acceleration method with motion prediction for this device, b I don't have the time to implement this. So unless you want to do this yourself, this is as good as we're going to get, sorry.
Comment 18 CircleCode 2017-01-13 07:56:21 UTC
Don't be sorry, it's sad Lenovo did not provide enough information (or better drivers) to make this work correctly under linux.
You spent a lot of time on this issue, including helping and teaching me… thanks
Comment 19 Fabrice Bellet 2018-08-27 10:43:16 UTC
The 70ms delay is caused by the bluetooth low energy mode of this mouse. And it can be lowered by reducing the min and max LE connection parameters with "hcitool lecup".
Comment 20 CircleCode 2018-08-28 06:43:06 UTC
As I am not at al a bluetooth expert, I wonder if these parameters can have other side effects (if I understand it correctly, they are applied system-wide)

And as a side question, it seems hcitool is deprecated, so is there another way to achieve the same result?

Last question, for my understanding: what exactly do these parameters?
Comment 21 Fabrice Bellet 2018-09-03 13:26:03 UTC
I'm not a bluetooth expert too, I simply noticed that these parameters solved a similar issue on a completely unrelated bluetooth device, that only shared the characteristic to be a "low energy" device too:

https://github.com/IanHarvey/bluepy/issues/117

My understanding of these min/max values is that they define a fixed rate, used by low energy bluetooth to exchange data, allowing the hardware to enter power saving mode between communications, instead of being always on.

I think these params are specific to a connection, via the handle value.
Comment 22 Peter Hutterer 2018-09-04 04:19:09 UTC
there are several options here for libinput to handle this when detected:
- issue a warning in the log to point to documentation on how to resolve this using the hcitool (or writing to the sysfs files). This is the easiest one to add
- change the connection details itself by writing to the sysfs files. This could be an issue because we may not have write access
- change the connection details by monitoring/writing to the bluez DBus interface. This is the most complex issue because it'd require dbus handling inside libinput which we don't have yet

I think even the first one (log + docs) would be very useful and I'd really appreciate a patch to that extent. Unfortunately I don't have a device to reproduce this here, so I'll rely on you to test the exact sequences of steps.

If you're interested, please open a new issue here: https://gitlab.freedesktop.org/libinput/libinput/issues


Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.