Почему 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 / видна только его пользователю)

Ответы:


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


Ничего себе, после стольких поисков в 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'
} &

Я не знаю , почему это было не так в вашем сценарии, но я должен был уйти , по крайней мере , \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
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.