Por que o xsetwacom não funciona no udev?

8

Fiz um roteiro para girar meu tablet Wacom Bamboo 180 graus. Funciona bem quando eu o executo como eu (usuário) ou root, mas quando iniciado udev(por exemplo, ao conectar o tablet a uma usbporta), não funciona.

Regras do 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

Resultado em /tmp/red-wacom.log :

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

(Observe que o erro no log significa que a regra do udev não é o problema.)

Eu tentei definir um sleepno script, talvez precise de alguns ms. Mas isso não ajuda.

  • Por que esse script não funciona quando chamado diretamente de udev?
    • Como faço para corrigir isso?
  • Posso chamar um script udevcomo um usuário específico? (por exemplo, sincronizar /homecom a unidade de backup externa - / home / fica visível apenas para o usuário)
Redsandro
fonte

Respostas:

3

Existe uma solução bastante fácil, você pode adicionar algo assim ao seu xorg.conf(ou a um arquivo xorg.conf.d, como eu fiz):

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

Verifique a página de manual do wacom (4) para obter detalhes de todas as opções que você pode definir.

(Em teoria, você pode MatchProductconfigurar individualmente o touchpad, a caneta, o apagador etc.), mas quando tentei isso um tempo atrás, o Xorg foi interrompido. O mesmo se eu tentasse fazer a flutuação deles. Mas você não está fazendo nada disso ... e talvez o bug esteja corrigido agora.)

derobert
fonte
Uau, depois de tantas pesquisas no Google, nunca me deparei com isso. Eu votei na sua resposta. Vou experimentá-lo quando estiver no trabalho. Alguma razão específica para 55? Eu sempre uso a idéia de que "inúmeras entradas são processadas por último, por isso é melhor pular números para entradas personalizadas".
Redsandro
@Redsandro /usr/share/X11/xorg.conf.d/50-wacom.conftem 50 anos no meu sistema, então escolhi 55 para ir atrás dele. Não tenho certeza se isso importa.
Derobert
Esta resposta fornece informações úteis, mas não responde à pergunta original. E se você conectar seu dispositivo USB Wacom depois que o servidor X for iniciado?
precisa saber é o seguinte
1
O @Lqueryvg InputClass se aplica a dispositivos hotplugged, portanto também deve funcionar.
Derobert 26/09/15
@derobert, obrigado por responder. Eu não sabia que o InputClass também funcionava para hotplug. Tenho alguns eventos de botão que mapeio usando o xsetwacom e gostaria de acioná-los se eu conectar meu tablet após o X ser iniciado. Vou tentar. Obrigado !
Lqueryvg
2

Quando você conecta o dispositivo:

  1. O Linux detecta o dispositivo e cria uma entrada de dispositivo com base nas regras do udev.
  2. O servidor X detecta o dispositivo.

Você não pode executar xsetwacomantes do estágio 2. Seu script está falhando porque você está executando no estágio 1, quando o X ainda não conhece o dispositivo.

Você pode definir algumas configurações com gnome-settings-daemon. Acredito que ele receba a notificação do novo dispositivo através do D-Bus , mas não sei como é o evento do D-Bus. Tente espionar o ônibus com dbus-monitor.

Gilles 'SO- parar de ser mau'
fonte
Votei sua resposta com mais detalhes, mas não tenho certeza se isso está correto pelo seguinte motivo: Tentei usar sleepcom alguns segundos. Ao conectar, o tablet funciona após menos de um segundo; portanto, quando os comandos são executados, o dispositivo já é detectado e está em uso por X. Mas ainda não funciona?
Redsandro
2

Funciona se você criar dois arquivos, um script de wrapper sendo chamado pelo udev, que por sua vez chama o script de configuração real em segundo plano. O script de configuração precisa dormir por um tempo, para que o X11 tenha tempo para fazer seu trabalho. Aqui está a configuração que eu uso:

