I have Lenovo ThinkPad X230 Tablet with Ubuntu 16.04. It has a convertible screen and when it is in tablet mode the touchpad is still active and make a mess.

I've created the following script and bound it to one of the built in buttons (by a custom shortcut):

#!/bin/bash -e

# Find the TouchPad device ID
ID="$(xinput | grep -ioP 'touchpad.*id=\K[0-9]*')"                                  

if   [ "$(LANG=C xinput --list-props "$ID" | awk 'NR==2{print $4}')" == "0" ]; then 
        # If the device is disabled, then enable it and kill 'onboard' virtual keyboard
        xinput enable "$ID"; killall onboard; xrandr -o normal
elif [ "$(LANG=C xinput --list-props "$ID" | awk 'NR==2{print $4}')" == "1" ]; then
        # If the device is enabled, then disable it and run 'onboard' virtual keyboard
        xinput disable "$ID"; nohup onboard >/dev/null 2>&1 &

The script works properly, but this is a fake solution and yesterday I spent few hours to learn how to do that in a proper way. So I decided to share this experience here.

3 Answers 3


To check whether the device is in tablet mode or not we could read the value (0 or 1) of:


This value is switched by specific events. We can catch these events and could bind scripts to them by using acpid - Advanced Configuration and Power Interface event daemon.

1. Catch the events. Execute acpi_listen or netcat -U /var/run/acpid.socket, turn the lid in tablet mode, then turn it back. Here is an example output:

$ acpi_listen
video/tabletmode TBLT 0000008A 00000001
video/tabletmode TBLT 0000008A 00000000

Please note when the lid is close/open the result is different:

$ acpi_listen
button/lid LID close
button/lid LID open

2. Configure acpid to recognize the events triggered by the device mode change. Run the following lines into a terminal as (single) commands:

cat << EOF | sudo tee /etc/acpi/events/thinkpad-tablet-enabled
# /etc/acpi/events/thinkpad-tablet-enabled
# This is called when the lid is placed in tablet position on
# Lenovo ThinkPad X230 Tablet

event=video/tabletmode TBLT 0000008A 00000001
action=/etc/acpi/thinkpad-touchpad-twist-mode.sh 1
cat << EOF | sudo tee /etc/acpi/events/thinkpad-tablet-disabled
# /etc/acpi/events/thinkpad-tablet-disabled
# This is called when the lid is placed in normal position on
# Lenovo ThinkPad X230 Tablet

event=video/tabletmode TBLT 0000008A 00000000
action=/etc/acpi/thinkpad-touchpad-twist-mode.sh 0

The above commands will create the files:

  • /etc/acpi/events/thinkpad-tablet-enabled
  • /etc/acpi/events/thinkpad-tablet-disabled

Note: The scripts for lid open/close aren't provided here. But they are similar as the above.

3. Restart acpid so it can re-read the event filters, including the ones you just added:

sudo systemctl restart acpid.service

4. Create the script /etc/acpi/thinkpad-touchpad-in-twist-mode.sh that will disable 1 and enable 0 the touchpad (&& make it executable):

cat << EOF | sudo tee /etc/acpi/thinkpad-touchpad-twist-mode.sh && sudo chmod +x /etc/acpi/thinkpad-touchpad-twist-mode.sh
LANG=C                                                                                                        # Ensure stable parsing
export DISPLAY="\$(w | awk 'NF > 7 && \$2 ~ /tty[0-9]+/ {print \$3; exit}' 2>/dev/null)"                      # Get and export the current user's \$DISPAY
export XAUTHORITY="/home/\$(w | awk 'NF > 7 && \$2 ~ /tty[0-9]+/ {print \$1; exit}' 2>/dev/null)/.Xauthority" # Get and export the currentuser's \$XAUTHORITY
ID="\$(xinput | grep -ioP 'touchpad.*id=\K[0-9]*')"                                                           # Find the TouchPad device ID

