This is one of those really simple things that are surprisingly tricky to do right. My goal: automatically disable the touchpad when an external mouse is plugged in. Why go through all the trouble? Because—in addition to being plain annoying—a moving cursor can alter the window focus in my current tiling window manager.

On Windows, you can either do it easily (if the driver supports it) or it’s nearly impossible. For better or worse, on Linux, you can almost always do it after expending some (possibly non-trivial) effort.

## Solution

In the end, I boiled it down to:

These are intended for Arch Linux. I haven’t tried on any other systems yet, but it shouldn’t be too hard to adapt them for other distributions. It might even work out of the box!

## Details

I started out by following the Arch Linux wiki, but I’ve simplified the script and made some of my own discoveries along the way.

Firstly, the udev rules: these consist of two simple rules that will call /bin/touchpad-ctl whenever a mouse is added or removed. Nothing too fancy here.

# /etc/udev/rules.d/01-touchpad.rules
SUBSYSTEM=="input", KERNEL=="mouse[0-9]*", ACTION=="remove", RUN+="/bin/touchpad-ctl"

The udev rules would miss the opportunity to fire if the mouse is already plugged in at boot, so it’s necessary to call touchpad-ctrl in .xinitrc to make sure that the touchpad is disabled in this scenario.

# ~/.xinitrc (insert this somewhere before starting your window manager)
touchpad-ctl

The touchpad-ctl script is where the magic occurs. Since I’ve not come across an easy to way to figure out which device is the actual touchpad, you’ll have to set this variable manually in the script. To list all the mouse-like devices, run this command:

find /sys/class/input/ -name mouse\*                    \
-exec udevadm info --attribute-walk --path={} \;   \
| grep ATTRS{name}

(If it says it can’t find udevadm, then try running it as root.)

The script does two things:

• Check if any external mouse is plugged in. This is the easy part: simply loop through all the mice and check if it’s an external mouse (i.e. not the touchpad).

FOUND=0
for MOUSE in find /sys/class/input -name mouse\*
do
if [ "cat $MOUSE/device/name" != "$TOUCHPAD" ]
then
FOUND=1
break
fi
done
• Enable or disable the touchpad with synclient. This is a bit more difficult because it needs to know the DISPLAY and XAUTHORITY. The DISPLAY variable is hardcoded, while the XAUTHORITY is obtained from the home directories of the users. This is repeated for every user.

DISPLAY=:0
export DISPLAY
for USER in w -h | cut -d\  -f1 | sort | uniq
do
XAUTHORITY=sudo -Hiu $USER env | grep ^HOME= | cut -d= -f2/.Xauthority export XAUTHORITY synclient TouchpadOff=$FOUND
done