Ubuntu 15.04: キーボードのカスタマイズ設定

Happy Hacking Keyboard を使っていて Meta キー(スペースキーの隣)を Alt キーとして使うように設定するのにえらく苦労したので記録を残しておく。

要点をまとめると、こんな感じ。

  • XKB の設定ファイルを書く。
  • システム側の XKB 設定ファイルが上の設定ファイルを参照するように書き換える。
    • /usr/share/X11/xkb/rules/evdev
    • X.org のアップデートで上書きされる可能性あり。
  • GNOME の設定(gsettings)に上で追加した設定を適用するよう設定する。
    • これは各ユーザ毎に設定する必要あり。

設定ツールの GUI で気軽に設定というわけにはいかず、失敗するとキー入力に支障をきたすおそれもあり。以下ではなるべく安全な手順を踏むように書いておく。

前提

Ubuntu のインストール時に、言語環境は日本語、キーボードは英語(US)を指定してインストールした環境。入力メソッドフレームワークは fictx (日本語 Remix のデフォルト)。

デスクトップ環境は GNOME flashback (metacity)。Unity での動作は未検証だが同じ設定で大丈夫だと思う。

キーコードを確認

設定ファイルを書くための下調べ。以降の設定ファイルを丸写しするだけならこの作業は不要。

まず、設定したいキーのスキャンコードを調べる。terminal を開いて xev を実行する。xev は太古の昔からある X の動作確認ツールで、マウスやキーのイベントの情報をダンプするもの。xev を実行すると小さなウィンドウが開くので、そのウインドウを選択してキーを押すと terminal にキーの情報が出力される。

左の Meta キーを押すと以下の出力。keycode の値からこのキーのスキャンコードが 102 であることがわかる。

KeyPress event, serial 37, synthetic NO, window 0x3200001,
    root 0x2b8, subw 0x0, time 395098700, (50,135), root:(837,187),
    state 0x0, keycode 102 (keysym 0xff22, Muhenkan), same_screen YES,
    XLookupString gives 0 bytes: 
    XmbLookupString gives 0 bytes: 
    XFilterEvent returns: False

右の Meta キーを押すと以下の出力。こちらは 100。

KeyPress event, serial 37, synthetic NO, window 0x3200001,
    root 0x2b8, subw 0x0, time 395099342, (50,135), root:(837,187),
    state 0x0, keycode 100 (keysym 0xff23, Henkan_Mode), same_screen YES,
    XLookupString gives 0 bytes: 
    XmbLookupString gives 0 bytes: 
    XFilterEvent returns: False

次に、スキャンコードに対応するシンボル形式のキーコードを調べる。/usr/share/X11/xkb/keycodes/evdev を上で調べたスキャンコードで検索すると、以下のような定義が見つかる。

        <HENK> = 100;   // Henkan
        <MUHE> = 102;   // Muhenkan

これで、(シンボル形式の)キーコードは、左 Meta キーが 、右 Meta キーが であることがわかる。

シンボル設定ファイルの作成

XKB のシンボル設定ファイル*1を作成する。

まず、後で動作確認のため適切なディレクトリ構造の下に保存しておく必要があるため、あらかじめ ~/.xkb というディレクトリを作成しておく。

そして、~/.xkb/symbols/hhk_swap というファイルに以下の内容を保存する(ファイル名は任意だが、サブディレクトリ名の symbols はこの通りにすること)。

partial modifier_keys
xkb_symbols "alt_keys" {
  replace key <MUHE> { [ Alt_L ] };
  replace key <HENK> { [ Alt_R ] };
};

これは、キーコード のキー(左 Meta キー)を左 Alt キー(Alt_L)に、 のキー(右 Meta キー)を右 Alt キーに置き換える設定。symbols ファイルの書き方は正直よくわからないが、以下の記事を参考に試行錯誤して書いた。

実は の設定の方は効かないことがあるので、何か間違っているのかもしれないがそのままにしておく。二度設定を読み込ませると効いたりするので XKB 側の不具合か何かかもしれない。

シンボル設定ファイルの動作確認

システムファイルを書き換える前に動作確認をしておく。

まず、setxkbmap コマンドで現在の XKB 設定を表示する。

$ setxkbmap -print
xkb_keymap {
	xkb_keycodes  { include "evdev+aliases(qwerty)"	};
	xkb_types     { include "complete"	};
	xkb_compat    { include "complete"	};
	xkb_symbols   { include "pc+us+inet(evdev)"	};
	xkb_geometry  { include "pc(pc104)"	};
};

この出力をコピーして、以下のように修正したファイルを ~/.xkb/keymap/hhk に保存する(太字が修正部分)。

xkb_keymap {
	xkb_keycodes  { include "evdev+aliases(qwerty)"	};
	xkb_types     { include "complete"	};
	xkb_compat    { include "complete"	};
	xkb_symbols   { include "pc+us+inet(evdev)+hhk_swap(alt_keys)"	};
	xkb_geometry  { include "pc(pc104)"	};
};

これはキーマップ設定ファイルで、修正部分は既に作成したシンボル設定ファイルを参照する設定。

