setting up a gaming mouse on linux

motivation

If you play many games then you might be used to a certain feel when moving the mouse around. For me, after playing lots of fps games, that was a low sensitivity without any mouse acceleration. Over time I eventually made my sensitivity when not playing games mimic this as my muscle memory was most used to this type of movement.

After switching to linux there was no longer the windows menu which had the slider and the option to turn off mouse acceleration. So I had to figure out how to do it manually instead

how to do it

First I'll introduce two scripts which allow you dynamically remove or change sensitivity on a mouse of your choosing.

We need to understand how xinput works:
    
        [ccn@ccn-desktop mouse-settings]$ xinput
        ⎡ Virtual core pointer                    	id=2	[master pointer  (3)]
        ⎜   ↳ Virtual core XTEST pointer              	id=4	[slave  pointer  (2)]
        ⎜   ↳ BenQ ZOWIE BenQ ZOWIE Gaming Mouse      	id=11	[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)]
            ↳ Power Button                            	id=7	[slave  keyboard (3)]
            ↳ USB Keyboard System Control             	id=10	[slave  keyboard (3)]
            ↳ USB Keyboard Consumer Control           	id=9	[slave  keyboard (3)]
            ↳ USB Keyboard                            	id=8	[slave  keyboard (3)]
    

Then familiarize ourselves with the properties associated with the zowie gaming mouse

    
        [ccn@ccn-desktop mouse-settings]$ xinput --list-props 11
        Device 'BenQ ZOWIE BenQ ZOWIE Gaming Mouse':
            Device Enabled (154):	1
            Coordinate Transformation Matrix (156):	0.750000, 0.000000, 0.000000, 0.000000,
                                                                    0.750000, 0.000000, 0.000000, 0.000000, 1.000000
            libinput Natural Scrolling Enabled (290):	0
            libinput Natural Scrolling Enabled Default (291):	0
            libinput Scroll Methods Available (292):	0, 0, 1
            libinput Scroll Method Enabled (293):	0, 0, 0
            libinput Scroll Method Enabled Default (294):	0, 0, 0
            libinput Button Scrolling Button (295):	2
            libinput Button Scrolling Button Default (296):	2
            libinput Button Scrolling Button Lock Enabled (297):	0
            libinput Button Scrolling Button Lock Enabled Default (298):	0
            libinput Middle Emulation Enabled (299):	0
            libinput Middle Emulation Enabled Default (300):	0
            libinput Accel Speed (301):	0.000000
            libinput Accel Speed Default (302):	0.000000
            libinput Accel Profiles Available (303):	1, 1
            libinput Accel Profile Enabled (304):	0, 1
            libinput Accel Profile Enabled Default (305):	1, 0
            libinput Left Handed Enabled (306):	0
            libinput Left Handed Enabled Default (307):	0
            libinput Send Events Modes Available (275):	1, 0
            libinput Send Events Mode Enabled (276):	0, 0
            libinput Send Events Mode Enabled Default (277):	0, 0
            Device Node (278):	"/dev/input/event5"
            Device Product ID (279):	1189, 32769
            libinput Drag Lock Buttons (308):	
            libinput Horizontal Scroll Enabled (309):	1
            libinput Scrolling Pixel Distance (310):	15
            libinput Scrolling Pixel Distance Default (311):	15
    

This mouse has already been configured, but the two properties that were of interest to me were "libinput Accel Profile Enabled" and "Coordinate Transformation Matrix", I know this is what I need because I already researched and tested different properties to find the correct ones. The main sources were ubuntu's resource on the matrix and waylands docs for acceleration profiles.

So to build a script to enable the flat acceleration profile, we can do this

mouse_accel.sh
    
        #!/usr/bin/env bash
        # https://wayland.freedesktop.org/libinput/doc/latest/pointer-acceleration.html#the-flat-pointer-acceleration-profile
        xinput --list
        read -p "Which of the above devices would you like to disable mouse sensivity on? (give the id number)" id
        echo    # (optional) move to a new line
        xinput --set-prop $id 'libinput Accel Profile Enabled' 0, 1
    

