我使用 xmodmap 编辑了键盘映射https://wiki.archlinux.org/index.php/Xmodmap,我有两个问题:执行xmodmap ~/.Xmodmap
完全使系统挂起 15-25 秒,考虑到我只是重新映射键盘,并且更改不会在注销时保留,甚至在挂起时也不会保留,这似乎有点奇怪。
我的启动时间增加了 20 秒或更多,而且每次从挂起状态唤醒时都必须运行它,这真是太痛苦了。这是正常的吗(我真的不这么认为?),我能做些什么,也许是重新映射键盘的替代方法?
Linux Mint 15 x64 肉桂
答案1
我在使用 xmodmap 命令冻结系统约 20 秒时遇到了这个问题。看来我的.Xmodmap
文件中有整个键盘映射,这迫使 xmodmap 重新映射配置文件中的每一行。
这就是我解决这个问题的方法:
在启动自定义 xmodmap 配置之前:
# Store default xmodmap
$ xmodmap -pke > ~/.Xmodmap.default
# Backup your custom xmodmap
$ mv ~/.Xmodmap ~/.Xmodmap.bak
# Make a diff between default and custom xmodmap, and store the diff as .Xmodmap
$ diff ~/.Xmodmap.bak ~/.Xmodmap.default | grep '<' | tr '<' ' ' > ~/.Xmodmap
答案2
我在 xubuntu 14.04 (64) 和 xmodmap (具有完全相同的键)上遇到了同样的问题,并找到了使用 xkb 而不是 xmodmap 的解决方案: 在 Ubuntu 中重新映射键(使用 xkb)
xkb 解决方案只需要更改中的键码
/usr/share/X11/symbols/pc
并清除 xkb 缓存
rm -rf /var/lib/xkb/*
后来我就没有再耽搁了。也许这也适用于 Linux Mint。
答案3
xmodmap
运行时,它会XChangeKeyboardMapping
对其修改的每个键调用一次,从而生成MappingNotify
事件。在某些配置(包括我的配置)中,这种突发事件会导致系统挂起一段时间。
我在创建自定义键盘映射时遇到了这个问题,我的(丑陋的)解决方法是编写一个生成 C 源代码的程序,该程序将通过仅调用一次来应用所有修改,从而仅XChangeKeyboardMapping
触发一次。MappingNotify
在运行此代码之前,您必须应用您的映射,因为它将获取当前的键盘映射。
#include <stdlib.h>
#include <stdio.h>
#include <X11/XKBlib.h>
int main(void) {
Display* display;
int min, max, i, j, k;
int keysyms_per_keycode;
KeySym* keysyms;
display = XOpenDisplay(NULL);
XDisplayKeycodes(display, &min, &max);
keysyms = XGetKeyboardMapping(display, min, max-min, &keysyms_per_keycode);
printf("#include <stdlib.h>\n");
printf("#include <stdio.h>\n");
printf("#include <X11/XKBlib.h>\n\n");
printf("int main(void) {\n");
printf(" int first_keycode = %d;\n", min);
printf(" int keysyms_per_keycode = %d;\n", keysyms_per_keycode);
printf(" int num_of_keycodes = %d;\n", max-min);
printf(" KeySym keysyms[%d] = {", ((max-min) * keysyms_per_keycode) + 1);
for (k = 0, i = 0; i < (max-min); i++) {
for (j = 0; j < keysyms_per_keycode; j++) {
printf("%ld,", keysyms[k++]);
}
}
printf("0};\n");
printf(" Display* display = XOpenDisplay(NULL);\n");
printf(" XChangeKeyboardMapping(display,first_keycode,keysyms_per_keycode,keysyms,num_of_keycodes);\n");
printf(" XCloseDisplay(display);\n");
printf(" return 0;\n");
printf("}\n");
XFree(keysyms);
XCloseDisplay(display);
return 0;
}
编译用gcc -lX11
.