Pourquoi xsetwacom ne fonctionne-t-il pas avec udev?

8

J'ai fait un script pour faire pivoter ma tablette Wacom Bamboo de 180 degrés. Cela fonctionne bien lorsque je l'exécute en tant que moi-même (utilisateur) ou root, mais lorsqu'il est démarré à partir de udev(c'est-à-dire lorsque vous branchez la tablette sur un usbport), cela ne fonctionnera pas.

Règles Udev :

SUBSYSTEMS=="usb", ATTRS{idVendor}=="056a", ATTRS{idProduct}=="00d1", ATTRS{manufacturer}=="Wacom Co.,Ltd.", RUN+="/usr/local/bin/red-wacom-bamboo.sh"

Script Wacom /usr/local/bin/red-wacom-bamboo.sh :

#!/usr/bin/env bash

exec > /tmp/red-wacom.log
exec 2>&1

# I had to do this otherwise xsetwacom would say:
# "Failed to open Display ."
# Is there a way to do this without using my username?
export XAUTHORITY=/home/redsandro/.Xauthority
export DISPLAY=:0

/usr/bin/xsetwacom set "Wacom Bamboo 2FG 4x5 Pen stylus" Rotate half
/usr/bin/xsetwacom set "Wacom Bamboo 2FG 4x5 Finger touch" Rotate half

Résultat dans /tmp/red-wacom.log :

Cannot find device 'Wacom Bamboo 2FG 4x5 Pen stylus'.
Cannot find device 'Wacom Bamboo 2FG 4x5 Finger touch'.

(Notez que l'erreur dans le journal signifie que la règle udev elle-même n'est pas le problème.)

J'ai essayé de mettre un sleepdans le script, peut-être qu'il a besoin de quelques ms. Mais ça n'aide pas.

  • Pourquoi ce script ne fonctionne-t-il pas lorsqu'il est appelé directement depuis udev?
    • Comment puis-je réparer ça?
  • Puis-je appeler un script à partir udevd'un utilisateur spécifique? (par exemple, la synchronisation /homeavec le lecteur de sauvegarde externe - / home / n'est visible que par son utilisateur)
Redsandro
la source

Réponses:

3

