(ArchLinux)(AlterLinux)(xmodmap) キーボードの、あるキーを押した時に、それとは違うキーを押したことにしたい

この記事はAlterLinuxPlasma版(ArchLinux系)で確認したものになります

一例としてこういうケースが有ったとします、
> よくスクリーンショットを取るけど PrintScreenキーが配置的になんか煩わしいので、
> 普段使わず浮いてる無変換キーを押したらスクリーンショットが発動して欲しい。
あくまで一例ですので似たようなケースに置き換えて読んでください。

実現する方法の一つとして「グローバルショートカットキーとして仕込む」というものがありますが、
キーによっては発動しない場合があるようです、
個人的環境(AlterLinux Plasma版)では、無変換キー単体にコマンドを仕込むことは出来ませんでした。

こういった場合にどうするのか?というと、
無変換キーを押したらPrintScreenキーを押したことにする
と、いうことになります、
ただ、それを実現するには xmodmapを使用することになりますが、
まずはキー入力の仕組みを知らないと、設定で混乱することになりますので少し大雑把に解説します。
例えば、 キーボード上の「A」と印刷されているキーを押すと、
OSはその物理キーに割り当てられている番号をキーコードとして認識します
そして、そのキーコードに対して割り当てられている 「a」を表すキーシムに置き換えて、
aが押されたと認識されることになります。
(かなり大雑把な説明なので、とりあえずはどんな感じかだけ把握してください)

よって、今回のケースで言えば、
無変換キーのキーコードに対して、「PrintScreenキーを表すキーシム」を割り当てる
ということをやれば、「無変換」を押しても「PrintScreen」を押した事になります。

ここで少し回り道になりますが、
あるキーを押した時にOSが認識している キーコードとキーシムの調べ方 について解説します、
厄介なのが、キーボードやOS環境によってキーコードとキーシムが必ずしも同じではなくて
どの環境ででも○キーのキーコードは○○で、キーシムは○○になるとは言いきれません、
よって、各自で実際にキーを押してみて、どう認識されているかを調べたほうが確実になります、

調べるにはGUIで動作する簡単なツール xev(extra/xorg-xev) があります、
ターミナルから xev として起動して、アクティブ時に調べたいキーを押すだけです
私の環境で Aと印字されたキーを押した場合、以下のようにレポートされました、

KeyPress event, serial 40, synthetic NO, window 0x3e00001,
    root 0x6b5, subw 0x0, time 694366, (462,199), root:(1333,664),
    state 0x10, keycode 38 (keysym 0x61, a), same_screen YES,
    XLookupString gives 1 bytes: (61) "a"
    XmbLookupString gives 1 bytes: (61) "a"
    XFilterEvent returns: False

KeyRelease event, serial 40, synthetic NO, window 0x3e00001,
    root 0x6b5, subw 0x0, time 694448, (462,199), root:(1333,664),
    state 0x10, keycode 38 (keysym 0x61, a), same_screen YES,
    XLookupString gives 1 bytes: (61) "a"
    XFilterEvent returns: False

今回注目すべき部分は keycode 38 (keysym 0x61, a) の所ですね、
どうやら「Aと印字されたキー」の「キーコード は 38」で「キーシム は 0x61(a)」となるようです
他にも色々試してると NumLock Shift Ctrl などによって stateの値が 変わっているようです、
ちなみに、Shift + Aと印字されたキーの場合だと

KeyPress event, serial 40, synthetic NO, window 0x3e00001,
    root 0x6b5, subw 0x0, time 1052924, (363,8), root:(1234,473),
    state 0x11, keycode 38 (keysym 0x41, A), same_screen YES,
    XLookupString gives 1 bytes: (41) "A"
    XmbLookupString gives 1 bytes: (41) "A"
    XFilterEvent returns: False

KeyRelease event, serial 40, synthetic NO, window 0x3e00001,
    root 0x6b5, subw 0x0, time 1053024, (363,8), root:(1234,473),
    state 0x11, keycode 38 (keysym 0x41, A), same_screen YES,
    XLookupString gives 1 bytes: (41) "A"
    XFilterEvent returns: False

キーコードは同じく38ですが、キーシムは 0x41(A)に変わっていますね
つまり、キーコードが同じでも Shiftなどと組み合わせると キーシムが変わることが有るようですね。

なんとなく分かってきた所で、無変換キー と PrintScreenキー も同じように調べてみます

