我正在尝试编写一个 GUI 工具来限制指向特定监视器的指针(例如,触摸屏指针应映射到其自己的屏幕上,而不是跨越所有监视器的联合)。该工具采用 Python 语言(使用 pygtk)。
对于 UI,我需要列出所有指针,以便您可以选择您想要的指针,然后调用xinput map-to-output pointer_id monitor_id
.如果此命令给出非指针设备的 id,则会引发错误,因此我想避免将这些 ID 作为选项提供。
输出xinput list
如下所示:
⎡ Virtual core pointer id=2 [master pointer (3)]
⎜ ↳ Virtual core XTEST pointer id=4 [slave pointer (2)]
⎜ ↳ ELAN Touchscreen id=18 [slave pointer (2)]
⎜ ↳ SynPS/2 Synaptics TouchPad id=21 [slave pointer (2)]
⎜ ↳ TPPS/2 IBM TrackPoint id=22 [slave pointer (2)]
⎜ ↳ Cherry USB Optical Mouse Consumer Control id=10 [slave pointer (2)]
⎜ ↳ Cherry USB Optical Mouse id=12 [slave pointer (2)]
⎜ ↳ HID 04b4:3003 Consumer Control id=14 [slave pointer (2)]
⎜ ↳ HID 04b4:3003 Mouse id=24 [slave pointer (2)]
⎜ ↳ WALTOP Graphics Tablet Pen (0) id=26 [slave pointer (2)]
⎣ Virtual core keyboard id=3 [master keyboard (2)]
↳ Virtual core XTEST keyboard id=5 [slave keyboard (3)]
↳ Power Button id=6 [slave keyboard (3)]
↳ Video Bus id=7 [slave keyboard (3)]
↳ Sleep Button id=8 [slave keyboard (3)]
↳ Integrated Camera: Integrated C id=19 [slave keyboard (3)]
↳ AT Translated Set 2 keyboard id=20 [slave keyboard (3)]
↳ ThinkPad Extra Buttons id=23 [slave keyboard (3)]
↳ Cherry USB Optical Mouse System Control id=9 [slave keyboard (3)]
↳ Cherry USB Optical Mouse Consumer Control id=11 [slave keyboard (3)]
↳ HID 04b4:3003 System Control id=13 [slave keyboard (3)]
↳ HID 04b4:3003 Consumer Control id=15 [slave keyboard (3)]
↳ HID 04b4:3003 Keyboard id=16 [slave keyboard (3)]
↳ HID 04b4:3003 id=17 [slave keyboard (3)]
↳ WALTOP Graphics Tablet id=25 [slave keyboard (3)]
为了构建菜单,我需要获取所有指针的名称和ID(我猜是从属指针,我不知道如果选择虚拟核心指针会发生什么)。一方面,xinput list --id-only
提供xinput list --name-only
我需要的确切信息,除了我需要过滤掉不是指针的 id 和名称。另一方面,我可以xinput list | grep pointer
获取相关行,但结果看起来不太好解析(有无关的括号和奇怪的 ↳ 箭头字符)。我尝试寻找选项来man xinput
进行一些过滤或简化输出,但找不到任何东西。
我的项目基于ptxconf,他们的解决方案如下。我希望找到更优雅的东西。
def getPenTouchIds(self):
"""Returns a list of input id/name pairs for all available pen/tablet xinput devices"""
retval = subprocess.Popen("xinput list", shell=True, stdout=subprocess.PIPE).stdout.read()
ids = {}
for line in retval.split("]"):
if "pointer" in line.lower() and "master" not in line.lower():
id = int(line.split("id=")[1].split("[")[0].strip())
name = line.split("id=")[0].split("\xb3",1)[1].strip()
if self.getPointerDeviceMode(id) == "absolute":
ids[name+"(%d)"%id]={"id":id}
return ids
答案1
尽管没有花费太多时间,但我找不到答案xinput
(我假设您在这里看了很多。
所以我选择的awk
似乎是一条基于上下文问题的简单线。
xinput list | awk 'BEGIN {is_pt=0}; /Virtual core pointer/ {is_pt=1}; /Virtual core keyboard/ {is_pt=0}; {if (is_pt==1) {print $0}} '
或者使用更好的格式:
xinput list | awk '
BEGIN {is_pt=0}
/Virtual core pointer/ {is_pt=1}
/Virtual core keyboard/ {is_pt=0}
{
if (is_pt==1) {
print $0
}
}
'
{}
如果后续模式匹配,则执行每个代码块 ( )。有一个块(其中带有 的块if
,没有进行模式。它针对每一行运行。$0
意味着所有当前记录(行)。BEGIN
是文件的开头。
答案2
我在尝试在 xinput 列表中匹配鼠标时遇到了同样的问题,我习惯于使用 sed 来解决此类问题,因此这是基于 sed 的方法:
MOUSE_G903_ID=$(xinput --list | sed -rn '/^.*Virtual core pointer/,/^.*Virtual core keyboard/ s/^.*Logitech G903 LS[[:blank:]]+id=([[:digit:]]+).*/\1/p')
-n 开关使 sed 抑制所有输出,因此您必须使用 p 命令显式打印您想要的内容,或者在本例中,使用 s 命令的 p 标志。
有一个 sed 表达式(在单引号中)首先定义了操作范围:两个“标题行”(虚拟核心指针、虚拟核心键盘)之间的行范围。
在范围之后, s 命令匹配与我的鼠标对应的行,捕获数字 id 并打印它。