Ubuntu: Automatically Disable Touchpad when External Mouse Connected


Introduction:

If you’re like me, you hate using your touchpad when you could be using an external mouse. If you’re like me you also have a habit of disabling your touchpad when using a mouse, and forgetting to re-enable it until after you unplug your mouse. If you’re like me, this tutorial is exactly what you need.

What you need to get started:

You will need to make sure that you have xinput and halevt installed. You almost certainly already have xinput, but the following command will make sure you have what you need:

sudo aptitude install xinput halevt

I also recommend that you create a folder for scripts (if you haven’t already), and add it to your $PATH. I created a “bin” folder in my home directory for this. Create the folder with:

mkdir ~/bin

and add it to your path by issuing the following commands:

echo "PATH=\$PATH:~/bin" >> ~/.bashrc
echo "export PATH" >> ~/.bashrc

Configure the script:

First we need to create and configure the script which will actually toggle the touchpad:

cd ~/bin
touch toggleTouchpad
gedit toggleTouchpad

The script should now be open in gedit (feel free to replace gedit with your favorite text editor). Paste the following into the script:

# toggleTouchpad by Brendon Dugan
# Toggles a touchpad on or off depending on it's current state or CLI argument
#
# To configure, run the command 'xinput list' in terminal and identify your touch pad.
# Using the output of the above command, change the touchpadString variable to a substring
# of your touchpad's description that is unique to that device.
#
# To run, simply type 'toggleTouchpad' to toggle your touchpad on or off, or
# 'toggleTouchpad on' to explicitly turn your touchpad on, or
# 'toggleTouchpad off' to explicitly turn it off.
#
# Enjoy!

# A function for logging
safemk () {
if [ ! -d $1 ];
  then mkdir $1;
  chmod +rw $1;
fi
}
logdir=/home/$USER/.toggleTouchpad
touchpadString="TouchPad"
touchpadID=$(xinput list | grep "$touchpadString" | awk -F " " '{print $6}' | awk -F "=" '{print $2}')
touchpadEnabled=$(xinput list-props $touchpadID | grep "Device Enabled" | awk -F ":" '{print $2}')
sleeptime=1

# Create the logging directory
safemk $logdir
touch $logdir/errorLog.txt

# Check for arguments on the command line
if test $# -eq 1
then
	# Change the argument to lowercase
	arg1=$(echo $1 | tr [:upper:] [:lower:])
	cliArg=1
else
	# There is no argument.
	cliArg=0
fi

if [ $cliArg -eq 1 ]
then
	# If there's an argument, check to see whether it is on, off, or junk
	if [ $arg1 = 'on' ]
	then
		# The argument was 'on', so turn the touchpad on
		xinput --set-prop $touchpadID "Device Enabled" 1
		if [ $(xinput list-props $touchpadID | grep "Device Enabled" | awk -F ":" '{print $2}') -eq 0 ]
		then
			echo "Something went wrong\n" >> $logdir/errorLog.txt
		fi
	elif [ $arg1 = 'off' ]
	then
		# Sleep for a short time to fix a bug that re-enabled the touchpad immediately after disabling it
		sleep $sleeptime
		# The argument was 'off', so turn the touchpad off
		xinput --set-prop $touchpadID "Device Enabled" 0
		if [ $(xinput list-props $touchpadID | grep "Device Enabled" | awk -F ":" '{print $2}') -eq 1 ]
		then
			echo "Something went wrong, perhaps \$sleeptime needs to be greater than $sleeptime ?\n" >> $logdir/errorLog.txt
		fi
	else
		# The argument was junk, so log the error and go on
		echo "Invalid argument \""$arg1"\" was supplied\n" >> $logdir/errorLog.txt
	fi
else
	# There was no argument, so just toggle the touchpad to the opposite
	# of the state it has now.
	if [ $touchpadEnabled -eq 1 ]
	then
		xinput --set-prop $touchpadID "Device Enabled" 0
	else
		xinput --set-prop $touchpadID "Device Enabled" 1
	fi
fi

Now make the script executable by running:

 chmod +x ~/bin/toggleTouchpad

