This answer show the command lines to swap the mouse primary and secondary button. However, I would like a script to automatically swap the mouse buttons every time is executed. Could somebody hint me on how to do this, I know near to nothing about bash scripts.
6 Answers
Without providing the output of xinput list
on your system, no one can offer an answer which you could use directly. That is because xinput
can show different devices than illustrated in How do I swap mouse buttons to be left handed from the terminal?.
For example, here's the output on OSX:
$ xinput list
⎡ Virtual core pointer id=2 [master pointer (3)]
⎜ ↳ Virtual core XTEST pointer id=4 [slave pointer (2)]
⎜ ↳ xquartz virtual pointer id=6 [slave pointer (2)]
⎜ ↳ pen id=8 [slave pointer (2)]
⎜ ↳ cursor id=9 [slave pointer (2)]
⎜ ↳ eraser id=10 [slave pointer (2)]
⎣ Virtual core keyboard id=3 [master keyboard (2)]
↳ Virtual core XTEST keyboard id=5 [slave keyboard (3)]
↳ xquartz virtual keyboard id=7 [slave keyboard (3)]
and here is the output on my Debian/testing:
$ xinput list
⎡ Virtual core pointer id=2 [master pointer (3)]
⎜ ↳ Virtual core XTEST pointer id=4 [slave pointer (2)]
⎜ ↳ VMware VMware Virtual USB Mouse id=7 [slave pointer (2)]
⎜ ↳ VirtualPS/2 VMware VMMouse id=9 [slave pointer (2)]
⎜ ↳ VirtualPS/2 VMware VMMouse id=10 [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)]
↳ AT Translated Set 2 keyboard id=8 [slave keyboard (3)]
so that on one system, there's possibly one id to choose (xquartz virtual pointer), while on another there are three possibilities. If you read through these, you'll find that the examples cited here are not contrived:
- How can I change mouse keymapping
- 'xinput list' shows same device twice & device IDs change: how to use 'set-prop' in a script?
Given the variation (and vague documentation for xinput
), you probably cannot automate the part about obtaining the mouse device's id.
Supposing that you do choose a usable identifier, and for the sake of discussion, call that "12". A script can read the output of
xinput get-button-map 12
into an array. Some scripting languages provide arrays, e.g., bash
. But there are several pitfalls:
- on my OSX system, that returns a list "1 2 3", while on the Debian system that returns a list "1 2 3 4 5 6 7 8 9 10 11 12".
- you have to guess whether the extra buttons mean something, and
- even the assignment of three button numbers may be not the obvious left/middle/right.
Then the script to toggle the keys has to save its state someplace, e.g., a file in your home directory. A script to manage that would have to
- initialize the file with the current buttons
- update it according to your scheme of toggling buttons (with 3 there are "3!" possible arrangements)
Supposing you have the simplest configuration (and interpretation), you could do something like this in a script:
#!/bin/sh
id=$1
cfg=$HOME/.mousebuttons
[ -f "$cfg" ] || xinput get-button-map $id | awk ' { printf "normal: %s\n", $0; }' >$cfg
mode=$(awk '{print $1;}' <$cfg)
# read and toggle
list=$(awk '{printf "%d %d %d\n", $3, $2, $4; }' <$cfg)
if [ "x$mode" = "xnormal" ]
then
mode=reverse
else
mode=normal
fi
# update the configuration
echo "$mode $list" | awk '{ printf "%s %d %d %d\n", $1, $2, $3, $4; }' >$cfg
xinput set-button-map $id $list
# show result
xinput get-button-map $id
The script accepts one parameter (the identifier of the mouse device). For the given example (and naming the script "toggle-buttons", making it executable and putting it in your $PATH
):
toggle-buttons 12
should do the job.

- 76,765
I'll add my own solution to this as the other answers sometimes seems overly complicated for the simple task of swapping the primary buttons (1 and 3) of a mouse.
#!/bin/bash
set -e
# To get the name of a devices, do "xinput list --name-only"
DEVICE_NAME="PixArt Microsoft USB Optical Mouse"
current_button_map=$(xinput get-button-map "$DEVICE_NAME")
if [[ $current_button_map =~ "1 2 3" ]]; then
echo "Making the mouse a lefty"
xinput set-button-map "$DEVICE_NAME" 3 2 1
else
echo "Making the mouse a righty"
xinput set-button-map "$DEVICE_NAME" 1 2 3
fi

- 260
You can put the command line into a file:
#!/bin/bash
# swap two mouse buttons for better ergonomics, e.g. BACK, FORWARD
xinput set-button-map 12 3 2 1
Once you have done that make it executable (if the file is named swap_buttons.sh
):
chmod +x swap_buttons.sh
Now you can run the script with:
./swap_buttons.sh

- 4,155

- 4,067
- 1
- 26
- 42
-
The problem with that is the command only swap the once, i.e., it maps the buttons to a fixed configuration. I what them to swap iteratively. – Fachicon May 22 '16 at 01:11
-
I'd do something like:
#!/bin/sh
mxid=$(xinput --list --short | awk '/Razer/{gsub(/.*id=/, "");gsub(/[[:blank:]].*/, "");print}')
bmap=$(xinput get-button-map $mxid)
nmap=$(awk '{s=$1;$1=$3;$3=s};1' <<<$bmap)
xinput set-button-map $mxid $nmap
This assumes you know the "name" of your mouse (in my case it's Razer
) and you know the default button mapping (i.e. which buttons are left and right so that you can swap them) that you get with xinput list $mxid
:
Button labels: "Button Left" "Button Middle" "Button Right"....
and xinput get-button-map $mxid
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
As you can see, in my case 1 =>> left
and 3 =>> right
so the script above just reads the current mapping and swaps first and third values and then sets the new mapping.

- 82,805
If you need to toggle a state (and your reverse/unreverse the order of the mouse keys is such a state), of device you either have to be able to query the device for the current state, or keep the state in some file.
As I couldn't find if xinput
does have a way of asking a mouse for the button mapping, you should probably go with storing the state in a file e.g. ~/.config/mousebuttons
. Your script should write 'reverse' to the file when it executes:
xinput set-button-map 12 3 2 1 and write 'normal' to that file when executing:
xinput set-button-map 12 2 3
The actual action to take depends on reading the file: do the first step if the file contents when the script starts are normal
(or the file doesn't exist), and do the second if the contents are reverse
.
The file contents flip from reverse
to normal
on each invocation. Your actual state might not reflect the content of the file, e.g. after a reboot, therefore print out to the screen what the new state is as well for a visual reminder. If the file is out of sync with the state, a single invocation of your script will sync it again.

- 79,293
As of 2023, you don't need a script. Use input-remapper, since scripts has to be executed everytime when it boots (input-remapper doesn't need to be started every time). More on it is answered here: https://askubuntu.com/questions/1427427/set-left-handed-mouse-and-right-handed-touchpad/1451846#1451846

- 967