xmodmap がシステムを 20 秒間停止させ、停止しない

xmodmap がシステムを 20 秒間停止させ、停止しない

私はxmodmapを使ってキーボードマップを編集しましたhttps://wiki.archlinux.org/index.php/Xmodmap、2 つの問題があります。実行すると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 (まったく同じキー) でも同じ問題が発生しましたが、xmodmap の代わりに xkb を使用する解決策を見つけました。 Ubuntu でのキーの再マッピング (xkb を使用)

xkbソリューションでは、キーコードを変更するだけで済みます。

/usr/share/X11/symbols/pc

そしてxkbキャッシュをクリアする

rm -rf /var/lib/xkb/*

その後は遅延はありませんでした。おそらく Linux Mint でも動作するでしょう。

答え3

実行すると、変更するキーごとに 1 回xmodmap呼び出され、イベントが生成されます。一部の構成 (私の構成も含む) では、このイベントのバーストにより、システムがしばらくハングします。XChangeKeyboardMappingMappingNotify

カスタマイズされたキーボード マップを作成しているときにこの問題が発生しましたが、私の (醜い) 回避策は、XChangeKeyboardMapping一度だけ呼び出すことですべての変更を適用し、それによってMappingNotify一度だけトリガーする C ソース コードを生成するプログラムを作成することでした。

このコードを実行する前に、現在のキーボード マッピングを取得するため、マップを適用する必要があります。

#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

関連情報