Ok, we’re almost configured. We need to make sure that your touchpad will be affected by the script. Run the following command to get a list of all current input devices:

xinput -list

It should have an output something like this:

brendon@brendon-lappy-linux:~$ xinput -list
⎡ Virtual core pointer                    	id=2	[master pointer  (3)]
⎜   ↳ Virtual core XTEST pointer              	id=4	[slave  pointer  (2)]
⎜   ↳ Logitech Logitech BT Mini-Receiver      	id=15	[slave  pointer  (2)]
⎜   ↳ SynPS/2 Synaptics TouchPad              	id=12	[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)]
    ↳ Laptop_Integrated_Webcam_2M             	id=10	[slave  keyboard (3)]
    ↳ AT Translated Set 2 keyboard            	id=11	[slave  keyboard (3)]
    ↳ Dell WMI hotkeys                        	id=13	[slave  keyboard (3)]
    ↳ Logitech Logitech BT Mini-Receiver      	id=14	[slave  keyboard (3)]
brendon@brendon-lappy-linux:~$

If your touchpad has the word “TouchPad” (case sensitive) in it, the script is ready to go. If it doesn’t, edit the variable “touchpadString” in the script to match your touchpad… but remember everything is case sensitive. For now, your script is configured. Next step is testing.

Test the script:

Make sure your touchpad is working, and then open a new terminal window. We are going to do four tests. Before and after each test, try your touchpad.

Test 1:

toggleTouchpad

Did your touchpad stop working? Good!

Test 2:

toggleTouchpad

Did your touchpad start working again? Good!

Test 3:

toggleTouchpad off

Wait at least one second…
Did your touchpad stop working? Good!

Test 4:

toggleTouchpad on

Wait at least one second…
Did your touchpad start working again? Good!

Making the magic happen automatically:

We’re almost there! Now we need to set the script to run automatically when your mouse is plugged in. Making sure your mouse is unplugged, run the following command:

halevt -i >>~/connectedDevices.txt

While the command is running, plug in your mouse, and then unplug it. Now press Ctrl +c to kill the process. Open ~/connectedDevices.txt, and you should see something that looks like:

New Device: /org/freedesktop/Hal/devices/usb_device_46d_b02_noserial
New Device: /org/freedesktop/Hal/devices/usb_device_46d_b02_noserial_if0
New Device: /org/freedesktop/Hal/devices/usb_device_46d_c70e_00076142E023
New Device: /org/freedesktop/Hal/devices/usb_device_46d_c70e_00076142E023_if0
New Device: /org/freedesktop/Hal/devices/usb_device_46d_c70e_00076142E023_if0_logicaldev_input
New Device: /org/freedesktop/Hal/devices/usb_device_46d_c70a_00076142E023
New Device: /org/freedesktop/Hal/devices/usb_device_46d_c70a_00076142E023_if0
New Device: /org/freedesktop/Hal/devices/usb_device_46d_c70a_00076142E023_if0_logicaldev_input
Device removed: /org/freedesktop/Hal/devices/usb_device_46d_c70e_00076142E023_if0_logicaldev_input
Device removed: /org/freedesktop/Hal/devices/usb_device_46d_c70e_00076142E023_if0
Device removed: /org/freedesktop/Hal/devices/usb_device_46d_c70e_00076142E023
Device removed: /org/freedesktop/Hal/devices/usb_device_46d_c70a_00076142E023_if0_logicaldev_input
Device removed: /org/freedesktop/Hal/devices/usb_device_46d_b02_noserial_if0
Device removed: /org/freedesktop/Hal/devices/usb_device_46d_c70a_00076142E023_if0
Device removed: /org/freedesktop/Hal/devices/usb_device_46d_c70a_00076142E023
Device removed: /org/freedesktop/Hal/devices/usb_device_46d_b02_noserial

All of those devices are your mouse. Since each of those events will trigger every time you plug in your mouse, we only need to handle one of them. Pick one that ends in seemingly random numbers, and copy and paste everything after the “:” into a text file. We will be using it in a moment. Now, let’s create our halevt config file:

