Conjunto de desaceleração do mouse - como?

2

Introdução: O comando xinput me permite configurar o parâmetro de desaceleração do meu mouse, o que eu tenho que fazer, porque eu gosto da sensibilidade do mouse e o menor valor no Ubuntu ainda é um pouco alto demais para mim. Então eu uso:

szczepan@szczepan-550P5C:~$ xinput list
⎡ Virtual core pointer                      id=2    [master pointer  (3)]
⎜   ↳ Virtual core XTEST pointer                id=4    [slave  pointer  (2)]
⎜   ↳ A4TECH USB Device                         id=10   [slave  pointer  (2)]
⎜   ↳ A4TECH USB Device                         id=11   [slave  pointer  (2)]
⎜   ↳ SynPS/2 Synaptics TouchPad                id=14   [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)]
    ↳ Video Bus                                 id=8    [slave  keyboard (3)]
    ↳ Power Button                              id=9    [slave  keyboard (3)]
    ↳ WebCam SC-13HDL11939N                     id=12   [slave  keyboard (3)]
    ↳ AT Translated Set 2 keyboard              id=13   [slave  keyboard (3)]
szczepan@szczepan-550P5C:~$ xinput set-prop 11 "Device Accel Constant Deceleration" 5

... e está tudo bem. Mas eu tenho que usar esses comandos toda vez que eu ligar meu dispositivo, faça o login depois de desligar / dormir.

A minha pergunta: é possível forçar o Ubuntu, cada vez que este processo é detectado, a definir o parâmetro "Device Accel Constant Deceleration" para o dispositivo A4TECH USB como 5? E se sim, como posso fazer isso? Obrigado por todo o esforço antecipadamente.

    
por Szczepan 04.08.2016 / 13:21

1 resposta

4

Introdução

O script abaixo espera que o dispositivo definido pelo usuário seja conectado e define os valores apropriados, repetindo continuamente o processo, permitindo que o usuário conecte e desconecte o dispositivo várias vezes durante a sessão.

Ele lê as configurações definidas pelo usuário no arquivo ~/.xinputmonrc , que deve ser criado antes de iniciar o script

Uso

Como mostrado por -h option:

usage: xinput_monitor.py [-h] [-q] -d DEVICE

Script that waits for presence of user device and sets preferences as defined in
~/.xinputmonrc file

optional arguments:
  -h, --help            show this help message and exit
  -q, --quiet           Blocks on-screen notifications
  -d DEVICE, --device DEVICE
                        device name

OBSERVAÇÃO : conforme indicado na descrição, o arquivo lê ~/.xinputmonrc , em que ~ é seu diretório pessoal. Exemplo de tal arquivo (uso da matriz de notas para propriedades que exigem vários valores):

{
 "Device Accel Constant Deceleration":5,
 "Evdev Scrolling Distance":[1,1,1]
}

Suponha que temos Logitech USB Receiver dispositivo listado em xinput output. O script pode ser chamado assim:

python3 xinput_monitor.py -d "Logitech USB Receiver"

O script emitirá uma notificação de que o monitoramento foi iniciado:

Quandoodispositivoestiverconectado,eleemitiráumanotificaçãodequeodispositivofoidetectado:

SetudoestiverOK,oscriptprosseguesilenciosamenteeaguardaatéqueodispositivosejadesconectado:

Aopção-qpermitesilenciartodasasbolhasdenotificação.

Obtendooscript

Ocódigo-fonteestádisponívelnestepostecomo Gist no Github

Você pode copiar o código-fonte daqui, salvá-lo como xinput_monitor.py e tornar executável com o comando chmod +x xinput_monitor.py terminal no diretório que você salvou.

Código-fonte

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Author: Sergiy Kolodyazhnyy
Date:  August 2nd, 2016
Written for: https://askubuntu.com/q/806212/295286
Tested on Ubuntu 16.04 LTS

usage: xinput_monitor.py [-h] [-q] -d DEVICE

Script that waits for presence of user device 
and sets preferences as defined
in ~/.xinputmonrc file