hhk_swap は先に作ったシンボル設定ファイルのファイル名。alt_keys はシンボル設定ファイルに書いた xkb_symbols "alt_keys" { の "" 内の名前。つまりこれは、設定ファイル hhk_swap 内の alt_keys という名前で定義されたシンボル設定の {} 内に書かれた設定を適用するという意味。

この設定を実際に動作中のデスクトップ環境に適用する。GNOME デスクトップにログインした状態で、以下のように xkbcomp コマンドを実行する。

xkbcomp -I$HOME/.xkb ~/.xkb/keymap/hhk $DISPLAY

第1引数の -I に続けて記述(スペースは空けない)した ~/.xkb は最初に作った設定ファイルの置き場所のディレクトリ。第2引数は上で作成したキーマップ設定ファイル。第3引数は普通はこのままで気にしなくてよい。((DISPLAY は X の環境変数で、現在使用している X サーバー(画面表示を行うモジュール)の名前が入っている。古典的なマルチディスプレイ環境だとディスプレイ毎に違う名前になるが、今時のマルチモニター環境では気にしなくてよいはず。このあたりの歴史的経緯の概略は マルチディスプレイ - ArchWiki を参照。))

コマンドラインを実行すると大量の(40行ぐらい) Warning が標準エラー出力に出力されるが、身におぼえのなさそうなものはシステム側の設定ファイルの問題なので気にしなくてよい。

これで期待したキー割り当てができているか確認する。

システム側の XKB 設定ファイルを変更する

以下の作業はシステムファイルを追加・変更するため、terminal で sudo コマンドを使って実行する。

まず、シンボル設定ファイル hhk_swap を /usr/share/X11/xkb/symbols/ にコピーする。ファイル名を変えている場合はコピー先に同名のファイルがないか確認して、同名のファイルがあるなら上書きしないように別のファイル名でコピーすること。

次に /usr/share/X11/xkb/rules/evdev を書き換える。このファイルには「DO NOT EDIT THIS FILE」などと書いてあるが、他に適切な方法がみつからないので…

/usr/share/X11/xkb/rules/evdev の末尾に次の1行を追加。

  hhk:alt_keys = +hhk_swap(alt_keys)

シンボル設定ファイルの設定をオプション設定として登録している。設定は hhk:alt_keys という名前で登録しており、GNOME の設定からはこの名前で設定を参照する。hhk_swap(alt_keys) の部分は「シンボル設定ファイルの動作確認」のキーマップ設定ファイルの修正部分と同じ意味。

GNOME の設定(ユーザ毎の設定)

実際にキーボードカスタマイズ設定を利用するユーザアカウントで GNOME デスクトップにログインして、以下のコマンドラインを実行する。

gsettings set org.gnome.desktop.input-sources xkb-options "['hhk:alt_keys']"

hhk:alt_keys は、/usr/share/X11/xkb/rules/evdev に追加したオプション設定の名前。

これで設定作業は終わり。

一度ログアウトして再度ログインするとキーカスタマイズ設定が適用されているはずだ。*2

失敗した方法

以下はうまくいきそうでいかなかった方法。

xmodmap は使えない

昔から UNIX 系 OS で X を使っている人なら、まず .Xmodmap で設定しようとするだろうが、これはダメだった。今までこれで大丈夫だったし、実際 terminal から xmodmap を実行すれば実行直後は効いているのだけど、入力メソッドを切り替えたりスリープから復帰したりすると元に戻ってしまう。

これは fcitx がキーボードレイアウトを切り替える際に xmodmap の設定を上書きしてしまうためだが、この時に xmodmap の設定ファイルを再読み込みする設定があるようだ(xmodmap settings being overwritten - FAQ - Fcitx)。

入力メソッドの設定 の [アドオン] タブでを開いて [拡張] チェックボックスにチェックを入れると一覧から [X Keyboard Integration] が選択できるようになるので[レイアウト変更後にこの独自 xmodmap スクリプトを適用する]に .Xmodmap をフルパスで設定する。

しかし、これもうまくいかなかった。設定直後は .Xmodmap が読み込まれるのだが、やはり入力メソッドを切り替えると設定がリセットされてしまう。

xkbcomp は使えない

システムファイルの変更を嫌ってデスクトップログイン時に xkbcomp を実行する方法が「[xkb] Ubuntu 14.04 で Caps Lock を別のキーにする方法」や「xkbでキーバインドを変更する」で紹介されているが、自分の環境では設定が反映されなかった。

GNOME の「自動起動するアプリケーション」に xkbcomp を実行するシェルスクリプトを設定しても、起動タイミングの問題なのか何なのか、設定が反映されないことがある。

また、ログイン完了後に terminal から xkbcomp を実行するなどしても、実行直後は設定が反映されるが、アカウントの切り替えから復帰したタイミングなどで設定がリセットされてしまう。

*1:訳語がこれでいいのか不明だが、キーコードとキーシンボルの対応付けを設定するファイル。システム上では /usr/share/X11/xkb/symbols/ の下に保存されている。

*2:ログアウトせずに「アカウントのロック/切り替え」でログイン画面を出してからロックを解除するだけでも設定が適用される模様。