Il existe une solution assez simple, vous pouvez ajouter quelque chose comme ça à votre xorg.conf(ou à un fichier xorg.conf.d, comme je l'ai fait):

anthony@Watt:/etc/X11/xorg.conf.d$ cat 55-local-wacom.conf 
Section "InputClass"
       Identifier "Wacom Left Handed"
       MatchDriver "wacom"
       Option "Rotate" "half"
EndSection

Consultez la page de manuel de wacom (4) pour plus de détails sur toutes les options que vous pouvez définir.

(En théorie, vous pouvez utiliser MatchProductpour configurer individuellement le pavé tactile, le stylo, la gomme, etc., mais quand j'ai essayé cela il y a quelque temps, cela a causé un défaut de configuration à Xorg. Même si j'ai essayé de les faire flotter. Mais vous ne faites pas de de cela ... et peut-être que le bug est corrigé maintenant.)

derobert
la source
Wow, après tant de recherches sur Google, je ne suis jamais tombé sur ça. J'ai voté pour votre réponse. Je vais l'essayer quand je serai au travail. Une raison précise pour 55? J'utilise toujours l'idée que "les entrées sans nombre sont traitées en dernier, il est donc préférable d'ignorer les numéros pour les entrées personnalisées".
Redsandro
@Redsandro a /usr/share/X11/xorg.conf.d/50-wacom.conf50 ans sur mon système, j'ai donc choisi 55 pour venir après. Pas sûr que ça compte.
derobert
Cette réponse fournit des informations utiles mais ne répond pas à la question d'origine. Que faire si vous branchez votre périphérique USB Wacom après le démarrage du serveur X?
Lqueryvg
1
@Lqueryvg InputClass s'applique aux périphériques branchés à chaud, donc cela devrait fonctionner aussi.
derobert
@derobert, merci d'avoir répondu. Je ne savais pas que InputClass fonctionnait aussi pour hotplug. J'ai des événements de bouton que je mappe à l'aide de xsetwacom et je voudrais les déclencher si je branche ma tablette à chaud après le démarrage de X. Je veux bien essayer. Merci !
Lqueryvg
2

Lorsque vous branchez l'appareil:

  1. Linux détecte le périphérique et crée une entrée de périphérique basée sur les règles udev.
  2. Le serveur X détecte le périphérique.

Vous ne pouvez pas exécuter xsetwacomavant l'étape 2. Votre script échoue car vous l'exécutez à l'étape 1, lorsque X ne connaît pas encore le périphérique.

Vous pouvez définir certains paramètres avec gnome-settings-daemon. Je pense qu'il reçoit sa notification du nouvel appareil via D-Bus , mais je ne sais pas à quoi ressemble l'événement D-Bus. Essayez d'espionner le bus avec dbus-monitor.

Gilles 'SO- arrête d'être méchant'
la source
J'ai voté pour votre réponse pour les détails, mais je ne suis pas sûr que ce soit correct pour la raison suivante: J'ai essayé d'utiliser sleepavec un tas de secondes. Lors de la connexion, la tablette fonctionne après moins d'une seconde, donc au moment où les commandes sont exécutées, l'appareil est déjà détecté et utilisé par X. Mais ça ne marche toujours pas?
Redsandro
2

Cela fonctionne si vous créez deux fichiers, un script wrapper étant appelé par udev, qui à son tour appelle le script de configuration réel en arrière-plan. Le script de configuration doit être mis en veille brièvement, afin que X11 ait le temps de faire son travail. Voici la configuration que j'utilise:

Script Wrapper appelé par udev (/usr/local/bin/setupwacom.sh):

#!/usr/bin/env bash
/usr/local/bin/setupwacom-post-X11.sh &

Script de configuration appelé par le script wrapper (/usr/local/bin/setupwacom-post-X11.sh):

#!/usr/bin/env bash
sleep 2
export XAUTHORITY=/home/adrian/.Xauthority
export DISPLAY=:0
# Put your xsetwacom commands here, for example: 
xsetwacom --set "Wacom Intuos S Pad pad" Button 1 "key +ctrl +shift e"
Adrian
la source
2

Aucune des réponses ici n'a fonctionné pour moi, et les options que je voulais définir ne pouvaient pas être spécifiées dans xorg.conf:

$ xsetwacom -x get 'Wacom Intuos PT S Pad pad' button 1 
Button: Actions are not supported by xorg.conf. Try shell format (-s) instead.

J'ai fini par devoir démarrer le script avec un service systemd déclenché par une règle udev:

$ cat /etc/udev/rules.d/99-wacom.rules
SUBSYSTEM=="usb", ENV{ID_VENDOR_ID}=="056a", ENV{ID_MODEL_ID}=="0302", TAG+="systemd"

Le fournisseur et l'ID du modèle peuvent être trouvés en cours lsusbd' exécution avec l'appareil branché.

Pour recharger les règles udev:

$ udevadm control --reload-rules
$ udevadm trigger

Le TAG+="systemd"permet aux autres services systemd (système ou utilisateur) de dépendre de l'appareil (l'enregistre comme unité d'appareil, voir man systemd.device). Pour trouver le nom de l'appareil, exécutez udevadm monitoret branchez la tablette. Je reçois

UDEV  [2918.098423] add      /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3 (usb)
...

Pour vérifier que systemd le ramasse, faites

$ systemctl status /sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/
● sys-devices-pci0000:00-0000:00:1d.0-usb2-2\x2d1-2\x2d1.3.device - CTH-480 [Intuos Pen & Touch (S)]
   Loaded: loaded
   Active: active (plugged) since Mon 2016-06-20 11:14:20 UYT; 29min ago
   Device: /sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3

Ainsi, l'unité de périphérique est sys-devices-pci0000:00-0000:00:1d.0-usb2-2\x2d1-2\x2d1.3.device, et elle peut être utilisée dans l'unité de service systemd

 $ cat .config/systemd/user/wacom.service    
[Service]
Type=forking
Restart=no
ExecStart=/path/to/wacom-pad-button-setup

[Install]
WantedBy=default.target
WantedBy=sys-devices-pci0000:00-0000:00:1d.0-usb2-2\x2d1-2\x2d1.1.device
WantedBy=sys-devices-pci0000:00-0000:00:1d.0-usb2-2\x2d1-2\x2d1.2.device
WantedBy=sys-devices-pci0000:00-0000:00:1d.0-usb2-2\x2d1-2\x2d1.3.device

Il y a une unité de périphérique par port USB.

Ensuite, activez et rechargez l'unité avec systemctl --user enable wacom.serviceet systemctl --user daemon-reload.

Le script a encore besoin de dormir un peu pour que xsetwacom trouve le périphérique, et définisse $DISPLAYet $XAUTHORITY. Type=oneshotfonctionne bien lorsque vous le branchez, mais il ne fonctionne pas si l'appareil était déjà branché lors du démarrage de l'ordinateur. C'est pourquoi j'avais besoin d'utiliser un service utilisateur au lieu d'un service système, et pourquoi l'unité aussi WantedBy=default.target. Le problème avec oneshot est qu'il bloquait startx. Type=forkinget Restart=noindique à systemd de ne pas attendre la fin du processus forké du script, afin que le script puisse ensuite dormir en arrière-plan en attendant le démarrage de Xorg.

$ cat bin/wacom-pad-button-setup
#!/bin/rc
{
    sleep 2

    if (~ $DISPLAY ()) {
        DISPLAY=:0
        XAUTHORITY=/home/spelufo/.Xauthority
    }

    xsetwacom set 'Wacom Intuos PT S Pad pad' button 9 'button +3 -3'
    xsetwacom set 'Wacom Intuos PT S Pad pad' button 8 'button +4 -4'
    xsetwacom set 'Wacom Intuos PT S Pad pad' button 3 'button +1 -1'
    xsetwacom set 'Wacom Intuos PT S Pad pad' button 1 'button +2 -2'
} &
spelufo
la source
Je ne sais pas pourquoi ce n'était pas le cas dans votre scénario, mais j'ai dû échapper au moins le \xto \\xdans le fichier de service. Mes WantedBy ressemblaient finalement à ceci: WantedBy=sys-devices-pci0000\:00-0000\:00\:14.0-usb1-1\\x2d4.deviceet maintenant ils sont déclenchés ... avant qu'ils ne le fassent pas.
Jan
1

La solution de contournement de derobert ne convient pas à toutes les situations (si vous ne pouvez pas utiliser le xorg.conf).

L'emballage et la sleepsolution proposés par Adrian ne fonctionnent pas pour moi (ubuntu 16.04).

Si vous ajoutez ceci en haut de votre script xsetwacom:

exec > /tmp/debug-my-script.txt 2>&1
xinput --list

Vous pouvez voir à partir de la sortie que le script xsetwacom est en quelque sorte toujours exécuté avant de xinputconnaître le wacom. Peu importe combien de temps vous dormez.

Ce que je propose ici est une autre solution / solution en utilisant le petit programme à plus simple que la solution par spelufo (que je ne l' ai pas essayé) mais ne demande qu'à installer le atprogramme. ( sudo apt install atpour les utilisateurs de Debian).

Maintenant, changez votre script wrapper (la réponse d'Adrian) en quelque chose comme ceci:

#!/usr/bin/env bash
at now -f /usr/local/bin/setupwacom-post-X11.sh

atest normalement utilisé pour planifier une commande une fois, vous pouvez par exemple planifier une heure à l'avance at now +1 hours -f yourscript.sh. Mais comme vous ne pouvez ajouter que des minutes / heures / jours / semaines, j'ai utilisé nowsans ajout, mais comptez sur le sommeil à l'intérieur du script xsetwacom.

Sébastien
la source
Face au même problème avec la suggestion d'Adrian et cela l'a corrigé pour moi sur 16.04 Ubuntu. Je suis déconcerté par la façon dont il a commencé à fonctionner at nowsans bifurquer. Une raison pour ça? En fait, avec la atméthode, il n'a même pas besoin du script wrapper. Vous pouvez l'ajouter directement comme .., RUN+="/usr/bin/at now -f script-path":)
Gaurav
C'est tellement fou car je n'ai même pas dormi dans le script et ça marche sans. Je souhaite savoir ce qui se passe en arrière-plan pour que ça fonctionneat
BozanicJosip