web-dev-qa-db-fra.com

Jeu de décélération de la souris - comment faire?

Introduction: La commande xinput me permet de définir le paramètre de décélération pour ma souris, ce que je dois faire, car j'aime la petite sensibilité de la souris et la plus petite valeur dans Ubuntu est encore un peu trop élevée pour moi. J'utilise donc:

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

... et tout va bien. Mais je dois utiliser ces commandes chaque fois que je branche mon appareil, connectez-vous après éteindre/dormir.

Ma question: est-il possible de forcer Ubuntu, chaque fois que ce périphérique est détecté, à définir le paramètre "Device Accel Constant Deceleration" pour le périphérique A4TECH USB Device sur 5? Et si oui, comment faire? Merci pour tous vos efforts à l'avance.

2
Szczepan

Introduction

Le script ci-dessous attend que le périphérique défini par l'utilisateur soit connecté et définit les valeurs appropriées, répétant le processus en continu, permettant ainsi à l'utilisateur de connecter et de déconnecter le périphérique plusieurs fois pendant la session.

Il lit les paramètres définis par l'utilisateur dans ~/.xinputmonrc fichier, qui doit être créé avant de lancer le script

Usage

Comme le montre -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

[~ # ~] note [~ # ~] : Comme indiqué dans la description, le fichier lit ~/.xinputmonrc~ est votre répertoire personnel. Exemple d'un tel fichier (notez l'utilisation du tableau pour les propriétés qui nécessitent plusieurs valeurs):

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

Supposons que nous ayons Logitech USB Receiver périphérique répertorié dans la sortie xinput. Le script peut être appelé ainsi:

python3 xinput_monitor.py -d "Logitech USB Receiver"

Le script émettra une notification indiquant que la surveillance a commencé:

enter image description here

Une fois l'appareil connecté, il émettra une notification indiquant que l'appareil a été détecté:

enter image description here

Si tout va bien, le script se déroule en silence et attend que l'appareil soit déconnecté:

enter image description here

Le -q L'option permet de faire taire toutes les bulles de notification.

Obtention du script

Le code source est disponible dans cet article et sous la forme Gist on Github

Vous pouvez copier le code source à partir d'ici, l'enregistrer sous xinput_monitor.py, et rendre exécutable avec chmod +x xinput_monitor.py commande de terminal dans le répertoire dans lequel vous l'avez enregistré.

Code source

#!/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 __== '__main__':
    main()

Remarques

4