xinput 的更改随机恢复为默认值

Rat*_*ler 5 touchscreen button xinput stylus remapping

我在带有 ELAN 触摸屏和 DELL 750-AAHC 有源手写笔的笔记本电脑上使用 Kubuntu 16.04(xenial)。触控笔上的一个按钮充当鼠标中键,而我希望它是一个右键。

我可以通过这样做来实现这一目标

$ xinput set-button-map "ELAN Touchscreen Pen" 1 3 2
Run Code Online (Sandbox Code Playgroud)

(即,将必须对应右侧按钮的按钮 3 的功能映射到物理按钮 2)。

这符合我的要求,但这种变化不是永久性的。

我添加了命令~/.xsessionrc(根据这篇文章的答案),所以当我重新启动时它会自动运行,但是“随机”映射的按钮会自行恢复为默认值:它按预期工作了一段时间,突然我发现它没有,所以我明白了

$ xinput get-button-map "ELAN Touchscreen Pen"
1 2 3 4 5
Run Code Online (Sandbox Code Playgroud)

我必须手动重新映射它。

我尝试了一些“可疑”的事情,看看可能是什么原因导致恢复,但我无法弄清楚。这不是由

  • 暂停笔记本电脑或关闭屏幕
  • 旋转屏幕(这是可疑的,因为 xinput 用于旋转来转换输入矩阵。)
  • 打开/关闭触摸屏、触摸板或手写笔输入(也使用 xinput)。

重要更新

我发现这个问题不是触控笔特有的:我之前出于某种原因禁用了屏幕的手指触摸功能(“ELAN 触摸屏”):

$ xinput disable "ELAN Touchscreen"
Run Code Online (Sandbox Code Playgroud)

我刚刚发现它自己回来了(手写笔右键单击又恢复了)。因此,由于这个未知原因,似乎所有 xinput 更改都恢复为默认值。

更新 2

我发现了一些可疑条目 /var/log/syslog再次发生这种情况时,。时间戳是在我有一段时间没有真正使用笔记本电脑的时候,所以节能功能可能被激活(我在 9 分钟时“调暗屏幕”,在 10 分钟时“关闭”;我将尝试节能相应地保存和更新)。

下面的模式实际上重复了很多次,每个块之间只有几秒钟的差异。

usb 1-8: USB disconnect, device number 18
usb 1-8: new full-speed USB device number 19 using xhci_hcd
usb 1-8: New USB device found, idVendor=04f3, idProduct=2073
usb 1-8: New USB device strings: Mfr=4, Product=14, SerialNumber=0
usb 1-8: Product: Touchscreen
usb 1-8: Manufacturer: ELAN
input: ELAN Touchscreen Pen as /devices/pci0000:00/0000:00:14.0/usb1/1-8/1-8:1.0/0003:04F3:2073.04EE/input/input7548
input: ELAN Touchscreen as /devices/pci0000:00/0000:00:14.0/usb1/1-8/1-8:1.0/0003:04F3:2073.04EE/input/input7549
input: ELAN Touchscreen Keyboard as /devices/pci0000:00/0000:00:14.0/usb1/1-8/1-8:1.0/0003:04F3:2073.04EE/input/input7552
hid-multitouch 0003:04F3:2073.04EE: input,hiddev0,hidraw0: USB HID v1.10 Keyboard [ELAN Touchscreen] on usb-0000:00:14.0-8/input0
Run Code Online (Sandbox Code Playgroud)

在每个区块中,除了一些增加的数字外,几乎所有内容都相同。这是用于比较的下一个块:

usb 1-8: USB disconnect, device number 19
usb 1-8: new full-speed USB device number 20 using xhci_hcd
usb 1-8: New USB device found, idVendor=04f3, idProduct=2073
usb 1-8: New USB device strings: Mfr=4, Product=14, SerialNumber=0
usb 1-8: Product: Touchscreen
usb 1-8: Manufacturer: ELAN
input: ELAN Touchscreen Pen as /devices/pci0000:00/0000:00:14.0/usb1/1-8/1-8:1.0/0003:04F3:2073.04EF/input/input7554
input: ELAN Touchscreen as /devices/pci0000:00/0000:00:14.0/usb1/1-8/1-8:1.0/0003:04F3:2073.04EF/input/input7555
input: ELAN Touchscreen Keyboard as /devices/pci0000:00/0000:00:14.0/usb1/1-8/1-8:1.0/0003:04F3:2073.04EF/input/input7558
hid-mul itouch 0003:04F3:2073.04EF: input,hiddev0,hidraw0: USB HID v1.10 Keyboard [ELAN Touchscreen] on usb-0000:00:14.0-8/input0
Run Code Online (Sandbox Code Playgroud)

设备编号环绕在 128 处。

系统

  • KDE 等离子 5.5.5
  • Qt 5.5.1
  • 内核 4.13.0-32-generic #35~16.04.1-Ubuntu 64 位
  • xinput 版本 1.6.2

    服务器上的 XI 版本:2.3

  • X.Org X 服务器 1.19.5

    发布日期:2017-10-12

    X 协议版本 11,修订版 0

stu*_*bee 3

这似乎是一个错误(事实上,触摸屏设备会随机断开连接并作为新设备重新连接,这会产生将所有设置重置为默认值的副作用)。

作为解决方法,您可以创建自己的udev规则(文件名基于Daniel Drake 的建议),该规则将运行一个脚本,每当触摸屏重新连接时,该脚本就会重新应用 xinput 更改:

sudo nano /etc/udev/rules.d/10-custom-elan.rules
Run Code Online (Sandbox Code Playgroud)

并添加此行,其中包含“idVendor”“idProduct”信息(来自您的syslog)。必须使用“elan.sh”绝对路径

ATTRS{idVendor}=="04f3", ATTRS{idProduct}=="2073", RUN+="/home/username/elan.sh"
Run Code Online (Sandbox Code Playgroud)

(大致翻译为“当找到与指定属性匹配的设备时,运行指定的脚本”)。

然后创建实际的脚本来运行xinput

nano /home/username/elan.sh 
Run Code Online (Sandbox Code Playgroud)

包含以下几行:

#!/usr/bin/env bash

#These lines allow the script to be called by udev rules
export DISPLAY=":0"
export XAUTHORITY="/home/username/.Xauthority"

#Command to remap buttons
xinput set-button-map "ELAN Touchscreen Pen" 1 3 2 4 5
Run Code Online (Sandbox Code Playgroud)

当然,让它可执行:

chmod +x /home/username/elan.sh
Run Code Online (Sandbox Code Playgroud)

如果没有导出行,该脚本在由您(活动用户)直接调用时可以工作,但在由 udev(根用户)调用时则不起作用。详细信息可以在这个这个答案中找到,但这里有一个简短的总结:

要在用户桌面上启动图形程序,您需要两件事:地址(用户桌面所在的显示器)和授权。当用户登录时,登录管理器通过生成 cookie 来授权与 X 服务器的连接,将其添加到服务器并通过将其写入 $HOME/.Xauthority 将其传递给用户。那么,root 用户应该能够通过了解用户使用的显示并访问 Xauthority cookie 来进行连接。这就是出口线路所实现的目标。

注意:显示编号是硬编码的事实在某些情况下可能会导致问题,但在这种使用场景(个人笔记本电脑的单个用户)中可能没问题。

  • 差不多就这样了,所以我添加了一些点(主要是脚本中的“导出”语句)以使其成为(最终!)对我有用的完整解决方案。感谢您的帮助! (2认同)