我正在尝试使用xmodmap来重新映射Dell L100键盘上的Alt /超级键,并且在获取键码时遇到了麻烦。
FocusOut event, serial 36, synthetic NO, window 0x4a00001,
    mode NotifyGrab, detail NotifyAncestor

FocusIn event, serial 36, synthetic NO, window 0x4a00001,
    mode NotifyUngrab, detail NotifyAncestor

KeymapNotify event, serial 36, synthetic NO, window 0x0,
    keys:  122 0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   
           0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   


对于右超级按键,xevxev给出了不同的键码-分别为showkey134

这些键码怎么了?

我尝试从126获取密钥代码,并使用下面的showkey -k文件,但是给出了一个奇怪的映射,该映射重新映射了b键:

评论

我在XUbuntu 14.04上有一个不触发Alt_L的问题(但是Alt_R很好)。您正在使用什么系统?

#1 楼

键盘和最终处理键盘事件的过程之间有许多参与者。 X系统具有自己的键盘处理层,并且X与Linux基本系统相比,X将不同的“键码”与键相关联是事实的主要内容。 showkey命令向您显示Linux基本系统语言中的键控代码。对于xmodmap,您需要X键码,这是xev所显示的。只要您打算使用X并使用xmodmap进行密钥重新绑定,那么就可以忽略showkeys并只听xev所说的话。这样的块:


KeyPress event, serial 27, synthetic NO, window 0x1200001,
    root 0x101, subw 0x0, time 6417361, (340,373), root:(342,393),
    state 0x0, keycode 64 (keysym 0xffe9, Alt_L), same_screen YES,
    XLookupString gives 0 bytes: 
    XmbLookupString gives 0 bytes: 
    XFilterEvent returns: False

KeyRelease event, serial 27, synthetic NO, window 0x1200001,
    root 0x101, subw 0x0, time 6417474, (340,373), root:(342,393),
    state 0x8, keycode 64 (keysym 0xffe9, Alt_L), same_screen YES,
    XLookupString gives 0 bytes: 
    XFilterEvent returns: False



xev往往会产生大量输出,尤其是在移动鼠标时。您可能需要向后滚动一会才能找到所需的输出。在上一个输出中,我们看到xev与X键码keysym Alt_L相关联。

评论


问题是我没有在Windows key上收到KeyPress事件。我尝试了3种不同的键盘,结果相同。从xev只能得到FocusOut,FocusIn和KeymapNotify,如上所示。但是,我可以通过Gnome管理器来设置快捷方式,它将Windows密钥视为“ Mod4”

–雅罗斯拉夫·布拉托夫(Yaroslav Bulatov)
2012年10月2日,下午5:43

右Windows键报告为Mod4,左Windows键报告为Alt ...这令人困惑,因为我的xmodmap中甚至没有“ Alt”类别。

–雅罗斯拉夫·布拉托夫(Yaroslav Bulatov)
2012年10月2日,下午5:59

尝试使用Mod1替代Alt。

– dubiousjim
2012年10月2日在10:24

@YaroslavBulatov听起来好像您的桌面环境正在占用键(可能是调出其主菜单?)

–德罗伯特
2012年10月26日16:18

您可以过滤xev给您的事件。在这种情况下,xev -event键盘足以消除大部分噪音。

–弗雷德里克·温特(Fredrik Wendt)
17年8月26日在6:04

#2 楼

xev应该可以工作

奇怪的是,我的xev提供了alt的KeyPress和KeyRelease事件(对于Windows键,这里称为“ super”):

KeyPress event, serial 40, synthetic NO, window 0xae00001,
    root 0x2ca, subw 0x0, time 595467354, (98,77), root:(102,443),
    state 0x10, keycode 64 (keysym 0xffe9, Alt_L), same_screen YES,
    XLookupString gives 0 bytes: 
    XmbLookupString gives 0 bytes: 
    XFilterEvent returns: False

KeyRelease event, serial 40, synthetic NO, window 0xae00001,
    root 0x2ca, subw 0x0, time 595467453, (98,77), root:(102,443),
    state 0x18, keycode 64 (keysym 0xffe9, Alt_L), same_screen YES,
    XLookupString gives 0 bytes: 
    XFilterEvent returns: False


