TouchpadToggle : Gestion du touchpad
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.
- 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; thennotify-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 ]]; thennotify-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" ]]; thenif (( $(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