Some desktop environments (DE) combined with various window managers (WM) can achieve quite a bit of functionality with input from the mouse, however it might not cover that one obscure setting we might want to change. In my case I use Logitech M510 mice on all of my machines, but rather than using the browse "forward" and "back" buttons (the buttons by the thumb) to browse the Internet, I prefer to use them for the middle mouse button. When I spend an hour or more modelling in Blender my middle finger will get sore otherwise. To make this change, I need to configure the X device itself using the "xinput" command.
I first need to find the device we want to work with, in this case my Logitech M510 mouse. This can be done by first listing all of the X devices using the xinput command as follows:
$ xinput
⎡ Virtual core pointer id=2 [master pointer (3)]
⎜ ↳ Virtual core XTEST pointer id=4 [slave pointer (2)]
⎜ ↳ Microsoft Natural® Ergonomic Keyboard 4000 id=11 [slave pointer (2)]
⎜ ↳ Logitech Unifying Device. Wireless PID:1025 id=12 [slave pointer (2)]
⎜ ↳ SynPS/2 Synaptics TouchPad id=15 [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)]
↳ Power Button id=8 [slave keyboard (3)]
↳ Sleep Button id=9 [slave keyboard (3)]
↳ Microsoft Natural® Ergonomic Keyboard 4000 id=10 [slave keyboard (3)]
↳ BisonCam, NB Pro id=13 [slave keyboard (3)]
↳ AT Translated Set 2 keyboard id=14 [slave keyboard (3)]
Make special note that my mouse is under the Virtual core pointer and the point at which it is connected to the computer (via USB) as X device id=12. Not that we need it, but because it is nice to know, if we needed more details of the device we would do the following (where 12 is the X device ID):
$ xinput list 12
Logitech Unifying Device. Wireless PID:1025 id=12 [slave pointer (2)]
Reporting 7 classes:
Class originated from: 12. Type: XIButtonClass
Buttons supported: 24
Button labels: "Button Left" "Button Middle" "Button Right" "Button Wheel Up" "Button Wheel Down" "Button Horiz Wheel Left" "Button Horiz Wheel Right" "Button Side" "Button Extra" "Button Forward" "Button Back" "Button Task" "Button Unknown" "Button Unknown" "Button Unknown" "Button Unknown" "Button Unknown" "Button Unknown" "Button Unknown" "Button Unknown" "Button Unknown" "Button Unknown" "Button Unknown" "Button Unknown"
Button state:
Class originated from: 12. Type: XIValuatorClass
Detail for Valuator 0:
Label: Rel X
Range: -1.000000 - -1.000000
Resolution: 1 units/m
Mode: relative
Class originated from: 12. Type: XIValuatorClass
Detail for Valuator 1:
Label: Rel Y
Range: -1.000000 - -1.000000
Resolution: 1 units/m
Mode: relative
Class originated from: 12. Type: XIValuatorClass
Detail for Valuator 2:
Label: Rel Horiz Wheel
Range: -1.000000 - -1.000000
Resolution: 1 units/m
Mode: relative
Class originated from: 12. Type: XIValuatorClass
Detail for Valuator 3:
Label: Rel Vert Wheel
Range: -1.000000 - -1.000000
Resolution: 1 units/m
Mode: relative
Class originated from: 12. Type: XIScrollClass
Scroll info for Valuator 2
type: 2 (horizontal)
increment: 1.000000
flags: 0x0
Class originated from: 12. Type: XIScrollClass
Scroll info for Valuator 3
type: 1 (vertical)
increment: -1.000000
flags: 0x2 ( preferred )
Reconfiguring the button functions now is a simple matter of changing the button map. We will get the existing button map as follows:
$ xinput get-button-map 12 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
This is the current button map. Think of this as an array of buttons and each of the values is the "function" of the button at that index. Unfortunately I can't quite recall how I came to this conclusion, but on my mouse I want to change the functions of the buttons, 8, 9, and 10 to behave like button 2. I do this by changing the function numbers for those buttons and setting it back as the button map for the X device as follows:
$ xinput set-button-map 12 1 2 3 4 5 6 7 2 2 2 11 12 13 14 15 16 17 18 19 20 21 22 23 24
To make this a permanent solution, I add the above command to my .profile to be executed when I login. However, the device ID could change from boot to boot depending on what devices are attached to the computer. To avoid this grep and awk can be used to find the device ID and feed it to the xinput command as follows:
MOUSE_ID=`xinput list | grep -i Logitech | awk -F= '{ print $2}' | awk '{print $1}'` `xinput set-button-map $MOUSE_ID 1 2 3 4 5 6 7 2 2 2 11 12 13 14 15 16 17 18 19 20 21 22 23`
The above lines are added to the .profile file and the device will dynamically be located from the xinput list and remap the button functions as we desire them to be. Note however, that Logitech in the above example is vague (as I only have 1 Logitech device), so from the output of the xinput command you may need to fill in something more specific for grep to match with.