Setting individual mouse pointer speeds in Linux with micetune

This post is about micetune, a Python script I wrote for setting individual pointer speeds for different mouse devices in Linux, with the ability to reduce the speed beyond what the control center setting allows. The script changes the real pointer speed without involving acceleration.

Note that I boosted the trackpoint speed individually with a Thinkpad specific tweak in this post, which is unrelated to this.


I use a couple of pointing devices with my laptop, such as the built-in trackpoint and touchpad, and various USB mouse devices when docked in docking stations. Some of the devices are faster than others and it quickly became a problem to find a single pointer speed setting to rule them all.

This is what I get in the Mouse Preferences in Linux Mint 18 Mate:

Mouse speed set to slowest in Mint 18

The other problem is that even with the lowest speed setting, as seen above, even simple non-gamer USB mouse devices move very fast. Too fast for my liking.

So, I went looking for ways to set the pointer speed with a bigger range and with seperate values for different pointing devices.. and came up short.

After a bit of research and experimentation, I decided that the way to go was to adjust the "Coordinate Transformation Matrix" of pointer devices with xinput. But since the id numbers used by xinput to identify devices weren't always the same, there was no way around scripting something to solve this once and for all.


.. is a Python script that works by running and analysing the output of xinput --list to identify the pointer devices currently available, and then setting the desired speeds according to configuration values.

The script is available on Github

Download it, make it executable and place it in a path directory, like for example: /usr/bin/micetune

First run micetune list, which will show the output of xinput --list. All the "slave pointer" devices should be identified by the script as seen below:

$ micetune list
This is the output from: 'xinput --list'

⎡ Virtual core pointer                      id=2    [master pointer  (3)]
⎜   ↳ Virtual core XTEST pointer                id=4    [slave  pointer  (2)]
⎜   ↳ Lenovo USB Receiver                       id=10   [slave  pointer  (2)]
⎜   ↳ Lenovo USB Receiver                       id=11   [slave  pointer  (2)]
⎜   ↳ SynPS/2 Synaptics TouchPad                id=14   [slave  pointer  (2)]
⎜   ↳ TPPS/2 IBM TrackPoint                     id=15   [slave  pointer  (2)]
⎜   ↳ Logitech M505/B605                        id=18   [slave  pointer  (2)]
⎣ Virtual core keyboard                     id=3    [master keyboard (2)]
    ↳ Virtual core XTEST keyboard               id=5    [slave  keyboard (3)]
    ↳ Power Button                              id=6    [slave  keyboard (3)]
    ↳ Video Bus                                 id=7    [slave  keyboard (3)]
    ↳ Sleep Button                              id=8    [slave  keyboard (3)]
    ↳ Lenovo USB Receiver                       id=9    [slave  keyboard (3)]
    ↳ CHICONY USB NetVista Full Width Keyboard  id=12   [slave  keyboard (3)]
    ↳ AT Translated Set 2 keyboard              id=13   [slave  keyboard (3)]
    ↳ ThinkPad Extra Buttons                    id=16   [slave  keyboard (3)]
    ↳ Integrated Camera                         id=17   [slave  keyboard (3)]

Pointer devices identified:
'Virtual core XTEST pointer'
'Lenovo USB Receiver'
'Lenovo USB Receiver'
'SynPS/2 Synaptics TouchPad'
'TPPS/2 IBM TrackPoint'
'Logitech M505/B605'

Script configuration:
'Lenovo USB Receiver' = 0.750000
'Logitech M505/B605' = 0.700000
'Logitech M315/M235' = 1.200000

The configuration is set in the beginning of the script and should be adjusted manually. This is how my script is configured:

# Speed value examples:
#   0.5  :  Half pointer speed
#   1    :  Unchanged pointer speed
#   1.5  :  150% pointer speed

speeds = {
u'Lenovo USB Receiver': 0.75,
u'Logitech M315/M235': 1.2,
u'Logitech M505/B605': 0.7

Now try running micetune test:

$ micetune test
xinput --set-prop 10 'Coordinate Transformation Matrix' 1.0 0.0 0.0  0.0 1.0 0.0  0.0 0.0 1.333333
xinput --set-prop 11 'Coordinate Transformation Matrix' 1.0 0.0 0.0  0.0 1.0 0.0  0.0 0.0 1.333333
xinput --set-prop 18 'Coordinate Transformation Matrix' 1.0 0.0 0.0  0.0 1.0 0.0  0.0 0.0 1.428571

Those are the actual commands micetune intends to run. Device number 10 and 11 match the "Lenovo USB Receiver" and will be set to a 0.75 relative speed by setting 1/0.75 = 1.3333 in the transformation matrix. Device 18 matches "Logitech M505/B605" and is similarly adjusted.

Now, to run the commands shown in the test run above, run:

$ micetune run

Making the script run automatically

Ideally, the script should run automatically everytime new devices are plugged in. I haven't bothered with that so far, I just made the script run at system startup which has been good enough in most cases. If necessary to run the script again, I'd just run micetune run in a terminal.

I made the script run at system startup using this nifty tool:

Add micetune as startup program

It popped up in the start menu after searching for "startup" and seems to be a Mate thing. It works fine.


Comments powered by Talkyard