How do I make xinput mouse settings persistent for a USB mouse?
You could cron
the command or add it to your startup but neither are particularly elegant. If I were you, I'd add this to my udev rules and let the system detect events and fire off the command when it needs to.
First we need the mouse vendor and product strings. You can find these through lsusb
. Look for your mouse. Here's my mouse shows up:
Bus 004 Device 012: ID 1532:000f Razer USA, Ltd
The In the part 1532:000f
, 1532
is the vendor and 000f
is the product.
So then we add a rule to udev. udev rules are found in /lib/udev/rules.d/
. You can write your own or be cheeky and edit another one. There is a helpful little README in there too that I suggest you peruse (cat /lib/udev/rules.d/README
).
Whichever you do you want to add a rule like this. Notice I use the IDs from earlier to make this work.
BUS=="usb", SYSFS{idVendor}=="1532", SYSFS{idProduct}=="000f", ACTION=="add",
RUN+="/usr/bin/xinput set-ptr-feedback 'USB Optical Mouse' 4 1 1"
udev should pick that up immediately.
Note udev can do pretty clever things on its own when it comes to configuring devices. You might not need xinput
at all. Here's an example of a custom configuration for a mouse.
I can think of no other solution than starting a little daemon that
periodically polls xinput --list
and runs a command when a device is
plugged in or removed.
Sample code:
#! /bin/sh -x
#
# xievd [INTERVAL]
#
# Poll `xinput` device list every INTERVAL seconds (default: 10)
# and run script in ~/.xievd/${device_name}.sh when a device is
# plugged-in (or pulled out).
#
# The device name is the same as given by `xinput --list`, with
# the following transformations applied:
# * any non-alphanumeric character is deleted (except: space, `_` and `-`)
# * leading and trailing spaces are removed
# * any sequence of 1 or more space chars is converted to a single `_`
#
interval=${1:-10}
scripts_dir="$HOME/.xievd"
if [ ! -d "$scripts_dir" ]; then
echo 1>&2 "xievd: No scripts directory -- exiting."
exit 1
fi
state_dir="$(mktemp -t -d xievd.XXXXXX)" \
|| { echo 1>&2 "xievd: Cannot create state directory -- exiting."; exit 1; }
trap "rm -rf $state_dir; exit;" TERM QUIT INT ABRT
process_xinput_device_list() {
touch "${state_dir}/.timestamp"
# find new devices and run "start" script
xinput --list --short \
| fgrep slave \
| sed -r -e 's/id=[0-9]+.+//;s/[^a-z0-9 _-]//ig;s/^ +//;s/ *$//;s/ +/_/g;' \
| (while read device; do
if [ ! -e "${state_dir}/${device}" ]; then
# new device, run plug-in script
[ -x "${scripts_dir}/${device}" ] && "${scripts_dir}/${device}" start
fi
touch "${state_dir}/${device}"
done)
# find removed devices and run "stop" script
for d in "$state_dir"/*; do
if [ "${state_dir}/.timestamp" -nt "$d" ]; then
# device removed, run "stop" script
device="$(basename $d)"
[ -x "${scripts_dir}/${device}" ] && "${scripts_dir}/${device}" stop
rm -f "$d"
fi
done
}
# main loop
while true; do
process_xinput_device_list
sleep $interval
sleep 1
done
# cleanup
rm -rf "$state_dir"
Save the code above in a xievd
executable file somewhere in your PATH, add it
to your startup applications, and then create a
~/.xievd/USB_Optical_Mouse
shell script:
#! /bin/sh
if [ "$1" = "start" ]; then
xinput set-ptr-feedback 'USB Optical Mouse' 4 1 1
fi