So to build a script to change our mouse sensitivity we can build

mouse_sens.sh
    
        #!/usr/bin/env bash
        xinput --list
        read -p "Which of the above devices would you like to change the mouse sensitivity? (give the id number)" id
        echo    # (optional) move to a new line
        read -p "What would you like to change your mouse sensivity to?" sens
        # Add a scalar multiplier to the matrix
        xinput set-prop $id "Coordinate Transformation Matrix" $sens 0 0 0 $sens 0 0 0 1
    

So then a sample session with these two scripts could look like:

    
        [ccn@ccn-desktop mouse-settings]$ ./mouse_accel.sh
        ⎡ Virtual core pointer                    	id=2	[master pointer  (3)]
        ⎜   ↳ Virtual core XTEST pointer              	id=4	[slave  pointer  (2)]
        ⎜   ↳ BenQ ZOWIE BenQ ZOWIE Gaming Mouse      	id=11	[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)]
            ↳ Power Button                            	id=7	[slave  keyboard (3)]
            ↳ USB Keyboard System Control             	id=10	[slave  keyboard (3)]
            ↳ USB Keyboard Consumer Control           	id=9	[slave  keyboard (3)]
            ↳ USB Keyboard                            	id=8	[slave  keyboard (3)]
        Which of the above devices would you like to disable mouse sensivity on? (give the id number)11

        [ccn@ccn-desktop mouse-settings]$ ./mouse_sens.sh
        ⎡ Virtual core pointer                    	id=2	[master pointer  (3)]
        ⎜   ↳ Virtual core XTEST pointer              	id=4	[slave  pointer  (2)]
        ⎜   ↳ BenQ ZOWIE BenQ ZOWIE Gaming Mouse      	id=11	[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)]
            ↳ Power Button                            	id=7	[slave  keyboard (3)]
            ↳ USB Keyboard System Control             	id=10	[slave  keyboard (3)]
            ↳ USB Keyboard Consumer Control           	id=9	[slave  keyboard (3)]
            ↳ USB Keyboard                            	id=8	[slave  keyboard (3)]
        Which of the above devices would you like to change the mouse sensitivity? (give the id number)11

        What would you like to change your mouse sensivity to?0.75
    

optimizing

These scripts are good for tweaking your sensitivity to find the correct one, but once you have the right sensitivity there is really no need for a dynamic script anymore. For me I built the following script to reduce the amount of time I have to spend tweaking my mouse settings.

setup_zowie_gaming_mouse.sh
    
        #!/usr/bin/env bash
        # https://wayland.freedesktop.org/libinput/doc/latest/pointer-acceleration.html#the-flat-pointer-acceleration-profile
        xinput --set-prop 'BenQ ZOWIE BenQ ZOWIE Gaming Mouse' 'libinput Accel Profile Enabled' 0, 1
        xinput set-prop 'BenQ ZOWIE BenQ ZOWIE Gaming Mouse'  "Coordinate Transformation Matrix" 0.75 0 0 0 0.75 0 0 0 1
    

Notice that here I don't use the id but instead the actual name of the mouse (as listed by xinput). I do this because the id's may change based on the number of things you have plugged into your usb slots.

Still this isn't perfect because when you restart your pc the settings don't save. There are multiple ways to deal with this, but probably the most simple is to tack this script on to your scripts that you run at start, depending on your desktop environment/window manager there will be different ways to get this to work. I use xfce4, so in the autostart settings I have a script which is always run, called autostart.sh, then at the bottom of that file I just have to run my mouse setup.

autostart.sh
    
        #!/bin/bash
        sh ~/basic-system/shell-progs/switch_escape_and_caps.sh
        sh ~/basic-system/shell-progs/switch_menu_key_to_super.sh
        sh ~/basic-system/mouse-settings/setup_zowie_gaming_mouse.sh
    

comments section