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

8

Я сделал скрипт для поворота планшета 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 /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 / видна только его пользователю)
Redsandro
источник

Ответы:

3

Существует довольно простой обходной путь, вы можете добавить что-то вроде этого к себе 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

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

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

derobert
источник
Ничего себе, после стольких поисков в Google, я никогда не сталкивался с этим. Я проголосовал за ваш ответ. Я попробую это, когда буду на работе. Есть какая-то конкретная причина 55? Я всегда использую идею, что «бесчисленные записи обрабатываются последними, поэтому лучше пропустить числа для пользовательских записей».
Redsandro
@Redsandro /usr/share/X11/xorg.conf.d/50-wacom.conf50 в моей системе, поэтому я выбрал 55, чтобы последовать за ним. Не уверен, что даже имеет значение.
Дероберт
Этот ответ предоставляет полезную информацию, но не отвечает на оригинальный вопрос. Что если вы подключите устройство USB Wacom после запуска X-сервера?
Lqueryvg
1
@Lqueryvg InputClass применяется к устройствам с горячим подключением, поэтому он также должен работать.
Дероберт
@ derobert, спасибо за ответ. Я не осознавал, что InputClass работает и для hotplug. У меня есть некоторые события кнопок, которые я отображаю с помощью xsetwacom, и я хотел бы вызвать их, если я подключу планшет к сети после запуска X. Я дам это попробовать. Спасибо !
Lqueryvg
2

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

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

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

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

Жиль "ТАК - перестань быть злым"
источник
Я уточнил ваш ответ для деталей, но я не уверен, что это правильно по следующей причине: я пытался использовать sleepс кучей секунд. При подключении планшет работает менее чем за секунду, поэтому к моменту выполнения команд устройство уже обнаруживается и используется X. Но все равно это не работает?
Redsandro
2

Это работает, если вы создаете два файла, один скрипт-обертка вызывается 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"
Адриан
источник
2

Ни один из ответов здесь не работал для меня, и параметры, которые я хотел установить, не могли быть указаны в 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"Позволяет другим Systemd услуги (системные или пользовательские), зависит от устройства (регистрирует его в качестве блока устройства см man systemd.device). Чтобы узнать название устройства, запустите udevadm monitorи подключите планшет. я получил

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

Чтобы проверить, что systemd собирает его, выполните

$ 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. Проблема с oneshot в том, что он блокировал 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'
} &
spelufo
источник
Я не знаю , почему это было не так в вашем сценарии, но я должен был уйти , по крайней мере , \xчтобы \\xв файле службы. В конце концов, мой WantedBy выглядел так: WantedBy=sys-devices-pci0000\:00-0000\:00\:14.0-usb1-1\\x2d4.deviceи теперь они сработали ... раньше, чем не сделали.
Jan
1

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

Предложенное sleepАдрианом обертывание и решение почему-то у меня не работают (Ubuntu 16.04).

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

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

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

То , что я предлагаю здесь другое решение / обходной путь , используя небольшую программу , в которой проще , чем решение по spelufo (который я не пробовал) , но только требует , чтобы установить atпрограмму. ( 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.

Себастьян
источник
Столкнулся с той же проблемой с предложением Адриана, и это исправило его для меня 16.04 Ubuntu. Я сбиваю с толку, как это начало работать at nowбез разветвления. Есть причина для этого? На самом деле с этим atметодом ему даже не нужен скрипт-обертка. Вы можете непосредственно добавить это как .., RUN+="/usr/bin/at now -f script-path":)
Gaurav
Это так безумно, потому что я даже не спал в сценарии, и он работает без него. Я хотел бы знать, что происходит в фоновом режиме, чтобы он работал сat
BozanicJosip