和右边的一个:

KeyPress event, serial 40, synthetic NO, window 0xae00001,
    root 0x2ca, subw 0x0, time 595572876, (75,33), root:(79,399),
    state 0x10, keycode 108 (keysym 0xffea, Alt_R), same_screen YES,
    XLookupString gives 0 bytes: 
    XmbLookupString gives 0 bytes: 
    XFilterEvent returns: False

KeyRelease event, serial 40, synthetic NO, window 0xae00001,
    root 0x2ca, subw 0x0, time 595572972, (75,33), root:(79,399),
    state 0x18, keycode 108 (keysym 0xffea, Alt_R), same_screen YES,
    XLookupString gives 0 bytes: 
    XFilterEvent returns: False


我可以看到两种可能性:


其他的东西完全是按下按键或按Alt键使窗口散焦。尝试在原本为空的X服务器中运行xev(例如,只需运行xinit -- :1,这应该使您只有一个xterm的X服务器-甚至没有窗口管理器在运行。退出xterm将关闭会话)。 />您只是错过了xev发出的两个事件。

一种简单的方法,如果知道键名

另一种可能性:只需从xmodmap:

anthony@Zia:~$ xmodmap -pk | grep -i alt
     64         0xffe9 (Alt_L)  0xffe7 (Meta_L) 0xffe9 (Alt_L)  0xffe7 (Meta_L)
    108         0xffea (Alt_R)  0xffe8 (Meta_R) 0xffea (Alt_R)  0xffe8 (Meta_R)
    204         0x0000 (NoSymbol)       0xffe9 (Alt_L)  0x0000 (NoSymbol)       0xffe9 (Alt_L)
anthony@Zia:~$ xmodmap -pk | grep -i super
    133         0xffeb (Super_L)        0x0000 (NoSymbol)       0xffeb (Super_L)
    134         0xffec (Super_R)        0x0000 (NoSymbol)       0xffec (Super_R)
    206         0x0000 (NoSymbol)       0xffeb (Super_L)        0x0000 (NoSymbol)       0xffeb (Super_L)


又是64和108。 xmodmap -pm将只向您显示修饰符映射,该映射也为您提供数字(尽管这次是十六进制)。

#3 楼

我“检测”了您的问题中的三个问题:


为什么xevshowkey报告某个键的键码不同?
为什么xev不能正常显示Alt? />如何交换Alt和Win?

关于第一个问题:这些天来,X中的键盘“驱动程序”并不能真正驱动硬件,它只能通过键盘上的键码进行传递。 X内核的内核,但事实并非如此。在将其传递给键码之前,它会在键码上添加8。其他答案已经涵盖了这一点。 (即,xev没有收到您想要看到的事件)。罪魁祸首可能与您的窗口管理器有关。尝试更赤裸的X会话。

第三:不要使用xmodmap。它已经过时了十年。新手是XKB及其工具setxkbmap

$ setxkbmap -query
rules:      evdev
model:      pc105
layout:     us
variant:    altgr-intl
options:    caps:backspace


要交换Alt和Win,已经在XKB中准备了一个选项。只需添加:

$ setxkbmap -option altwin:swap_alt_win
$ setxkbmap -query
rules:      evdev
model:      pc105
layout:     us
variant:    altgr-intl
options:    altwin:swap_alt_win,caps:backspace


评论


如何使setxkbmap永久更改?

– Steve Kehlet
17年6月23日在16:23

将更改添加到〜/ .xinitrc。

–马特西亚斯·布劳恩(Matthias Braun)
19年8月29日在17:44

#4 楼

我试图自己解决这个问题,我只是想出了办法。

主要问题是您没有为按键事件。查看发布的日志,原因很明显。

FocusOut event, serial 36, synthetic NO, window 0x4a00001,
    mode NotifyGrab, detail NotifyAncestor

FocusIn event, serial 36, synthetic NO, window 0x4a00001,
    mode NotifyUngrab, detail NotifyAncestor

KeymapNotify event, serial 36, synthetic NO, window 0x0,
    keys:  122 0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   
           0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   


