click here to jump to the instructions
Mice have an optical sensor that tells them how far they moved in "mickeys". Depending on the sensor, a mickey is anywhere between 1/100 to 1/8200 of an inch or less. The current "standard" resolution is 1000 DPI, but older mice will have 800 DPI, 400 DPI etc. Resolutions above 1200 DPI are generally reserved for gaming mice with (usually) switchable resolution and it's an arms race between manufacturers in who can advertise higher numbers.
HW manufacturers are cheap bastards so of course the mice don't advertise the sensor resolution. Which means that for the purpose of pointer acceleration there is no physical reference. That delta of 10 could be a millimeter of mouse movement or a nanometer, you just can't know. And if pointer acceleration works on input without reference, it becomes useless and unpredictable. That is partially intended, HW manufacturers advertise that a lower resolution will provide more precision while sniping and a higher resolution means faster turns while running around doing rocket jumps. I personally don't think that there's much difference between 5000 and 8000 DPI anymore, the mouse is so sensitive that if you sneeze your pointer ends up next to Philae. But then again, who am I to argue with marketing types.
For us, useless and unpredictable is bad, especially in the use-case of everyday desktops. To work around that, libinput 0.7 now incorporates the physical resolution into pointer acceleration. And to do that we need a database, which will be provided by udev as of systemd 218 (unreleased at the time of writing). This database incorporates the various devices and their physical resolution, together with their sampling rate. udev sets the resolution as the MOUSE_DPI property that we can read in libinput and use as reference point in the pointer accel code. In the simplest case, the entry lists a single resolution with a single frequency (e.g. "MOUSE_DPI=1000@125"), for switchable gaming mice it lists a list of resolutions with frequencies and marks the default with an asterisk ("MOUSE_DPI=400@50 800@50 *1000@125 1200@125"). And you can and should help us populate the database so it gets useful really quickly.
How to add your device to the database
We use udev's hwdb for the database list. The upstream file is in /usr/lib/udev/hwdb.d/70-mouse.hwdb, the ruleset to trigger a match is in /usr/lib/udev/rules.d/70-mouse.rules. The easiest way to add a match is with the libevdev mouse-dpi-tool (version 1.3.2). Run it and follow the instructions. The output looks like this:
$ sudo ./tools/mouse-dpi-tool /dev/input/event8 Mouse Lenovo Optical USB Mouse on /dev/input/event8 Move the device along the x-axis. Pause 3 seconds before movement to reset, Ctrl+C to exit. Covered distance in device units: 264 at frequency 125.0Hz | |^C Estimated sampling frequency: 125Hz To calculate resolution, measure physical distance covered and look up the matching resolution in the table below 16mm 0.66in 400dpi 11mm 0.44in 600dpi 8mm 0.33in 800dpi 6mm 0.26in 1000dpi 5mm 0.22in 1200dpi 4mm 0.19in 1400dpi 4mm 0.17in 1600dpi 3mm 0.15in 1800dpi 3mm 0.13in 2000dpi 3mm 0.12in 2200dpi 2mm 0.11in 2400dpi Entry for hwdb match (replace XXX with the resolution in DPI): mouse:usb:v17efp6019:name:Lenovo Optical USB Mouse: MOUSE_DPI=XXX@125Take those last two lines, add them to a local new file /etc/udev/hwdb.d/71-mouse.hwdb. Rebuild the hwdb, trigger it, and done:
$ sudo udevadm hwdb --update $ sudo udevadm trigger /dev/input/event8Leave out the device path if you're not on systemd 218 yet. Check if the property is set:
$ udevadm info /dev/input/event8 | grep MOUSE_DPI E: MOUSE_DPI=1000@125And that shows everything worked. Restart X/Wayland/whatever uses libinput and you're good to go. If it works, double-check the upstream instructions, then file a bug against systemd with those two lines and assign it to me.
Trackballs are a bit hard to measure like this, my suggestion is to check the manufacturer's website first for any resolution data.
Update 2014/12/06: trackball comment added, udevadm trigger comment for pre 218
Update 2015/08/26: udpated link to systemd bugzilla (now on github)