Почему xsetwacom не работает с udev?

Я сделал скрипт, чтобы повернуть мой планшет Wacom Bamboo на 180 градусов. Он отлично работает, когда я выполняю его как сам (пользователь) или root, но при запуске с udev (т. Е. При подключении планшета к порту usb ) это не сработает.

Правила Удева :

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

Wacom script /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 

Результат в /tmp/red-wacom.log :

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

(Обратите внимание, что ошибка в журнале означает, что правило udev само по себе не является проблемой.)

Я попытался установить sleep в скрипте, возможно, ему понадобится несколько мс. Но это не помогает.

  • Почему этот скрипт не работает при вызове непосредственно из udev ?
    • Как это исправить?
  • Можно ли вызвать скрипт из udev в качестве конкретного пользователя? (например, синхронизация /home к внешнему резервному диску – / home / видна только пользователю)

Существует довольно простой способ обхода, вы можете добавить что-то подобное к вашему xorg.conf (или файлу в xorg.conf.d , как я это сделал):

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

Проверьте справочную страницу wacom (4) для получения подробной информации обо всех параметрах, которые вы можете установить.

(В теории вы можете использовать MatchProduct для индивидуальной настройки тачпада, пера, ластика и т. Д., Но когда я попытался это сделать, он заставил Xorg segfault. То же самое, если бы я пытался их плавать. любой из них … и, возможно, ошибка исправлена ​​сейчас.)

Когда вы подключаете устройство:

  1. Linux обнаруживает устройство и создает запись устройства на основе правил udev.
  2. X-сервер обнаруживает устройство.

Вы не можете запустить xsetwacom до этапа 2. Сценарий не работает, потому что вы запускаете его на этапе 1, когда X еще не знает устройство.

Вы можете установить некоторые параметры с помощью gnome-settings-daemon . Я считаю, что он получает уведомление о новом устройстве через D-Bus , но я не знаю, как выглядит событие D-Bus. Попробуйте шпионить за шиной с помощью dbus-monitor .

Он работает, если вы создаете два файла, один скрипт-оболочку вызывается udev, который по очереди вызывает фактический сценарий конфигурации в фоновом режиме. Скрипт конфигурации должен поспать ненадолго, так что X11 успевает выполнить свою работу. Вот настройка, которую я использую:

Сценарий обертки, названный udev (/usr/local/bin/setupwacom.sh):

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

Скрипт конфигурации, вызываемый сценарием оболочки (/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" 

Ни один из ответов здесь не работал, и параметры, которые я хотел установить, не могли быть указаны в 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. 

В итоге мне пришлось запустить скрипт с помощью службы systemd, вызванной правилом udev:

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

Идентификатор поставщика и модель можно найти с помощью lsusb с подключенным устройством.

Чтобы перезагрузить правила udev:

 $ udevadm control --reload-rules $ udevadm trigger 

TAG+="systemd" позволяет другим системным службам (системе или пользователю) зависеть от устройства (регистрирует его как устройство, см. man systemd.device ). Чтобы найти название устройства, запустите udevadm monitor и подключите планшет. я получил

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

Чтобы проверить, что системаd собирает его, сделайте

 $ 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 

Таким образом, устройством является sys-devices-pci0000:00-0000:00:1d.0-usb2-2\x2d1-2\x2d1.3.device , и его можно использовать в сервисном модуле 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 

Существует один блок устройства на каждый USB-порт.

Затем включите и перезагрузите устройство с помощью systemctl --user enable wacom.service и systemctl --user daemon-reload .

Сценарий по-прежнему должен немного уснуть для xsetwacom, чтобы найти устройство, и установить $DISPLAY и $XAUTHORITY . Type=oneshot отлично работает при подключении, но он не запускается, если устройство уже было подключено при загрузке компьютера. Вот почему мне нужно было использовать пользовательскую службу вместо системной, и почему у устройства также есть WantedBy=default.target . Проблема с одним выстрелом заключается в том, что он блокировал startx. Type=forking и Restart=no сообщает systemd не дожидаться выхода из разветвленного процесса скрипта, поэтому скрипт может затем заснуть в фоновом режиме, ожидая начала 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' } & 

Обходной путь derobert не подходит для всех ситуаций (если вы не можете использовать xorg.conf).

Предлагаемое решение Adrian для упаковки и sleep для меня как-то не работает (ubuntu 16.04).

Если вы добавите это в начало скрипта xsetwacom:

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

Вы можете видеть из вывода, что скрипт xsetwacom каким-то образом выполняется до того, как xinput узнает о wacom. Независимо от того, как долго вы спите.

То, что я предлагаю здесь, – это другое решение / обходное решение, использующее небольшую программу, в которой проще, чем решение spelufo (которое я не пытался), а требует установки программы. ( sudo apt install at для пользователей debian).

Теперь измените ваш сценарий оболочки (ответ Адриана) на что-то вроде этого:

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

at обычно используется для планирования команды один раз, вы можете, например, запланировать один час вперед, at now +1 hours -f yourscript.sh . Но поскольку вы можете добавлять только минуты / часы / дни / недели, которые я использовал now без добавления, но полагайтесь на сон внутри скрипта xsetwacom.