How to make a program that finds id's of xinput devices and sets xinput some settings
Asked Answered
S

7

30

I have a G700 mouse connected to my computer. The problem with this mouse in Linux (Ubuntu) is that the sensitivity is very high. I also don't like mouse acceleration, so I've made a script that turns this off. The script looks like this

#!/bin/bash
# This script removes mouse acceleration, and lowers pointer speed
# Suitable for gaming mice, I use the Logitech G700.
# More info: http://www.x.org/wiki/Development/Documentation/PointerAcceleration/
xinput set-prop 11 'Device Accel Profile' -1
xinput set-prop 11 'Device Accel Constant Deceleration' 2.5
xinput set-prop 11 'Device Accel Velocity Scaling' 1.0
xinput set-prop 12 'Device Accel Profile' -1
xinput set-prop 12 'Device Accel Constant Deceleration' 2.5
xinput set-prop 12 'Device Accel Velocity Scaling' 1.0

Another problem with the G700 mouse is that it shows up as two different devices in xinput. This is most likely because the mouse has a wireless adapter, and is usually also connected via a usb cable (for charging). This is my output from xinput --list (see id 11 and 12):

$ xinput --list
⎡ Virtual core pointer                              id=2    [master pointer  (3)]
⎜   ↳ Virtual core XTEST pointer                    id=4    [slave  pointer  (2)]
⎜   ↳ Logitech USB Receiver                         id=8    [slave  pointer  (2)]
⎜   ↳ Logitech USB Receiver                         id=9    [slave  pointer  (2)]
⎜   ↳ Logitech Unifying Device. Wireless PID:4003   id=10   [slave  pointer  (2)]
⎜   ↳ Logitech G700 Laser Mouse                     id=11   [slave  pointer  (2)]
⎜   ↳ Logitech G700 Laser Mouse                     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)]
    ↳ Power Button                                  id=7    [slave  keyboard (3)]

This isn't usually a problem, since the id's are usually the same. But sometimes the id's of the mouse change, and that's where my question comes in.

What's the simplest way of writing a script/program that finds the id that belongs to the two listings named Logitech G700 Laser Mouse in the output from xinput --list, and then running the commands in the top script using those two ids?

Simone answered 12/9, 2013 at 5:25 Comment(3)
Stack Overflow is a site for programming and development questions. This question appears to be off-topic because it is not about programming or development. See What topics can I ask about here in the Help Center. Perhaps Super User or Unix & Linux Stack Exchange would be a better place to ask.Leatherback
That might be true, but this question is more than 4 years old, and has more than 10k views. Any reason for bringing this up now? Are you going to delete the question?Simone
No, I don't have plans to delete it. Someone else cited it as "here's a similar question".Leatherback
A
19

You can do something like the following.

if [ "$SEARCH" = "" ]; then 
    exit 1
fi

ids=$(xinput --list | awk -v search="$SEARCH" \
    '$0 ~ search {match($0, /id=[0-9]+/);\
                  if (RSTART) \
                    print substr($0, RSTART+3, RLENGTH-3)\
                 }'\
     )

for i in $ids
do
    xinput set-prop $i 'Device Accel Profile' -1
    xinput set-prop $i 'Device Accel Constant Deceleration' 2.5
    xinput set-prop $i 'Device Accel Velocity Scaling' 1.0
done

So with this you first find all the IDs which match the search pattern $SEARCH and store them in $ids. Then you loop over the IDs and execute the three xinput commands.

You should make sure that $SEARCH does not match to much, since this could result in undesired behavior.

Aylsworth answered 12/9, 2013 at 6:31 Comment(2)
Can I call this directly from ~/.xinputrc? It seems like that file gets sourced but I'm not sure.Mongrelize
@JarettMillard Yes this looks like a good place to put the script above. But maybe you use the approach of @Schoenix or @SergiyKolodyazhnyy and make the resulting script executable. To then only add /path/to/new_script NAME_OF_DEVICE OTHER_OPT to .xinputrc.Aylsworth
M
22

If the device name is always the same, in this case Logitech G700 Laser Mouse, you can search for matching device IDs by running

xinput list --id-only 'Logitech G700 Laser Mouse'
Micropyle answered 29/4, 2018 at 17:40 Comment(4)
This doesn't work for my logitech mouse (xinput list --id-only pointer:"Logitech G203 Prodigy Gaming Mouse"). xinput refuses to print the ids, because "There are multiple devices matching". Kind of silly though.Adaxial
+1 for Vinson Chuong - I'm with @MauricioMachado here. This works for me. My mouse is listed in "Virtual core pointer" and "Virtual core keyboard", therefore I'm doing what Markus proposed. e.g. id="$(xinput list --id-only pointer:'SIGMACHIP Usb Mouse')" xinput --set-prop $id 'Evdev Wheel Emulation' 1 xinput --set-prop $id 'Evdev Wheel Emulation Button' 2 which enables scrolling via middle mouse button click. Thanks.Crosswalk
For some reason adding the tag pointer: works, in other words xinput list --id-only pointer:'the name' prints the mouse device ID correctlyAjax
I know I am late to the party, but I wanted to keep this working for those who may have the same issues. I was having a similar problem - every time i connected my Keyboard it would get a new ID, and I wanted to switch the 'Alt' and the 'super key' on my mac keyboard so they will match. I used: setxkbmap -device "$(xinput list --id-only 'Kinesis KB800MB-BT Keyboard')" -option altwin:swap_alt_win worked like a charm.Wistful
A
19

You can do something like the following.

if [ "$SEARCH" = "" ]; then 
    exit 1
fi

ids=$(xinput --list | awk -v search="$SEARCH" \
    '$0 ~ search {match($0, /id=[0-9]+/);\
                  if (RSTART) \
                    print substr($0, RSTART+3, RLENGTH-3)\
                 }'\
     )

