LinuxでKeymapをmacOSぽくする
#linuxmacユーザがmacOS離れをすると、キーマップ問題にだいたい悩まされる。
みんな同じ悩みを抱えている様子だけど、ベストプラクティスらしいものは見つからない。
- shortcut keys - How to make keyboard work like OSX System Wide? - Ask Ubuntu
- macos - Efficient key bindings using both Mac and Linux - Super User
- Is it possible to have an OS X-like key map in Gnome (Ubuntu)? : linux
自分もその1人だけど、今回だいぶ満足できる環境になったのでメモしておく。
macOSぽいキーマップとは
macOSではcommand
とctrl
で役割がちゃんと分離されている。
command
キーを使ったショートカットは、全て選択・カット・ペースト・ウィンドウを閉じる、といったよくある操作が設定されている。一方ctrl
キーを使ったショートカットは、行の先頭/末尾に移動する・行を移動する、といったemacsライクな操作が設定されている。この住み分けが非常に使いやすく、矢印キーまで手を伸ばす必要がなくホームポジションを維持しやすい。
macOSのキーマップに慣れてしまうと、他OSで文章入力中にC-a
とかC-n
を打ったときのストレスが地味に蓄積する。慣れてしまえばOS毎にショートカットは使い分けできるが、文章入力に関してはどうしてもカーソル移動に不便を感じてしまう。それくらいにmacOSのキーマップは素晴らしく、一度経験すると他OSのキーマップに不満を感じてしまうほどに依存性が高い。
環境
ハードウェアはThinkPad X1 Carbon 2017。
Ubuntu 18.04でデスクトップ環境はGnomeを使っている。
使用しているアプリケーションでキーマップの検討に関わるものは以下。
- IntelliJ等JetBrains系IDE
- Fcitx
このあたりかな。
目指すキーマップ
デフォルトの状態はこんな感じ。
ちなみにwin
キーはsuper
キーとして扱われる(厳密にはこの言い方は正しくないんだろうけど簡単のため)。
[tab]
[caps]
[shift]
[fn][ctrl][super][alt][space][alt]
これを以下の様にする。
[tab]
[ctrl]
[shift]
[fn][caps][meta][alt][space][alt]
ただし、JetBrains系ツールではleft_alt
とleft_meta
をswapさせる。
[tab]
[ctrl]
[shift]
[fn][caps][alt][meta][space][alt]
JetBrainsユーザ向けのポイントとしては
super
でなくmeta
を使うleft_alt
とleft_meta
をswapする
の2点。
JetBrainsツールのキーマップに"Mac OS X"という設定があり、これがmeta
を中心に構成されている。いちいち自分でキーマップ設定を作るよりも、既存の設定を使いまわせるほうがお手軽なのでこんなことをしている。
JetBrainsユーザではない場合は、この辺考えなくていいのでもっと楽に設定できると思う。
設定
やることざっくり書くと。
- dconf:
super
をmeta
にする- アプリケーション切り替えのキーマップを追加
- xkeysnail:
ctrl
とcaps
をswapする- アプリケーション毎にキーマップの設定をする
- JetBrains Tools: キーマップを"Mac OS X"にする
xkeysnailで頑張るスタイル。
dconf
super
をmeta
にする。gsettings
コマンドでもgnome tweaksでも好きな方で。
$ gsettings set org.gnome.desktop.input-sources xkb-options "['altwin:meta_win']"
gnome tweaksの場合、“Meta is mapped to Win"というのが、altwin(meta_win)
に対応している。
自分の環境ではこんな感じになる。
$ setxkbmap -print
xkb_keymap {
xkb_keycodes { include "evdev+aliases(qwerty)" };
xkb_types { include "complete" };
xkb_compat { include "complete" };
xkb_symbols { include "pc+us+us:2+inet(evdev)+altwin(meta_win)" };
xkb_geometry { include "pc(pc105)" };
};
dconf(xkb)側ではctrl
とcaps
のswapは設定しない。xkeysnailを使う場合、そちらでswapの設定を入れないと意図したキーマップにならないため。
次に、アプリケーション切り替えのキーマップを追加する。
これはJetBrainsツール使用時のみalt
がmeta
になっているため。meta+tab
でもアプリケーションを切り替えられるようにする。
$ gsettings get org.gnome.desktop.wm.keybindings switch-applications
['<Alt>Tab']
$ gsettings set org.gnome.desktop.wm.keybindings switch-applications "['<Alt>Tab', '<Super>Tab']"
$ gsettings get org.gnome.desktop.wm.keybindings switch-applications-backward
['<Shift><Alt>Tab']
$ gsettings set org.gnome.desktop.wm.keybindings switch-applications-backward "['<Shift><Alt>Tab', '<Shift><Super>Tab']"
xkeysnail
あんまりよくないけど、sudoで入れちゃう。
$ suso pip3 install xkeysnail
ちゃんとするならxkeysnail
ユーザ作った後にそのユーザスペースにインストールする方がお行儀良いかな。
設定はこちらを参照。
https://github.com/kobtea/dotfiles/blob/c2ae3342f2e895b75bb8d9b8db0bc7e6dd4a89fe/xkeysnail.py
ctrl
とcaps
をswapしたり、アプリケーションごとにキーマップを設定している。あんまりスマートではないけど、漏れがあったら随時追加していくスタイル。ちなみにFocusProxy
というのがJetBrainsツール。
rootで実行は避けたいので、専用ユーザを作成する。
参考: xkeysnailでキーリマップする - Qiita
$ sudo groupadd uinput
$ sudo useradd -G input,uinput -M -s /usr/bin/nologin xkeysnail
$ cat /etc/udev/rules.d/40-udev-xkeysnail.rules
KERNEL=="uinput", GROUP="uinput"
$ cat /etc/modules-load.d/uinput.conf
uinput
起動スクリプトを準備して、gnome startup applicationsに登録する。
https://github.com/kobtea/dotfiles/blob/c2ae3342f2e895b75bb8d9b8db0bc7e6dd4a89fe/xkeysnail.sh
JetBrains Tools
各ツールのKeymapで"Mac OS X"を選択するだけ。
おわりに
今回の設定で自分は満足する環境を手に入れたけど、まぁ面倒くさいこと。macOSのキーマップを完全に再現できるのは結局の所macOSだけなので、ハードウェアに不満がなければMacBook買えばいいと思う。自分はペチペチキーボードがどうにも合わないので、当分ThinkPadとUbuntuにお世話になるつもり。
余談: xkbを諦めた話
xkeysnailを使う前はxkbでなんとかできないかなーと試行錯誤していたけど結局無理だった。
そんな挫折ポイントを2つほど書き残しておく。
キーマップの変更が非推奨
参考: X KeyBoard extension - ArchWiki
xkbの設定には2種類ある。
- ルールを使う
/etc
以下に設定を記載できるが、custom optionの定義はサポートされていない
- キーマップを使う(非推奨)
- 非推奨のため
/etc
に書く等カスタマイズする方法は提供されていない
- 非推奨のため
悲しいことにaltwin(meta_win)
などのsymbolを自分で定義する方法は、非推奨なキーマップ編集でのみ可能。そして、そのキーマップは/usr/share/X11/xkb/
のみを参照し、$HOME/.xkb
といったユーザ固有のパスは提供されていない。symbolをカスタマイズする場合は、強い気持ちで/usr/share/X11/xkb
を編集していく必要がある。
Fcitxが設定をロールバックする
自分は/usr
以下をいじりたくなかったので、自前の設定とそれを読み込む以下のスクリプトを作成し、gnome startup applicationsに登録した。
#!/bin/sh
sleep 10
test -f $HOME/.xkb/keymap/mykbd.xkb && xkbcomp -I$HOME/.xkb $HOME/.xkb/keymap/mykbd.xkb $DISPLAY 2> /dev/null
これで任意のsymbolを適用できるようにはなったが、Fcitxのキー設定を変更すると/usr
で定義されたデフォルトの状態へとロールバックされてしまう。
ここでxkbは挫折した。もっと柔軟に設定できると嬉しいなー。