touch ~/.halevt.xml && gedit ~/.halevt.xml

Paste the following into the file:

<?xml version="1.0" encoding="UTF-8"?>
<halevt:Configuration version="0.1" xmlns:halevt="http://www.environnement.ens.fr/perso/dumas/halevt.html">
	<halevt:Device match="hal.info.udi = /org/freedesktop/Hal/devices/usb_device_46d_c70e_00076142E023">
		<halevt:Insertion exec="toggleTouchpad off"/>
		<halevt:Removal exec="toggleTouchpad on"/>
	</halevt:Device>
</halevt:Configuration>

We are almost done! Remember the bit I had you paste into another file?? We are going to use that to identify your device. In the config file, change the line that says:

<halevt:Device match="hal.info.udi = /org/freedesktop/Hal/devices/usb_device_46d_c70e_00076142E023">

to say :

<halevt:Device match="hal.info.udi = /org/freedesktop/Hal/devices/the_rest_of_what_you_copied_into_the_file">

Theoretically, we’re done!

Test the Magic:

From terminal run:

sudo killall halevt
halevt -c ~/.halevt.xml

Now, connect your mouse. If all is going well, about ~1.5 seconds after you plug in your mouse your touchpad should stop working. Now, disconnect your mouse. Your touchpad should start working again.

Making it permanent:

If all went well in the tests, you will want to make this happen automatically forever. Go to “System->Preferences->Startup Applications”, and add a new startup program. Name it something you will remember, and for the command put “halevt -c ~/.halevt.xml”. You’re done!!

Special Thanks:

While writing this script I received a great deal of help from the user Arndt at Ubuntuforums, so you should go leave him lots of love and thanks.

About these ads
Leave a comment

9 Comments

  1. Jef Tobias

     /  November 28, 2010

    Followed the directions exactly as written. When I get to the “test” phase, I get this:
    jef@emptyspace:~/bin$ toggleTouchpad
    toggleTouchpad: command not found

    Reply
    • Brendon Dugan

       /  November 29, 2010

      It seems as though the either the toggleTouchpad script is not executable, or somehow ~/bin isn’t in your PATH. What do you get when you type

      echo $PATH
      

      into terminal? Also, feel free to check out this same tutorial at Ubuntuforums, as that is a bit better of a place for providing support.

      Reply
  2. Jef Tobias

     /  November 28, 2010

    Well, solved the problem with an alternative route, though your solution would use one less button. At any rate, still would like to know why I couldn’t make your solution work.

    Reply
  3. Tácio Roscha

     /  December 20, 2010

    Great script! That was the only issue I had with my Dell Studio 1458. I finally found the perfect solution. Thanks!

    Reply
    • Brendon Dugan

       /  December 21, 2010

      I understand… I wrote this because I was getting annoyed with my Dell Studio 1558 :)

      Reply
  4. Andrew Meadows

     /  January 1, 2011

    This wasn’t working for me because my $touchpadString had a whitespaces in it. When I replaced all whitespaces with dots (.) it worked great. For example, I replaced “ADB mouse” with “ADB.mouse”.

    I’m going to copy the script to /usr/local/bin/ and will try to make it toggle automatically when adding/removing an external mouse by adding a config file in /etc/udev/rules.d/

    Reply
  5. I can’t seem to get the last piece of the puzzle working. The toggle tests work fine. I’ve substituted my device /org/freedesktop/Hal/devices/usb_device_46d_c52b_noserial but the halevt script doesn’t seem to be detecting the change.

    Reply
  6. Marco

     /  December 30, 2012

    Hi, the line

    touchpadID=$(xinput list | grep “$touchpadString” | awk -F ” ” ‘{print $6}’ | awk -F “=” ‘{print $2}’)

    has a problem: this awk -F ” ” ‘{print $6}’ will only work if the device name have exactly 3 words (so there will be 5 spaces before the id=), so I recommend changing it to:

    touchpadID=$(xinput list | grep “$touchpadString” | awk -F “id=” ‘{print $2}’ | awk -F ” ” ‘{print $1}’)

    Reply

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.