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-q
permitesilenciartodasasbolhasdenotificação.
Obtendooscript
Ocódigo-fonteestádisponívelnestepostecomo
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
epython 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?