optional arguments:
  -h, --help            show this help message and exit
  -q, --quiet           Blocks on-screen notifications
  -d DEVICE, --device DEVICE
                        device name

"""
from __future__ import print_function
import gi
gi.require_version('Notify', '0.7')
from gi.repository import Notify
import subprocess
import argparse
import time
import json
import os

def send_notif(n,title, text):
    try:
        if Notify.init(__file__):
            # n = Notify.Notification.new("Notify")
            n.update(title, text)
            n.set_urgency(2)
            if not n.show():
                raise SyntaxError("sending notification failed!")
        else:
            raise SyntaxError("can't initialize notification!")
    except SyntaxError as error:
        print(error)
        if error == "sending notification failed!":
            Notify.uninit()
    else:
        Notify.uninit()

def run_cmd(cmdlist):
    """ Reusable function for running shell commands"""
    try:
        stdout = subprocess.check_output(cmdlist)
    except subprocess.CalledProcessError as pserror:
        return pserror.output.decode().strip()
        #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)
    return mouse_ids

def read_config_file(notif):

    """ reads ~/.xinputmonrc  file """
    rcfile = os.path.join( os.path.expanduser('~'),'.xinputmonrc')
    try:
        with open(rcfile) as config_file:
            config_data = json.load(config_file)
    except IOError as error:
        send_notif(notif, __file__ , error.__repr__()  )
    else:
        if config_data:
            return config_data

def set_props(notif,device):
    """Sets properties per each device is
       given by list_ids() function"""

    props = read_config_file(notif)
    # Thiscan also be set manually as in 
    # commented-out example below

    #props = { 'Device Accel Profile':'-1',
    #          'Device Accel Constant Deceleration':'3.5',
    #          'Device Accel Velocity Scaling':'1.0'   }

    if not props:
        send_notif(notif,'Reading ~/.xinputmonrc failed', 
                   'Please write proper rc file.') 
        return None
    """ 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(device):
        # print(dev_id)
        for prop,value in props.items():
            if type(value) is not list: 
                value = [value]
            run_cmd(['xinput','set-prop',dev_id,prop] + 
                    [str(item) for item in value ])  

def parse_args():
    """ Parse command line arguments"""
    arg_parser = argparse.ArgumentParser(
                 description="""Script that waits for """ + 
                             """presence of user device """+ 
                             """and sets preferences as """ + 
                             """defined in ~/.xinputmonrc file""")
    arg_parser.add_argument(
                '-q','--quiet', action='store_true',
                help='Blocks on-screen notifications',
                required=False)

    arg_parser.add_argument(
                '-d','--device', 
                help='device name',
                type=str,
                required=True)
    return arg_parser.parse_args()

def main():
    notif = Notify.Notification.new("Notify")
    args = parse_args()
    while True:
         if not args.quiet:
             send_notif(notif, __file__ , 
                        'Wating for ' + args.device )
         while args.device not in run_cmd(['xinput','list','--name-only']):
             time.sleep(0.25)
             pass
         time.sleep(0.25) # let xinput catch up
         if not args.quiet:
             send_notif(notif, __file__, 
                        args.device + ' connected. Setting values')
         # set props here
         set_props(notif,args.device)
         while args.device in run_cmd(['xinput','list','--name-only']):
             time.sleep(0.25)
             pass
         if not args.quiet:
             send_notif( notif , __file__ , args.device +  
                         ' disconnected. Resuming monitoring' )

if __name__ == '__main__':
    main()

Notas

  • Várias instâncias podem ser iniciadas para monitorar vários dispositivos, mas isso não é recomendado porque várias instâncias lêem o mesmo arquivo de configuração.
  • O script é python 3 e python 2 compatible, pode ser executado com qualquer um deles.
  • Consultar Como posso editar / criar novos itens de iniciador no Unity manualmente? para criar um atalho ou atalho na área de trabalho para este script, se você deseja iniciá-lo com um clique duplo
  • Para vincular esse script a um atalho de teclado para facilitar o acesso, consulte Como adicionar atalhos de teclado?
por Sergiy Kolodyazhnyy 06.08.2016 / 23:08