Le touchpad, je ne m'en sers que quand je ne peux pas faire autrement,
c'est-à-dire quand je n'ai pas de souris. Par contre quand il est actif il me
gène plus qu'autre chose et l'activité des mains sur le clavier provoque bien
des erreurs. Il y a bien une touche de fonction prévue à cet usage sur mon
ordinateur mais elle ne fonctionne pas nativement dans mon environnement de
travail (Archlinux Openbox). Aussi je l'avais tout simplement (et
paresseusement) désactivé en mettant dans mon autostart la première commande
trouvée sur le web :
$ /usr/bin/synclient TouchpadOff=1 &
Curieusement cela n'affecte que le déplacement du pointeur, mais pas l'activité
des boutons. ClickPad=0 résolvait partiellement le problème (le simple clic,
mais pas le double) mais la recherche commençait à devenir pénible et je
sentais bien que si je voulais une solution pérenne il me fallait reprendre le
problème à la base. En l’occurrence la base c'est xorg (tant que Wayland n'aura
pas définitivement remplacé xorg), et ça tombe bien, chez xorg ils ont commis
un petit outil en ligne de commande pour gérer les périphériques d'entrée :
xinput (que vous trouverez dans le paquet xorg-xinput de toutes les bonnes
distributions).
Voici donc ma démarche et le petit script qui en résulte (voir à la fin de
l'article). À adapter en fonction des besoins et du matériel.
Les objectifs :
- fonctionner en bascule pour être intégré avec la susdite touche de
fonction
- détecter la présence ou non d'une souris au démarrage de ma session et
désactiver le touchpad en fonction
- afficher le résultat sous forme de notification
- tout ceci indépendamment de l'environnement graphique
Vérifier les dépendances
avant toute chose vérifier que xinput est disponible, sinon ce n'est pas la
peine d'aller plus loin.
if !
command -v xinput
>/dev/null
; then
notify-send --icon=dialog-error -t 7000
$Titre "Dépendance xorg-xinput non trouvée"
2>/tmp/touchpadError
exit 1
fi
Pour bénéficier des notifications il faut que libnotify soit installé (voir
ci-dessous) mais le message d'erreur éventuel sera enregistré dans /tmp
Prise en main de xinput
la commande xinput sans paramètre liste les périphériques détectés. Voici ce
que cela donne chez moi :
[vincent@Astor ~]$ xinput
⎡ Virtual core pointer id=2 [master pointer (3)]
⎜ ↳ Virtual core XTEST pointer id=4 [slave pointer (2)]
⎜ ↳ Logitech USB Receiver id=10 [slave pointer (2)]
⎜ ↳ Logitech USB Receiver id=11 [slave pointer (2)]
⎜ ↳ ETPS/2 Elantech Touchpad id=15 [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)]
↳ Sleep Button id=9 [slave keyboard (3)]
↳ USB2.0 HD UVC WebCam id=12 [slave keyboard (3)]
↳ Asus WMI hotkeys id=13 [slave keyboard (3)]
↳ AT Translated Set 2 keyboard id=14 [slave keyboard (3)]
Les renseignements qui nous intéressent sont le nom et l'identifiant. Ici on
peut voir mon touchpad (ETPS/2 Elantech Touchpad, id=15) et ma souris (Logitech
USB Receiver, id=10 et 11).
Pour aller plus loin une lecture de man s'impose. Les commande pour activer
et désactiver un périphérique sont :
$ xinput enable identifiant
$ xinput disable identifiant
Arf... et évidement l'identifiant peut changer d'un boot à l'autre. Il
faudra donc le lire. Quelque chose comme
DevID=$(xinput | grep "$NomTouchpad"
| cut -d"=" -f2 | cut -d $'\\x09' -f1)
ou $NomTouchpad contient le nom du périphérique (ici ETPS/2 Elantech
Touchpad)
Évidement si l'on ne trouve pas de touchpad (désactivé dans le BIOS ?) on
s’arrêtera là :
if [[ -z $DevID ]];
then
notify-send --icon=dialog-info -t 5000
$Titre "Touchpad non
trouvé"
exit 0
fi
Pour savoir l'état d'un périphérique (actif ou nom) la commande est
$ xinput list-props identifiant
Le résultat donne ceci (c'est la 2ème ligne qui nous intéresse) :
$ xinput list-props 15
Device 'ETPS/2 Elantech Touchpad':
Device Enabled (135): 0
Coordinate Transformation Matrix (137): 1.000000, 0.000000...etc.
ici la ligne "Device Enabled (135) : 0"
nous indique que le
touchpad n'est pas actif. Pour isoler la variable on peut faire quelque chose
comme ça :
Enabled=$(xinput list-props $DevID | grep Enabled | tail -c2)
Il suffit donc de tester cette variable pour connaître la commande à lancer.
Voilà pour le fonctionnement en bascule.
Automatiser la désactivation au démarrage si une souris est détectée
Autant pour la détection du touchpad on peut estimer que le matériel
n'évoluera pas pendant la durée de vie de l'ordinateur, autant on peut
considérer que changer de souris, ne serait-ce qu’occasionnellement, ça doit
pouvoir s'envisager. Donc repérer le périphérique par son nom ne semble pas une
bonne idée.
En revanche si l'on observe la liste issue de la commande xinput ci-dessus
on voit que la rubrique Virtual Core Pointer ne contient d'autre matériel que
le touchpad et la souris. Donc si l'on ne retient que les lignes contenant le
mot "pointeur" et ne contenant pas le mot "Virtual", et qu'il y en a au moins
2, ce serait bien le diable s'il n'y avait pas une souris la dedans. Il y a
d'autres solutions possibles, notamment lsusb ou lshw, mais outre que cela
créerait une dépendance supplémentaire, je n'ai pas trouvé de formulation aussi
simple.
Pour savoir si le script est appelé au démarrage on recherchera un paramètre
d'appel que l'on aura placé sur la ligne de commande. Et si oui on ne le
poursuivra que dans la mesure ou on supposera l'existence d'une souris.
if [[ $1 == "autostart"
]];
then
if (( $(xinput |
grep pointer
|
grep -vc Virtual
) < 2
));
then exit 0
; fi
fi
Si le touchpad a été désactivé par erreur un simple appel de la touche de
fonction associé le rétablira.
En matière d'autostart la solution la plus standard me semble la création
d'un fichier desktop dans $XDG_CONFIG_HOME/autostart/ (généralement
~/.config/autostart). Ça devrait ressembler à ça :
[Desktop Entry]
Name=TouchpadToggle
GenericName=Touchpad Toggle
Comment=Activation désactivation du touchpad
Exec=touchpadtoggle autostart
Terminal=false
Type=Application
Categories=System;
StartupNotify=false
À noter le paramètre autostart passé sur la ligne de commande et évoqué plus
haut pour distinguer l'appel initial d'un appel par la touche de fonction.
Gestion des notifications
Bon, ce n'est pas essentiel, mais tant qu'à faire... La dépendance à
installer est libnotify, qui est également dans toutes les distributions. La
commande est
$ notify-send [-i icon] [-t millisecondes] [titre] message
Les icônes seront nommées selon les
spécification de la freedesktop organisation. Le rendu pourra être
différent d'un environnement à l'autre et je ne l'ai testé que sous OpenBox et
KDE, j'espère que ça marche partout.
Association à une touche de fonction
Bien sûr il est aisé d'utiliser les raccourcis clavier de l'environnement de
bureau que l'on utilise, mais puisque l'on recherche une solution qui marche
partout on préférera Xbindkeys. Ça marche avec toutes les touches de fonction
et c'est indépendant des environnement de bureau. Après installation (paquet
disponible dans toutes les distributions) pensez immédiatement à créer un
fichier de configuration vide à la racine de votre répertoire personnel sans
quoi vous auriez un message d'erreur à la première utilisation.
$ touch ~/.xbindkeysrc
Ensuite il faut définir la touche à utiliser. Dans mon cas fn→F9
$ xbindkeys -k
Cela provoque l'ouverture d'une petite fenêtre blanche et l'invite à choisir
une clef ou une action souris. À la suite de quoi le résultat s'affichera dans
le terminal sous cette forme :
You can use one of the two lines after "NoCommand"
in $HOME/.xbindkeysrc to bind a key.
"(Scheme function)"
m:0x10 + c:199
Mod2 + XF86TouchpadToggle
Plus clairement cela nous convie à éditer le fichier de config
(~/.xbindkeysrc) et à saisir successivement la commande à exécuter et la clef
associée, soit sous forme de couple modificateur / N° de clef (ici m:0x10 +
c:199), soit sous forme de nom symbolique (Mod2 + XF86TouchpadToggle). Dans mon
cas l'une des deux formules suivante :
# Activation / désactivation du touchpad
"touchpadtoggle"
m:0x10 + c:199
ou encore
# Activation / désactivation du touchpad
"touchpadtoggle"
Mod2 + XF86TouchpadToggle
enfin n'oubliez pas de rajouter xbindkeys
avant la ligne qui
démarre votre gestionnaire de fenêtre dans votre ~/.xinitrc
Récapitulatif
Si la solution vous intéresse :
- Installez si ce n'est déjà fait xorg-xinput, xbindkey et libnotyfy.
- Copiez le script ci-dessous dans un répertoire figurant dans votre $PATH
(
/usr/local/bin
semble approprié), nommez le touchpadtoggle et
rendez le exécutable (chmod +x /usr/local/bin/touchpadtoggle
)
- Exécutez xinput et repérez la ligne correspondant à votre touchpad.
Personnalisez le script en modifiant le contenu de la variable
NomTouchpad
- Créez un touchpadtoggle.desktop dans votre répertoire ~/.config.autostart
avec les données ci-dessus si vous souhaitez une désactivation automatique à
l'ouverture de votre session.
- Créez un
.xbindkeysrc
vide dans votre Home et rajoutez
xbindkeys dans votre ~/.xinitrc
- Lancez la commande $ xbindkeys -k et récupérer le code de la touche que
vous voulez associer au script puis éditez votre
.xbindkeysrc
en
conséquence.
Voilà, j'espère que je n'ai rien oublié, chez moi ça marche impeccablement.
Dans tous les cas je serais heureux d'avoir votre retour.
Le script
#! /bin/bash
######################################################
## TouchpadToggle ##
## Gestion du touchpad avec xinput ##
## ##
## copyleft vgay at vintherine dot org ##
## version 0.2 du 20140918 ##
## ##
## dépendance obligatoire : xorg-xinput ##
## dépendance optionelle libnotify ##
## et xbindkey pour associer ce script à une touche ##
######################################################
### Personnalisation -> mettez ici le nom de votre touchpad tel que trouvé avec la commande xinput.
NomTouchpad="ETPS/2 Elantech Touchpad"
### Début du script
IFS=$'\\n'
if ! command -v xinput >/dev/null; then
notify-send --icon=dialog-error -t 7000 $Titre "Dépendance xorg-xinput non trouvée" 2>/tmp/touchpadError
exit 1
fi
Cde[0]="xinput enable "
Cde[1]="xinput disable "
Msg[0]="Touchpad désactivé"
Msg[1]="Touchpad activé"
Titre="Gestion du touchpad :"
DevID=$(xinput | grep "$NomTouchpad" | cut -d"=" -f2 | cut -d $'\\x09' -f1)
if [[ -z $DevID ]]; then
notify-send --icon=dialog-information -t 5000 $Titre "Touchpad non trouvé"
exit 0
fi
Enabled=$(xinput list-props $DevID | grep Enabled | tail -c2)
if [[ $1 == "autostart" ]]; then
if (( $(xinput | grep pointer | grep -vc Virtual) < 2 )); then exit 0; fi
fi
Message=$(eval ${Cde[$Enabled]}$DevID 2>&1)
Enabled=$(xinput list-props $DevID | grep Enabled | tail -c2)
if [[ -z $Message ]]; then
notify-send --icon=dialog-information -t 5000 $Titre ${Msg[$Enabled]}
else
notify-send --icon=dialog-error -t 7000 $Titre $Message
fi
Original post of Vincent Gay.Votez pour ce billet sur Planet Libre.