4

I am using Ubuntu 22.04 on a Lenovo ThinkPad P16 Gen 1.

At the bottom of my touchpad are left, middle and right click buttons. I am often accidentally pasting things by clicking the bottom middle of the pad. To avoid this, I can change the middle-click button to a left-click by:

xinput set-button-map 12 1 1 3 4 5 6 7

But when I restart my machine this resets and so I have to do this again each time - and as I understand it, the xinput for my touchpad won't be 12 every time (as it is in this example).

How can I make this change permanent or automate this mapping change each time I boot?

4 Answers4

3

How can I make this change permanent or automate this mapping change each time I boot?

The easiest way is to create a new Startup Application for that and use this:

sh -c 'sleep 5 && xinput set-button-map 12 1 1 3 4 5 6 7'

... in the Command: field similar to this example ... and it will be automatically executed on reboot and on login.

Notice that sleep 5 will delay the execution of the command for five seconds (increase it if needed) to allow the graphical user session to fully load before xinput is executed ... This is needed because xinput requires a working graphical user session to execute and do it's job.

and as I understand it, the xinput for my touchpad won't be 12 every time

That is possible if the device is e.g. removable and is connected to a different port the next time it's plugged in again.

While the ID might change, the device name usually doesn't ... So, you could look into the output of xinput list to get the name of your device and use that to get the ID like so:

xinput list --id-only "Exact Device Name" 2>/dev/null

... or even like so:

xinput list 2>/dev/null | grep --color=never -Po "Exact Device Name.*=\K[0-9]+"

... and that can be used in the above sh command string in place of the device ID (in a command substitution syntax $(...)) like so:

sh -c 'sleep 5 && xinput set-button-map "$(xinput list --id-only "Exact Device Name" 2>/dev/null)" 1 1 3 4 5 6 7'

or like so:

sh -c 'sleep 5 && xinput set-button-map "$(xinput list 2>/dev/null | grep --color=never -Po "Exact Device Name.*=\K[0-9]+")" 1 1 3 4 5 6 7'

... and your device ID should be automatically discovered.

Raffa
  • 34,963
0

If you edit your .profile startup file you can execute this at startup.

.profile is located in the /home/{user} directory.

You can create the .profile file if it does not exist.

# the default umask is set in /etc/profile; for setting the umask
# for ssh logins, install and configure the libpam-umask package.
# umask 022

if running bash

if [ -n "$BASH_VERSION" ]; then # include .bashrc if it exists if [ -f "$HOME/.bashrc" ]; then . "$HOME/.bashrc" fi fi

set PATH so it includes user's private bin if it exists

if [ -d "$HOME/bin" ] ; then PATH="$HOME/bin:$PATH" fi

set PATH so it includes user's private bin if it exists

if [ -d "$HOME/.local/bin" ] ; then PATH="$HOME/.local/bin:$PATH" fi

sh -c 'sleep 5 && xinput set-button-map 12 1 1 3 4 5 6 7'

Jpirok
  • 1
0

Find out the exact name of the device:

xinput list

terminal1

xinput list | grep "TM3127-001"

You can't rely on "Touchpad", "TouchPad", etc. I know this will never change.

xinput list | grep "TM3127-001" | grep -Eo 'id=[0-9]{1,2}'

Isolate the id number (above), then grep out the numbers (below):

xinput list | grep "TM3127-001" | grep -Eo 'id=[0-9]{1,2}' | grep -Eo '[0-9]{1,2}'

terminal2

sudo nano /path/to/script/my_script.sh

Use the following script for my_script.sh.
Replace YOUR_UNIQUE_STRING with your device name, where mine was TM3127-001.
Save & exit.

#!/bin/bash

device_id=$(xinput list | grep "YOUR_UNIQUE_STRING" | grep -Eo 'id=[0-9]{1,2}' | grep -Eo '[0-9]{1,2}')

xinput set-button-map "$device_id" 1 1 3 4 5 6 7

exit 0

Change mode to executable: sudo chmod +x /path/to/script/my_script.sh

sudo nano /etc/rc.local

Put the following at the end of the file:

/path/to/script/my_script.sh start

Now save, exit & reboot. Your button mapping is now permanent.

0

You can remap the event on the kernel level using udev rules (modified from here)

This method will remap the buttons at a deeper level meaning it will affect all users on the system and will work after replugging the device and restarting the computer.

Create a file like /etc/udev/hwdb.d/99-my-mouse-test.hwdb with contents like:

# evdev:input:b<bus>v<vendor>p<product>*
evdev:input:b0003v056Ep010C*
 # KEYBOARD_KEY_<value>=<action>
 KEYBOARD_KEY_90005=btn_right
 KEYBOARD_KEY_90004=btn_middle

To get the the required values you can use evtest (sudo apt install evtest)

Running sudo evtest will ask which device to scan, after selecting device it will output something like:

Input driver version is 1.0.1
Input device ID: bus 0x3 vendor 0x56e product 0x10c version 0x111
Input device name: "ELECOM TrackBall Mouse HUGE TrackBall"
Supported events:
...

Grab the bus, vendor and product numbers and convert them to 4 character uppercase hexadecimal numbers: (0x3 -> 0003, 0x56e -> 056E and 0x10c -> 010C) Add them together with b for bus, v for vendor and p for product: b0003v056Ep010C. Than add an asterisks (*) to match anything after it.

To get the KEYBOARD_KEY_* number click the button and look for the value (90005 below)

Event: time 1725469422.862391, type 4 (EV_MSC), code 4 (MSC_SCAN), value 90005
Event: time 1725469422.862391, type 1 (EV_KEY), code 273 (BTN_RIGHT), value 1
Event: time 1725469422.862391, -------------- SYN_REPORT ------------
Event: time 1725469422.943388, type 4 (EV_MSC), code 4 (MSC_SCAN), value 90005
Event: time 1725469422.943388, type 1 (EV_KEY), code 273 (BTN_RIGHT), value 0
Event: time 1725469422.943388, -------------- SYN_REPORT ------------

There seems to exist different output formats for this, my source had a different one and had to convert the number into a (lowercase) hexadecimal number.

Check input-event-codes.h for what names the things you want to happen might be called, but make sure to make it lower-case.

To activate the new keybindings it needs to be compiled and reloaded:

sudo udevadm hwdb --update
sudo udevadm trigger
edruid
  • 101