xmodmap 挂起系统 20 秒且不粘住

xmodmap 挂起系统 20 秒且不粘住

我使用 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.

相关内容