为什么 xsetwacom 不能从 udev 工作?

为什么 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 脚本 /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 规则本身不是问题。)

我尝试在脚本中设置 a sleep,也许需要几毫秒。但这没有帮助。

  • 为什么直接从 调用此脚本时不起作用udev
    • 我该如何解决?
  • udev我可以作为特定用户调用脚本吗? (例如同步/home到外部备份驱动器 - /home/ 仅对其用户可见)

答案1

如果您创建两个文件,其中一个包装器脚本由 udev 调用,而 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(或 中的文件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 出现段错误。如果我尝试浮动它们,情况也是如此。但你没有做任何事情那个......也许这个错误现在已经修复了。)

答案3

这里的答案都不适合我,并且无法在以下位置指定我想要设置的选项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.

我最终不得不使用由 udev 规则触发的 systemd 服务来启动脚本:

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

可以找到lsusb插入设备后正在运行的供应商和型号 ID。

重新加载 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$XAUTHORITYType=oneshot插入时工作正常,但如果启动计算机时设备已插入,则不会运行它。这就是为什么我需要使用用户服务而不是系统服务,也是为什么该设备还具有WantedBy=default.target. oneshot 的问题是它阻塞了 startx。Type=forkingRestart=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'
} &

答案4

derobert 的解决方法并不适合所有情况(如果您不能使用 xorg.conf)。

Adrian提出的包装和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 脚本内的睡眠。

相关内容