Script de wrapper chamado pelo udev (/usr/local/bin/setupwacom.sh):

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

Script de configuração chamado pelo script do 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
fonte
2

Nenhuma das respostas aqui funcionou para mim e as opções que eu queria definir não puderam ser especificadas em 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.

Acabei tendo que iniciar o script com um serviço systemd acionado por uma regra do udev:

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

O ID do fornecedor e do modelo pode ser encontrado em execução lsusbcom o dispositivo conectado.

Para recarregar regras do udev:

$ udevadm control --reload-rules
$ udevadm trigger

O TAG+="systemd"permite que outros serviços Systemd (sistema ou utilizador) para dependem do dispositivo (registra-lo como um dispositivo de unidade, ver man systemd.device). Para encontrar o nome da unidade do dispositivo, execute udevadm monitore conecte o tablet. eu recebo

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

Para verificar se o systemd está pegando, faça

$ 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

Portanto, a unidade do dispositivo é sys-devices-pci0000:00-0000:00:1d.0-usb2-2\x2d1-2\x2d1.3.devicee pode ser usada na unidade de serviço do 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

Há uma unidade de dispositivo por porta USB.

Ative e recarregue a unidade com systemctl --user enable wacom.servicee systemctl --user daemon-reload.

O script ainda precisa dormir um pouco para o xsetwacom encontrar o dispositivo e definir $DISPLAYe $XAUTHORITY. Type=oneshotfunciona bem ao conectá-lo, mas não o executa se o dispositivo já estiver conectado ao inicializar o computador. É por isso que eu precisava usar um serviço de usuário em vez de um sistema, e por que a unidade também possui WantedBy=default.target. O problema com o oneshot é que ele estava bloqueando o startx. Type=forkinge Restart=nodiz ao systemd para não esperar o processo bifurcado do script sair, para que o script possa dormir em segundo plano, esperando o Xorg iniciar.

$ 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
fonte
Não sei por que não foi o caso no seu cenário, mas tive que escapar pelo menos do \xpara \\xo arquivo de serviço. Meu WantedBy ficou assim no final: WantedBy=sys-devices-pci0000\:00-0000\:00\:14.0-usb1-1\\x2d4.devicee agora eles são acionados ... antes que não.
Jan
1

A solução alternativa do derobert não é adequada para todas as situações (se você não pode usar o xorg.conf).

O envoltório e a sleepsolução propostos por Adrian de alguma forma não estão funcionando para mim (ubuntu 16.04).

Se você adicionar isso à parte superior do seu script xsetwacom:

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

Você pode ver na saída que o script xsetwacom de alguma forma ainda é executado antes de xinputconhecer o wacom. Não importa quanto tempo você durma.

O que proponho aqui é outra solução / solução alternativa, usando o pequeno programa no qual é mais simples que a solução do spelufo (que eu não tentei), mas requer apenas a instalação do atprograma. ( sudo apt install atpara usuários debian).

Agora mude seu script de wrapper (resposta de Adrian) para algo como isto:

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

atnormalmente é usado para agendar um comando uma vez, você pode, por exemplo, agendar uma hora antes at now +1 hours -f yourscript.sh. Mas como você só pode adicionar minutos / horas / dias / semanas, usei nowsem adição, mas confio no sono dentro do script xsetwacom.

Sebastian
fonte
Enfrentou o mesmo problema com a sugestão de Adrian e isso corrigiu para mim no Ubuntu 16.04. Eu me confunde como começou a trabalhar at nowsem nenhum garfo. Alguma razão para isso? Na verdade, com o atmétodo, ele nem precisa do script do wrapper. Você pode adicioná-lo diretamente como .., RUN+="/usr/bin/at now -f script-path":)
Gaurav
Isso é tão louco, já que eu nem dormi no script e está funcionando sem ele. Gostaria de saber o que está acontecendo em segundo plano para que ele esteja funcionandoat
BozanicJosip