KeyPress event, serial 40, synthetic NO, window 0x3e00001,
    root 0x6b5, subw 0x0, time 1726706, (468,287), root:(1339,752),
    state 0x10, keycode 102 (keysym 0xff22, Muhenkan), same_screen YES,
    XLookupString gives 0 bytes: 
    XmbLookupString gives 0 bytes: 
    XFilterEvent returns: False

KeyRelease event, serial 40, synthetic NO, window 0x3e00001,
    root 0x6b5, subw 0x0, time 1726826, (468,287), root:(1339,752),
    state 0x10, keycode 102 (keysym 0xff22, Muhenkan), same_screen YES,
    XLookupString gives 0 bytes: 
    XFilterEvent returns: False

KeyPress event, serial 40, synthetic NO, window 0x3e00001,
    root 0x6b5, subw 0x0, time 1728572, (468,287), root:(1339,752),
    state 0x10, keycode 107 (keysym 0xff61, Print), same_screen YES,
    XLookupString gives 0 bytes: 
    XmbLookupString gives 0 bytes: 
    XFilterEvent returns: False

KeyRelease event, serial 40, synthetic NO, window 0x3e00001,
    root 0x6b5, subw 0x0, time 1728692, (468,287), root:(1339,752),
    state 0x10, keycode 107 (keysym 0xff61, Print), same_screen YES,
    XLookupString gives 0 bytes: 
    XFilterEvent returns: False

無変換キーは、キーコードが102、キーシムが0xff22(Muhenkan)
PrintScreenキーは、キーコードが107、キーシムが0xff61(Print)
であることが分かりましたね。

ということで 本来の目的である、無変換キーを押したらPrintScreenを押したことにする事とは、
キーコード102 に キーシム0xff61(Print) を 割り当てればよさそうです
xmodmapの使い方を見て、コマンドを打ってみます

xmodmap -e "keycode 102 = 0xff61"
#または
xmodmap -e "keycode 102 = Print"

再び xevで確認してみます

KeyPress event, serial 40, synthetic NO, window 0x3c00001,
    root 0x6b5, subw 0x0, time 2972834, (315,336), root:(1186,801),
    state 0x10, keycode 102 (keysym 0xff61, Print), same_screen YES,
    XLookupString gives 0 bytes: 
    XmbLookupString gives 0 bytes: 
    XFilterEvent returns: False

KeyRelease event, serial 40, synthetic NO, window 0x3c00001,
    root 0x6b5, subw 0x0, time 2972956, (315,336), root:(1186,801),
    state 0x10, keycode 102 (keysym 0xff61, Print), same_screen YES,
    XLookupString gives 0 bytes: 
    XFilterEvent returns: False

KeyPress event, serial 40, synthetic NO, window 0x3c00001,
    root 0x6b5, subw 0x0, time 2979404, (163,-27), root:(1034,438),
    state 0x10, keycode 107 (keysym 0xff61, Print), same_screen YES,
    XKeysymToKeycode returns keycode: 102
    XLookupString gives 0 bytes: 
    XmbLookupString gives 0 bytes: 
    XFilterEvent returns: False

KeyRelease event, serial 40, synthetic NO, window 0x3c00001,
    root 0x6b5, subw 0x0, time 2979506, (163,-27), root:(1034,438),
    state 0x10, keycode 107 (keysym 0xff61, Print), same_screen YES,
    XKeysymToKeycode returns keycode: 102
    XLookupString gives 0 bytes: 
    XFilterEvent returns: False

キーコード 102(無変換キー) も 107(PrintScreenキー) も、両方ともキーシムが 0xff61(Print) になってます。

ただし、コマンドによって割り振られたものは一時的なもので、PCを再起動したりすると元に戻ります、
この設定を永続化させるためには ~/.Xmodmap に設定します、ファイルが無い場合は作成します、

! この行はコメント行
keycode 102 = Print

~/.Xmodmap を編集したらPCを再起動して ログイン時から反映していれば成功です。

AlterLinuxPlasma版の場合 PrintScreenキーを押してもスクリーンショットは発動しないようで、
個人的には グローバルショートカットに ImageMagickのimportを使ってスクショを撮る自作のソフトを仕込み、
PrintScreenキーを押す度に それを呼び出すようにしています、
無変換キーにも同じように グローバルショートカットを仕込みましたが、
特殊な扱いなのか、いくら押しても実行されませんでした、そこで試してみたのが今回のやり方ですが、
これならきちんとPrintScreenキーが押された判定となり、スクショが発動するようになりました。