for i in $ids
do
    xinput set-prop $i 'Device Accel Profile' -1
    xinput set-prop $i 'Device Accel Constant Deceleration' 2.5
    xinput set-prop $i 'Device Accel Velocity Scaling' 1.0
done

So with this you first find all the IDs which match the search pattern $SEARCH and store them in $ids. Then you loop over the IDs and execute the three xinput commands.

You should make sure that $SEARCH does not match to much, since this could result in undesired behavior.

Aylsworth answered 12/9, 2013 at 6:31 Comment(2)
Can I call this directly from ~/.xinputrc? It seems like that file gets sourced but I'm not sure.Mongrelize
@JarettMillard Yes this looks like a good place to put the script above. But maybe you use the approach of @Schoenix or @SergiyKolodyazhnyy and make the resulting script executable. To then only add /path/to/new_script NAME_OF_DEVICE OTHER_OPT to .xinputrc.Aylsworth
Q
8

My 2 cents for a Logitech Gaming Mouse G502

#!/bin/sh


for id in `xinput --list|grep 'Logitech Gaming Mouse G502'|perl -ne 'while (m/id=(\d+)/g){print "$1\n";}'`; do
    # echo "setting device ID $id"
    notify-send -t 50000  'Mouse fixed'
    xinput set-prop $id "Device Accel Velocity Scaling" 1
    xinput set-prop $id "Device Accel Constant Deceleration" 3
done 
Quarterstaff answered 1/10, 2016 at 9:6 Comment(0)
N
4

For the fun of it, same answer, but simpler way to parse and get ids:

for id in $(xinput list | grep 'Logitech USB Receiver' |  grep pointer | cut -d '=' -f 2 | cut -f 1); do xinput --set-button-map $id 3 2 1; done

Took me a while to figure out this can get the ids:

xinput | cut -d '=' -f 2 | cut -f 1
Nodular answered 7/2, 2019 at 18:43 Comment(0)
B
3

I did it like the Answer of Raphael Ahrens but used grep and sed instead of awk and The command is now something like my_script part_of_device_name part_of_property_name_(spaces with \space) value:

#!/bin/sh

DEVICE=$1
PROP=$2
VAL=$3

DEFAULT="Default"

if [ "$DEVICE" = "" ]; then 
    exit 1
fi

if [ "$PROP" = "" ]; then 
    exit 1
fi

if [ "$VAL" = "" ]; then 
    exit 1
fi

devlist=$(xinput --list | grep "$DEVICE" | sed -n 's/.*id=\([0-9]\+\).*/\1/p')

for dev in $devlist
do
    props=$(xinput list-props $dev | grep "$PROP" | grep -v $DEFAULT | sed -n 's/.*(\([0-9]\+\)).*/\1/p')

    for prop in $props
    do
        echo $prop
        xinput set-prop $dev $prop $VAL 
    done 
done
Burdett answered 23/11, 2016 at 17:55 Comment(0)
T
1

Currently I am working on a script for a question over at askubuntu.com , which requires something similar, and I thought I'd share the simple python script that does pretty much what this question asks - find device ids and set properties:

The Script

from __future__ import print_function
import subprocess
import sys

def run_cmd(cmdlist):
    """ Reusable function for running shell commands"""
    try:
        stdout = subprocess.check_output(cmdlist)
    except subprocess.CalledProcessError as pserror:
        sys.exit(1)
    else:
        if stdout:
            return stdout.decode().strip()

def list_ids(mouse_name):
    """ Returns list of ids for the same device"""
    while True:
        mouse_ids = []
        for dev_id in run_cmd(['xinput','list','--id-only']).split('\n'):
            if mouse_name in run_cmd(['xinput','list','--name-only',dev_id]):
                mouse_ids.append(dev_id)
        if mouse_ids:
           break
    return mouse_ids

"""dictionary of propery-value pairs"""
props = { 'Device Accel Profile':'-1',
          'Device Accel Constant Deceleration':'2.5',
          'Device Accel Velocity Scaling':'1.0'   }

""" set all property-value pair per each device id
    Uncomment the print function if you wish to know
    which ids have been altered for double-checking
    with xinput list-props"""
for dev_id in list_ids(sys.argv[1]):
    # print(dev_id)
    for prop,value in props.items():
        run_cmd(['xinput','set-prop',dev_id,prop,value]) 

Usage

Provide quoted name of the mouse as first command line argument:

python set_xinput_props.py 'Logitech G700 Laser Mouse'

If everything is OK, script exits silently, with exit status of 0 , or 1 if any xinput command failed. You can uncomment print statement to show which ids are being configured (to later double check with xinput that values are set alright)

How it works:

Essentially, list_ids function lists all device ids , finds those devices that have the same name as user's mouse name and returns a list of those ids. Next we simply loop over each one of them, and of each one we set all the property-value pairs that are defined in props dictionary. Could be done with list of tuples as well, but dictionary is my choice here.

Teaching answered 6/8, 2016 at 5:9 Comment(0)
B
0

Update: Add Pointer or Keyboard as a prefix to the device name.

LINUX:~$ xinput --set-prop "Logitech MX Master 2S" 157 5 0 0 0 5 0 0 0 1

Warning: There are multiple devices matching 'Logitech MX Master 2S'. To ensure the correct one is selected, please use the device ID, or prefix the device name with 'pointer:' or 'keyboard:' as appropriate.

unable to find device pointer

#Solution

LINUX:~$ xinput --set-prop "pointer:Logitech MX Master 2S" 157 5 0 0 0 5 0 0 0 1

Beowulf answered 20/7, 2021 at 15:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.