if   [ "\${1}" -eq 0 ]; then xinput enable "\$ID"   # Laptop mode or Lid is open
elif [ "\${1}" -eq 1 ]; then xinput disable "\$ID"  # Tablet mode or Lid is closed
  • The script will parse and export the environment variables $DISPAY and $XAUTHORITY of the current user's session, in order to allow root (who runs the acpid process) to access the user's X session, respectively xinput.
  • Then the script will parse the $ID of the touchpad. And depending on the value of the input variable $1 it will enable or disable the touckpad.

Note: The backslashes before the dollar signs \$ are intended to escape the variable (command substitution) expansion within the cat command. So if you copy/paste the script (instead using of the cat approach) you should remove them manually.



Using the answer of pa4080, I had to make this change for it to work in Ubuntu 18.04: hard code my user (tim) in the script and run the script in the context of my user.

File /etc/acpi/events/thinkpad-lid-event:

action=su tim -c '/home/tim/scripts/lid.sh.post'

and lid.sh.post:

#! /bin/bash
# toggle touchpad enabled status when lid changes (lid closed,touchpad off)
# is run in user context
# example rule /etc/acpi/events/thinkpad-lid-close
# event=button/lid.*
# action=su tim -c '/home/tim/scripts/lid.sh.post'  
# see https://askubuntu.com/questions/91534/disable-touchpad-while-the-lid-is-down
# and https://askubuntu.com/questions/980997/how-do-i-disable-the-touchpad-when-the-lid-is-twisted-or-closed/980999#980999
# this needs an event defined in /etc/acpi/events to call this script when lid status changes
# these variables need to be set to use xinput properly
export XAUTHORITY=$(ls -1 /home/$user/.Xauthority | head -n 1)
export DISPLAY=":$(ls -1 /tmp/.X11-unix/ | sed -e s/^X//g | head -n 1)"

export TouchPadID=$(xinput | grep 'TouchPad' | sed  -n "s/^.*id=\([[:digit:]]\+\).*$/\1/p")
grep -q closed /proc/acpi/button/lid/*/state
xinput set-int-prop  $TouchPadID "Device Enabled" 8 $LidClosedResult
if [ $? -eq 0 ]; then
  echo "for user: $user xinput device $TouchPadID enabled status changed to $LidClosedResult because of LID ACPI event" | systemd-cat
  echo "failed to change xinput device $TouchPadID enabled status after LID ACPI event" | systemd-cat

Made another variation acting on 'lid' and 'tabletmode' and just 2 rules catching the response from the ACPI events (use "%e" in the action, mind the quotes !):

# toggle 'touchpad enabled status' off/on when lid changes (lid closed or tablet mode => touchpad off)
# let it act on 2 rules in /etc/acpi/events/: lid-change and tabletmode-change:
#     event=button/lid.*
#     action=/etc/acpi/touchpad-toggle.sh "%e"
#     event=video/tabletmode.*
#     action=/etc/acpi/touchpad-toggle.sh "%e"

# variables needed to use xinput properly
user1="$(who | cut -d ' ' -f1)"
export XAUTHORITY="$(ls -1 /home/$user1/.Xauthority | head -n 1)"
export DISPLAY=":$(ls -1 /tmp/.X11-unix/ | sed -e s/^X//g | head -n 1)"
export TPdID="$(xinput | grep -ioP 'touchpad.*id=\K[0-9]*')"

if [ "${@}" == "" ]; then
    echo "ACPI event didn't return trigger values." | systemd-cat
elif [ "$user1" == "" ]; then
    echo "ACPI event action didn't find current user." | systemd-cat
    if   [ "${@}" == "button/lid LID open" ]; then xinput enable $TPdID
    elif [ "${@}" == "button/lid LID close" ]; then xinput disable $TPdID
    elif [ "${@}" == "video/tabletmode TBLT 0000008A 00000000" ]; then xinput enable $TPdID
    elif [ "${@}" == "video/tabletmode TBLT 0000008A 00000001" ]; then xinput disable $TPdID
    if [ $? -eq 0 ]; then
        echo "ACPI event: xinput device $TPdID status changed on ${@}." | systemd-cat
        echo "ACPI event failed: xinput device $TPdID status NOT changed on ${@}." | systemd-cat

Enjoy using the script ...

Edit: $USER doesn't always return a result when used by root ... So I replaced it using: user1="$(who | cut -d ' ' -f1)"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.