Xmodmap alternatives?

Xubuntuで、Caps と Ctrl を交換するだとか、その他細々としたキーボードのリマップを、xmodmap でやっている。が、なんだか知らないが、xmodmap はとっくの昔に Obsolete らしいのであった。さらに困ったことに、数時間おきに xmodmap によるリマップが勝手にリセットされるのだ。いや正確に言うと数時間おきというのも違い、ランダムというしかないタイミングでリセットされる。わからん。どういう嫌がらせなんだ。

で、xmodmap の代替は xkb らしいのだけど。ちょっと調べてみてなんかめんどくさそうだなーまあ xmodmap でいいかな…というのをかれこれ年に3回位繰り返している。

しかしせっかくなので、いろいろ試行錯誤してみた。xkb は基本的に言えば、物理キーに対してどの論理キーとして振る舞わせるかを制御する。また Shift−Level なんかも制御する。それらの情報は /usr/share/X11/xkb 以下にテキストファイルとして保持されている。各ユーザのホームに個別の .xkbrc ファイルみたいなのを置いて上書きするような仕組みはない。やろうとするなら、.xinitrc なり .xsession なりで setxkbmap を呼ぶことになると思う。

さて実際にキーの割当を記述するのは、symbols/ サブディレクトリ以下のファイル群となる。
/usr/share/X11/xkb $ ls symbols
af by es hu kz mm pt terminate
al ca et ie la mn ro th
altwin capslock eu il latam mt rs tj
am cd eurosign in latin mv ru tm
apl ch fi inet level3 nbsp rupeesign tr
ara cm fo iq level5 nec_vndr se tw
at cn fr ir lk ng sgi_vndr typo
az compose fujitsu_vndr is lt nl sharp_vndr tz
ba ctrl gb it lv no shift ua
bd cz ge jp ma nokia_vndr si us
be de gh ke macintosh_vndr np sk uz
bg digital_vndr gn keypad mao olpc sn vn
br dk gr kg md pc sony_vndr xfree68_vndr
brai ee group kh me ph srvr_ctrl za
bt empty hp_vndr kpdl mk pk sun_vndr
bw epo hr kr ml pl sy

ここにたくさんのファイルがあるわけだが、個々のファイルはそれら自身が行うキー定義量によって実質的に階層化されている。例えば pc ファイルはほぼすべてのキーに対して割当を定義する。言語コードっぽいファイルは各言語に応じた部分だけを定義する。ctrl や altwin、shift といったファイルは、それぞれの個別のキーをどのように振る舞わせるかだけを定義する。このようにレイアウトや言語から独立して、ほんの一部の定義だけを行うものを option と呼ぶ。

言語による定義の場合、さらにその言語内でいくつかのバリエーションが必要になる場合がある。その場合は、例えば us ファイルであればそのファイル内で、基本の定義を継承し、必要な部分だけを変更したものを定義する。そのような定義を variant と呼ぶ。

これらのファイルから任意のものをピックアップし、定義量の大きいファイルから小さいファイルへ順々に定義を行うことで任意のキーレイアウトが完成する。

で、実際にキーボードの種別を指定するには /etc/default/keyboard ファイルを

XKBMODEL="pc105"
XKBLAYOUT="us"
XKBVARIANT=""
XKBOPTIONS=""

と言った感じに記述する。model -> layout -> variant -> option という並びがまさに前述の、定義量の大きい順から小さい順というトピックに対応している。

ということを踏まえた上で、行いたいリマップは:

  1. 左の Ctrl と、Capslock を交換する
  2. Menu キーを Compose キーにする
  3. 右の Alt キーを、F20 キーにする

1. と 2. については、標準でオプションが定義されているので、前述の keyboard ファイル中の XKBOPTIONS に “ctrl:swapcaps,compose:menu” という値を与えればいい。問題は 3. だ。3. を実現するには、us の variant を定義するか、あるいは新しい option を定義するか…が正道に思える。

しかし、実際に行うのはそのどちらでもない。というのは variant や option を新設するには、rules/ 以下のいろいろなファイルを併せていじる必要があり、とても面倒だからだ。しかもそれらの編集が間違っていると、X 上の文字入力が一切できない、つまりログインスクリーンから進めないというかなり困る状態になってしまう。実際にやらかして、アワワワワ…となった。

実際に行うのは、上記で参照している option の定義中に 3. の定義を忍び込ませるというものだ。かなりイケてないが、たぶんこれが xkb の定義ファイルを最小限いじるだけで済むベストな方法だ。us ファイルを使わないのは、それが定義順の左の方に位置するので、知らない定義で上書きされる可能性が高いからだ。option なら定義の最後なので上書きされる恐れはかなり小さい。

swapcaps の定義は ctrl ファイルの

// Swap the functions of the CapsLock key and the left Ctrl key.
partial modifier_keys
xkb_symbols "swapcaps" {
replace key { [ Control_L ] };
replace key { [ Caps_Lock ] };
};

というセクションなので、この中に

replace key { [ F20 ] };

という行を追加する。そして祈りながら再起動する。これで xmodmap でやっていたリマップを xkb で再現できた。

Leave a Reply

Your email address will not be published. Required fields are marked *