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.

相關內容