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)
So, what would be the correct procedure for mice with switchable dpi?ReplyDelete
I am assuming it's to provide the lowest value, or whatever the device defaults to once it's powered on.
@yOSHi314: More specific instructions about multi-resolution mices are here:ReplyDelete
I really, really hope that acceleration will be optional. I can't stand it, and always disable it on my Windows computers.ReplyDelete
I agree about disabling acceleration. Since my mouse can go to Philae if I sneeze, I don't need or want accel. :-)ReplyDelete
Are the reasons why this in some cases will not work?ReplyDelete
I identified my mouse to be event20 with "ls -l /dev/input/by-id". I ran the mouse-dpi-tool. Put the last two lines into /etc/udev/hwdb.d/71-mouse.hwdb with the correct dpi. Second line needs to start with whitespace otherwise hwdb update fails? I get "Error, DATA expected but got empty line in '/etc/udev/hwdb.d/71-mouse.hwdb':" if it doesn't start with whitespace. Ran the hwdb --update. "sudo udevadm trigger /dev/input/event20" doesn't work "Extraneous argument: '/dev/input/event20'" Just running trigger works. MOUSE_DPI doesn't show up in udevadm info for event20. Rebooted, still nothing.
Karl: if the trigger command doesn't work, you don't have an up-to-date systemd which means you probably don't have the hwdb set up yet. If you manually put the rules/hwdb files in, just use udevadm trigger without any arguments.ReplyDelete
I used the mouse-dpi-tool on my mouse, which is a wireless Logitech M705 with a "unifying receiver" that supports many different Logitech devices. The rule it produces looks like this:ReplyDelete
mouse:usb:v046dpc52b:name:Logitech Unifying Device. Wireless PID:101b:
I'm guessing the vid/pid in this rule is for the unifying receiver itself though -- so this rule will be useless, because someone can have the same unifying receiver with a different mouse attached.
I wonder if there is any way udev can match the specific mouse attached to the receiver?
djc: I forgot to mention this: that's going to be fixed in 3.18 when it will be reliable. I'll amend that asapReplyDelete
I'm using systemd 217 on Arch Linux, which I belive is the latest stable version. Do I need the development version?
@Peter: I've got one of those switchable gaming mice, and DPI switching works just fine since I got it over a year ago - so what would improve when I submit the measurements to udev hwdb? Is it only about changing the acceleration, too?ReplyDelete
Karl: from the post "And to do that we need a database, which will be provided by udev as of systemd 218 (unreleased at the time of writing). "ReplyDelete
Florian: on switchable mice the default resolution must be marked, that's the one libinput picks and normalizes to 1000dpi. because we can't detect dpi changes at runtime, all other resolutions will be relatively faster or slower than that default one. That default one will now have acceleration applied to properly. But given that the default is likely to be around 1000dpi I doubt you'll see any changes anyway :)
djc: sorry got the kernel versions wrong: it's fixed in 3.19, not 3.18, so we'll need double entries for all these devices (with the wireless PID in the name and the fixed one for 3.19)ReplyDelete
Peter: If we want to gather a reasonable mouse properties database, that detection tool needs to be available pre-compiled. Most people don't know how to compile it or are too lazy to do it (myself included), but would happily provide the data if the tool could easily be downloaded and run (either standalone or as a part of some RPM package). Do you consider providing that? Thanks.ReplyDelete
kparal: it's already part of the libevdev-utils package in Fedora 21 and rawhide. Please get your distribution to ship it (I suspect they will anyway once the update to libevdev 1.3.2)ReplyDelete
This is a great step in the right direction. It really lends itself to trying to set the mouse to the highest DPI by default (someday), and then normalizing the pointer speed/acceleration to adjust for the increased DPI. The increased precision from having a higher DPI makes a noticeable difference for users that lower or disable acceleration.ReplyDelete
Have you considered fully automating the submission process? The database would probably grow much more quickly if users can submit information without having to file a bug.
Unfortunately, the amount of effort to make this automatic and useful for everyone is well beyond the time I have available.ReplyDelete
Peter Hutterer: Yeah, I use Fedora. It would be a good idea to mention the fact that mouse-dpi-tool is a part of libevdev-utils in the blog post itself. That simplifies things a lot for people not familiar with this area.ReplyDelete
Could you explain me how the measurement is done.
As far as I understand, I have to move the mouse, measure the distance on my screen (in centimeters), divide it by the "Covered distance in device units" and match that number with the second columns.
What the first column, stands for ?
What if the number obtained doesn't match exactly with a number in the second column ?
lecbee: you need to measure the distance covered by the mouse on the table, not on the screen.ReplyDelete
say you move 5 inches, find the line that says 5in in the second column and the third value is your DPI. You don't need to calculate anything at all.
The first number is mm, second in inches, but they're the same value (US vs rest of the world). if you measure in inches, ignore the first column.
If you can't find a matching DPI value, simply divide the units counted by the number of inches you moved and that's it.
The mouse-dpi-tool always reports zero units for me. Running as root, under Xorg and VT, fedora libevdev-devel package and compiled from source. Always the same results.ReplyDelete
# mouse-dpi-tool /dev/input/event6
Mouse AlpsPS/2 ALPS DualPoint TouchPad on /dev/input/event6
Move the device along the x-axis.
Pause 3 seconds before movement to reset, Ctrl+C to exit.
Covered distance in device units: 0 at frequency 142.9Hz \^C
Estimated sampling frequency: 142Hz
To calculate resolution, measure physical distance covered
and look up the matching resolution in the table below
0mm 0.00in 400dpi
0mm 0.00in 600dpi
0mm 0.00in 800dpi
0mm 0.00in 1000dpi
0mm 0.00in 1200dpi
0mm 0.00in 1400dpi
0mm 0.00in 1600dpi
0mm 0.00in 1800dpi
0mm 0.00in 2000dpi
0mm 0.00in 2200dpi
0mm 0.00in 2400dpi
Entry for hwdb match (replace XXX with the resolution in DPI):
mouse:unknown bus type:v0002p0008:name:AlpsPS/2 ALPS DualPoint TouchPad:
Jacek: that's a touchpad, not a mouse. The tool only works on relative devices, touchpads usually supply us with the information through the firmware anyway.ReplyDelete
I thought that it also needs the resolution info since two finger scrolling is overly sensitive under libinput. Maybe firmware reports wrong info. Is there any way to query the data?ReplyDelete
Jacek: yeah, check with evtest or evemu-describe, grep for Resolution. if you think it's off, best to file a bugReplyDelete
Would you please consider using modern metric units instead of inches? I think a pitch would make more sense too, so the database should specify how many millimeters per mickey instead of how many mickeys per inch.ReplyDelete
ecloud: all manufacturers advertise as DPI. The effort of going against that is not worth the gain.ReplyDelete
What to report if I don't get an exact value, like 882 DPI or so ?ReplyDelete
Also, with the same mouse, sometimes mouse-dpi-tools is in 125 Hz and other time in 142 Hz.
lecbee: check with the HW manufacturer first if they have an advertised rating. Also test on multiple surfaces, not all provide the best scanning conditions.ReplyDelete
Same with the frequency, many mice have dynamic frequency scaling so use the highest one you can find.
Couldn't find out how to assign the bug to you. The bug and a patch are here:
I'm trying to add an entry for the Apple MagicMouse. I run the mouse-dpi-tool and at the end it gives meReplyDelete
I've tried adding that as a rule, with or without the name, as obviously a more generic entry shouldn't contain it. But no matter it doesn't apply when I call udev trigger. I've tried doing the same to an old usb mouse I had lying around, and it works there. Not sure what I'm doing wrong here, so any advice would be appreciated.
Most gaming mice are programmable, i.e. their DPI sensitivity settings can be changed. So for those, this database might do more harm than good as far as I understand it...ReplyDelete
Who use this gaming mouse for World of warcraft? It is good or not?ReplyDelete