如何将 XF86Sleep 键重新映射到空间---xmodmap、xkbcomp 和 udev 失败

如何将 XF86Sleep 键重新映射到空间---xmodmap、xkbcomp 和 udev 失败

我正在运行 Ubuntu 16.04.1 LTS。我有一个类似的遥控器这里(虽然我的遥控器被称为“Vista MCE 遥控器”),它的作用类似于键盘,还有真正的键盘。我试图重新映射遥控器上发送 XF86Sleep 的按钮,改为发送空格,但 xkbcomp 和 xmodmap 的行为不符合我的预期。

首先,我尝试了 xkbcomp,因为我可以使用 -i 选项为其提供一个设备:

xid=`xinput list | grep 05a4:9881 | grep keyboard | perl -pe 's/^.*=([0-9]+).*/\1/'`
xkbcomp -i $xid ~/remote.xkb $DISPLAY

我可以通过以下方式更改发送 KP_Multiply 的键以发送下划线,而不会出现问题:

 key <KPMU> {
     type= "CTRL+ALT",
     symbols[Group1]= [     KP_Multiply,     KP_Multiply,     KP_Multiply,     KP_Multiply,   XF86ClearGrab ]
 };

到:

 key <KPMU> {
     type= "CTRL+ALT",
     symbols[Group1]= [      underscore,      underscore,      underscore,      underscore,   XF86ClearGrab ]
 };

但是当我改变那行时:

 key <I150> {         [       XF86Sleep ] };

 key <I150> {         [           space ] };

这没有任何效果;按下睡眠按钮仍然使我的电脑进入睡眠状态,即使 xev 报告该键发送了一个空格(在我唤醒它之后):

KeyRelease event, serial 29, synthetic NO, window 0x1a00001,
     root 0x1d7, subw 0x0, time 1621457, (99,102),  root:(1797,144),
     state 0x0, keycode 150 (keysym 0x20, space), same_screen YES,
     XKeysymToKeycode returns keycode: 65
     XLookupString gives 1 bytes: (20) " "
     XFilterEvent returns: False

然后我尝试了 xmodmap,如下所示:

% xmodmap -e 'keycode 150 = space'

(这也会影响真正的键盘,但没关系,因为我的键盘没有睡眠按钮,如果有的话我无论如何都会想禁用它。)在此之后,睡眠按钮在 emacs 和 konsole 等程序中不起作用---计算机不会进入睡眠状态,但没有生成空间---而 xev 仍然报告一个空格(就像上面一样)。

更奇怪的是,我尝试用另一个键(“主页”键)做同样的事。xkbcomp 方案有点管用,但每当我使用真实键盘时,该键都会恢复为 XF86HomePage,直到我使用遥控器上的另一个键。(XF86Sleep 键不会发生这种情况;无论我在遥控器上按多少键,它仍会使计算机进入睡眠状态,除非我也执行 xmodmap 命令。)另一方面,在这种情况下,xmodmap 命令确实有效,但代价是键盘上的主页按钮也会发送一个空格。

知道这里发生了什么吗?或者我如何将实际的睡眠键重新映射到空间?我在这里查看了各种类似的问题,但似乎没有一个匹配。(除了这个,没有答案。)

编辑:

终于有机会尝试下面 ssokolow 的答案。根据提供的链接,它应该有效。不幸的是,它没有。没有错误消息,但我在(例如)xev 中看到的键码或键系统没有变化。

这是我所做的:

(1)使用 lsusb 查找相关设备:

Bus 005 Device 002: ID 05a4:9881 Ortek Technology, Inc. IR receiver [VRC-1100 Vista MCE Remote Control]

(2)使用 evtest 找到几个键的 MSC_SCAN 代码:

sudo evtest ... /dev/input/event5: HID 05a4:9881 /dev/input/event6: HID 05a4:9881 ... (请注意两个单独的 /dev/input/events。我目前感兴趣的键在 #6 上,但尝试使用 event5 上的键也不起作用)。它们是“主页”和“电源”键:

Event: time 1514752612.650320, type 4 (EV_MSC), code 4 (MSC_SCAN), value c0223 Event: time 1514752612.650320, type 1 (EV_KEY), code 172 (KEY_HOMEPAGE), value 1 Event: time 1514752612.650320, -------------- SYN_REPORT ------------ Event: time 1514752612.690312, type 4 (EV_MSC), code 4 (MSC_SCAN), value c0223 Event: time 1514752612.690312, type 1 (EV_KEY), code 172 (KEY_HOMEPAGE), value 0 Event: time 1514752612.690312, -------------- SYN_REPORT ------------ Event: time 1514752615.826339, type 4 (EV_MSC), code 4 (MSC_SCAN), value 10082 Event: time 1514752615.826339, type 1 (EV_KEY), code 142 (KEY_SLEEP), value 1 Event: time 1514752615.826339, -------------- SYN_REPORT ------------ Event: time 1514752615.826366, type 1 (EV_KEY), code 142 (KEY_SLEEP), value 0 Event: time 1514752615.826366, -------------- SYN_REPORT ------------

构建文件 /etc/udev/hwdb.d/99-vrc1100-remote.hwdb,仔细确保 KEYBOARD_KEY 行上只有一个空格:

evdev:input:b0003v05a4p9881* KEYBOARD_KEY_10082=playpause KEYBOARD_KEY_C0223=q

我有 udev 版本 229,所以答案中的一个链接说这是正确的格式 (evdev:input:)。

跑步:

sudo systemd-hwdb update

如果我跑

sudo systemd-hwdb query 'evdev:input:b0003v05a4p9881*'

我拿回了文件的最后两行,所以这似乎起作用了。

然后我运行:

sudo udevadm trigger --verbose

我确实看到了打印的相关设备:

... /sys/devices/pci0000:00/0000:00:1a.2/usb5/5-1/5-1:1.0/0003:05A4:9881.0005/input/input8/event5 /sys/devices/pci0000:00/0000:00:1a.2/usb5/5-1/5-1:1.1/0003:05A4:9881.0006/input/input9/event6 ...

但按键仍然不起作用。主页按键仍然显示:

KeyPress event, serial 28, synthetic NO, window 0x4600001, root 0x1d7, subw 0x0, time 8089976, (127,61), root:(998,540), state 0x10, keycode 180 (keysym 0x1008ff18, XF86HomePage), same_screen YES, XLookupString gives 0 bytes: XmbLookupString gives 0 bytes: XFilterEvent returns: False

KeyRelease event, serial 28, synthetic NO, window 0x4600001, root 0x1d7, subw 0x0, time 8090016, (127,61), root:(998,540), state 0x10, keycode 180 (keysym 0x1008ff18, XF86HomePage), same_screen YES, XLookupString gives 0 bytes: XFilterEvent returns: False

电源(睡眠)键似乎不起作用。(在某个时候,我想我设法禁用了睡眠功能,尽管我不记得怎么做了。)

我也尝试过重启,但也没用。我尝试运行:

sudo udevadm control --log-priority=debug

之后,我查看了 /var/log/syslog,但没有找到任何有用的东西。

进一步编辑:

由于 xkbcomp 对我来说已经停止工作,我再次研究了这个问题。一条评论在这篇博文中给了我提示。在

evdev:input:b0003v05a4p9881*

“v”和“p”后面的部分必须大写,而不是像我一样的小写。通过这一更改,我可以更改之前无法更改的键。

答案1

需要理解的是,在 Ubuntu 上输入处理的工作方式如下:

hardware --scancode--> kernel --keycode--> X11 --> keysym --> application

我也遇到过类似的问题,最后沿着栈道走下去,回到过去直到我找到一个适用于我的 14.04 LTS 的解决方案。

我无法让 X11 层改变一些东西,所以我只是向下一层来udev重新定义内核如何将扫描码映射到键码。

由于你使用的是 16.04,所以你不需要像我一样走那么远

(14.04 处于一种奇怪的中间状态,其中列出的最后一个 udev 版本需要外部帮助程序,但它不包含该外部帮助程序,而我后来发现的一些东西表明它可能实际上通过反向移植的补丁支持内部方式……但只能使用一些额外的命令来强制配置更新。)

以下是在 16.04 中可以采用的方法的摘要:

  1. /etc/udev/hwdb.d/whatever.hwdb根据以下任意链接中总结的格式创建一个文件:[1] [2] [3] [4] [5]
  2. sudo systemd-hwdb update如果有则运行,否则运行sudo udevadm hwdb --update
  3. 运行sudo udevadm trigger,拔下并重新插入设备,或者重新启动。

重要的:仅使用一个空格来缩进行KEYBOARD_KEY_,否则将会悄悄失败。

相关内容