My wife got a new laptop recently, a ThinkPad P16s. Like the previous computer, we run Xubuntu, with the idea that XFCE changes less than GNOME between releases. So far, so good. However, the ThinkPad has both a trackpoint, with buttons under the space bar, and a touchpad with built-in buttons on the lower side. Since my wife often uses wrist supports, the pressure she puts on the touchpad is higher than normal wrists, causing undue clicking. Disabling “touch tap” and scrolling is easy enough in Ubuntu, but disabling the buttons is harder.
XInput
The easiest way to disable buttons for a single device is by clearing the button map with the xinput command.
Finding the device:
$ xinput list
⎡ Virtual core pointer id=2 [master pointer (3)]
⎜ ↳ Virtual core XTEST pointer id=4 [slave pointer (2)]
⎜ ↳ ELAN0688:00 04F3:320B Mouse id=9 [slave pointer (2)]
⎜ ↳ ELAN0688:00 04F3:320B Touchpad id=10 [slave pointer (2)]
⎜ ↳ TPPS/2 Elan TrackPoint id=12 [slave pointer (2)]
⎣ Virtual core keyboard id=3 [master keyboard (2)]
↳ Virtual core XTEST keyboard id=5 [slave keyboard (3)]
↳ Video Bus id=6 [slave keyboard (3)]
↳ Power Button id=7 [slave keyboard (3)]
↳ Sleep Button id=8 [slave keyboard (3)]
↳ AT Translated Set 2 keyboard id=11 [slave keyboard (3)]
↳ ThinkPad Extra Buttons id=13 [slave keyboard (3)]
Then showing the current button mapping:
$ xinput get-button-map 10
1 2 3 4 5 6 7
Seven buttons. And here I thought it only had three. The additional four are normally used for scrolling. Since she only wants the touchpad to move the cursor, we can disable all of them by setting them to zero:
$ xinput set-button-map 10 0 0 0 0 0 0 0
If you only want to disable the buttons, and leave scrolling:
$ xinput set-button-map 10 0 0 0
Cool, that wasn’t too hard. Now let’s make it a bit more user-friendly.
Robustness
It’s always good to think about the assumptions you make about the system while automating a process. Here, there aren’t too many moving parts, but let’s talk about two possibilities.
First, I’m sure most devices use the seven buttons we saw here, but we might as well first get the button mapping, count the buttons and set as many zeros. I’ve seen examples online of twelve buttons. The limit is 32.
Second, I have no idea how stable the numerical ID is in xinput, and since it supports name, that is probably more robust:
$ xinput get-button-map 'ELAN0688:00 04F3:320B Touchpad'
0 0 0 0 0 0 0
User Interface
There is another possibility for setting the button mapping, and that’s the libinput driver section in Xorg configuration:
Section "InputDevice"
Identifier "devname"
Driver "libinput"
Option "Device" "devpath"
Option "ButtonMapping" "0 0 0 0 0 0 0"
EndSection
The drawback of this approach is that it’s system-wide, and it doesn’t help with changing the setting after boot.
Since it might be useful to change back-and-forth, it seems better to just run xinput set-button-map
on login, and have a script that allows changing it.
The user script can store the latest configuration, and the login script can apply that same setting.
Script
Here is the script, using the device name above as selector:
- If you give it
on
oroff
, it will do that. - If you give it
control
, it uses Zenity or xmessage to interactively ask the user. - If you give it
load
, it will load the latest setting from$TPBCONFIG
.
If neither Zenity nor xmessage is to your liking, yad, gxmessage, or kdialog might do it.
The Zenity programming interface is a bit ugly compared to xmessage
, but the graphical interface is much nicer.
Application Menu
That script requires a command line interface to run, which isn’t very user friendly. We can build an application file, which gets picked up by the desktop environment (XFCE in this case,) and placed in the menu.
The XDG desktop/application file format is pretty simple:
After a logout+login, the TouchPad Buttons should show up under Settings.
Loading on Login
For running the script with the load
parameter on login, we need an almost identical application file:
After a logout+login, you should be able to see it in your Session Settings, and potentially disable it, if you’d like.
In some forums, I’ve seen others having issues with the setting not being applied after suspend+resume, but that doesn’t seem to be a problem with this solution.