您可以看到Focus{In,Out}事件的modeNotify{Grab,Ungrab}。这表明密钥是由另一个进程(可能是快捷方式/密钥绑定应用程序)处理的。在我的情况下,它是xbindkeys,但是如果您使用的是桌面环境,则它们可能具有密钥绑定系统。为了看到这些事件是xev,您将需要停止/禁用其他程序。

如果无法确定哪个程序在窃取关键事件,最好的解决方案是在不启动任何X会话的情况下启动它正在运行。运行以下命令以在显示屏:1上启动另一个X会话(如果已执行),只需增加末尾的数量即可。当然,您可以将终端更改为您喜欢的终端或系统上安装的终端。

xinit /usr/bin/xterm -- :1


然后再次运行xev。那应该为您提供结果,而不会被其他程序捕获。请注意,开始的窗口管理器是悬停焦点,因此必须将光标置于xev窗口上方才能捕获键。


对于dubiousjim的出色回答,键码是不同的,因为xev和内核之间有很多层。

评论


我遇到了一个确切的问题,一个基于窗口管理器的键绑定系统正在吃掉按键(一个VolumeUp媒体按钮),因此我无法弄清楚KeyPress。禁用绑定可以让新闻界通过,我可以找到键码。谢谢 !

– Nikana Reklawyks
20 Mar 22 '20 at 6:36

#5 楼

以root用户身份运行:

showkey -s


...以查看神秘密码的扫描码是什么。我得到这样的信息:

# showkey -s
kb mode was RAW
[ if you are trying this under X, it might not work
since the X server is also reading /dev/console ]

press any key (program terminates 10s after last keypress)...

0xc6 
0x46 0xc6 
0xc6 
0x46 0xc6 
0x46 


不知道为什么一个键会生成两个扫描代码。从我从模式中可以看出,这不是按键/按键操作。请注意警告,因此您可能需要在单用户模式下运行此警告。

我猜想我的扫描码是0x46。

接下来,找到一个未使用的键码,如下:您会看到在我的系统上未使用键码97:出于“历史原因”,X使用的键码和内核使用的键码被OFF 8。因此,将97-8 = 89并与setkeycodes命令一起使用89(再次以root用户身份):

用xev确认您收到的键代码为97的Keypress事件。(尽管一旦我告诉Fluxbox密钥文件使用该键代码,我就再也没有KeyPress事件了-也许是因为Fluxbox在使用它们时会吞下它们吗?)

请注意,“ setkeycodes”在重启后将无法生存,因此您必须将其添加到初始化脚本中(例如,在/etc/rc.local中)。

评论


您是否有关于“由于历史原因而减少8分”的指标?

– Robert Siemer
2014年11月14日上午11:09

我用您的答案将大写锁定映射到功能键(特别是F9)上。这使我可以将F9用作tmux中的前缀键。谢谢。

–雷蒙德·克鲁克(Raymond Kroeker)
18/12/2在0:35

@RobertSiemer tldp.org/HOWTO/Keyboard-and-Console-HOWTO-15.html“通常X数比Linux数多8。”我用“历史的”一词一定是来自另一本手册。

–格雷格·贝尔(Greg Bell)
18/12/3在3:05

我有一个密钥,xev报告密钥代码93,sudo showkey报告85和sudo showkey -s报告0x76 0xf6-所以我尝试使用0x76,0xf6,76或85作为scancode以及89作为keycode的sudo setkeycodes-但没有改变,xev仍然报告93!

– Xerus
20年5月15日在9:01



#6 楼

我在XUbuntu 14.04中消失了Alt_L时遇到了同样的问题(Alt_R很好)。经过大量的演奏,我观察到showkey记录了击键,但xev却没有---它必须是窗户系统中的东西。我搜寻了所有的“窗口管理器”和“窗口管理器调整”设置,但没有找到任何东西。最后,我在“设置编辑器”的键盘快捷键列表(Alt_L)中找到了一个杂乱的xfce4-keyboard-shortcuts。我“重置”了,我又恢复了我的Alt_L!杂乱的Alt_L快捷方式仅在“设置编辑器”中没有显示。