xkeysnailでキーコードの交換やワンショットモディファイヤができるとわかったので、試してみました。
Antergos、Xorg、GDMの環境にインストールします。
$ lsb_release -a
LSB Version: 1.4
Distributor ID: Arch
Description: Arch Linux
Release: rolling
Codename: ISO-Rolling
$ uname -r
4.14.15-1-ARCH
$ python --version
Python 3.6.4
導入
venvで/opt/xkeysnail
配下にインストールします。
$ sudo python -m venv /opt/xkeysnail
[sudo] miy4 のパスワード:
$ . /opt/xkeysnail/bin/activate
(xkeysnail) $ sudo pip install xkeysnail
Collecting xkeysnail
Downloading xkeysnail-0.1.0.tar.gz
Collecting evdev (from xkeysnail)
Downloading evdev-0.7.0.tar.gz
Collecting python-xlib (from xkeysnail)
Downloading python_xlib-0.21-py2.py3-none-any.whl (123kB)
100% |████████████████████████████████| 133kB 345kB/s
Collecting six>=1.10.0 (from python-xlib->xkeysnail)
Downloading six-1.11.0-py2.py3-none-any.whl
Installing collected packages: evdev, six, python-xlib, xkeysnail
Running setup.py install for evdev ... done
Running setup.py install for xkeysnail ... done
Successfully installed evdev-0.7.0 python-xlib-0.21 six-1.11.0 xkeysnail-0.1.0
(xkeysnail) $ deactivate
2019/1/27追記:PyPIとGithubにあるxkeysnailのバージョンが違うので、ご注意ください。リリース版ではないのかもしれませんが、Githubの方が開発が進んでおり、機能追加、バグ修正がされています。
2019/11/11追記:2019年5月にPyPIで0.2.0がリリースされています。GitHubとPyPIで機能的には同等のものが導入できるようになっています。
キーリマップの設定
以下の方針で設定します。
- CapsLockキー
- 単体で押すと
ESC
、他のキーと一緒に押すと(つまり修飾キーとして使うと)Ctrl
として使う - 単純に
CapsLock
とCtrl
を交換するなら、define_modmap
が使える
- 単体で押すと
- 変換キー
- 単体で押すと
変換
、修飾キーとして使うとCtrl
- 単体で押すと
- 無変換キー
- 単体で押すと
無変換
、修飾キーとして使うとAlt
- 単体で押すと
右手、左手、それぞれでCtrl
とAlt
を押しやすくなるので、Emacsを使う環境でよく設定しています。
# -*- coding: utf-8 -*-
import re
from xkeysnail.transform import *
#define_modmap({
# Key.CAPSLOCK: Key.LEFT_CTRL
#})
define_multipurpose_modmap({
Key.CAPSLOCK: [Key.ESC, Key.LEFT_CTRL],
Key.MUHENKAN: [Key.MUHENKAN, Key.LEFT_ALT],
Key.HENKAN: [Key.HENKAN, Key.RIGHT_CTRL]
})
これだけ!かんたん!
起動:失敗
$ sudo /opt/xkeysnail/bin/xkeysnail /etc/opt/xkeysnail/config.py
██╗ ██╗██╗ ██╗███████╗██╗ ██╗
╚██╗██╔╝██║ ██╔╝██╔════╝╚██╗ ██╔╝
╚███╔╝ █████╔╝ █████╗ ╚████╔╝
██╔██╗ ██╔═██╗ ██╔══╝ ╚██╔╝
██╔╝ ██╗██║ ██╗███████╗ ██║
╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝ ╚═╝
███████╗███╗ ██╗ █████╗ ██╗██╗
██╔════╝████╗ ██║██╔══██╗██║██║
███████╗██╔██╗ ██║███████║██║██║
╚════██║██║╚██╗██║██╔══██║██║██║
███████║██║ ╚████║██║ ██║██║███████╗
╚══════╝╚═╝ ╚═══╝╚═╝ ╚═╝╚═╝╚══════╝
v0.1.0
Traceback (most recent call last):
File "/opt/xkeysnail/bin/xkeysnail", line 6, in <module>
cli_main()
File "/opt/xkeysnail/lib/python3.6/site-packages/xkeysnail/__init__.py", line 44, in cli_main
eval_file(args.config)
File "/opt/xkeysnail/lib/python3.6/site-packages/xkeysnail/__init__.py", line 5, in eval_file
exec(compile(file.read(), path, 'exec'), globals())
File "/etc/opt/xkeysnail/config.py", line 4, in <module>
from xkeysnail.transform import *
File "/opt/xkeysnail/lib/python3.6/site-packages/xkeysnail/transform.py", line 13, in <module>
def get_active_window_wm_class(display=Xlib.display.Display()):
File "/opt/xkeysnail/lib/python3.6/site-packages/Xlib/display.py", line 89, in __init__
self.display = _BaseDisplay(display)
File "/opt/xkeysnail/lib/python3.6/site-packages/Xlib/display.py", line 71, in __init__
protocol_display.Display.__init__(self, *args, **keys)
File "/opt/xkeysnail/lib/python3.6/site-packages/Xlib/protocol/display.py", line 167, in __init__
raise error.DisplayConnectionError(self.display_name, r.reason)
Xlib.error.DisplayConnectionError: Can't connect to display ":1": b'No protocol specified\n'
Can't connect to display ":1"
と言っており、Xサーバに繋がらなかったようです。
xhostで確認すると、rootの接続は許可されていないのがわかります。
$ xhost
access control enabled, only authorized clients can connect
SI:localuser:miy4
起動:成功
試しにxhost +SI:localuser:root
でアクセスコントロールリストにrootを追加して、xkeysnailが起動することを確認しました。
$ xhost +SI:localuser:root
localuser:root being added to access control list
$ xhost
access control enabled, only authorized clients can connect
SI:localuser:root
SI:localuser:miy4
$ sudo /opt/xkeysnail/bin/xkeysnail /etc/opt/xkeysnail/config.py
██╗ ██╗██╗ ██╗███████╗██╗ ██╗
╚██╗██╔╝██║ ██╔╝██╔════╝╚██╗ ██╔╝
╚███╔╝ █████╔╝ █████╗ ╚████╔╝
██╔██╗ ██╔═██╗ ██╔══╝ ╚██╔╝
██╔╝ ██╗██║ ██╗███████╗ ██║
╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝ ╚═╝
███████╗███╗ ██╗ █████╗ ██╗██╗
██╔════╝████╗ ██║██╔══██╗██║██║
███████╗██╔██╗ ██║███████║██║██║
╚════██║██║╚██╗██║██╔══██║██║██║
███████║██║ ╚████║██║ ██║██║███████╗
╚══════╝╚═╝ ╚═══╝╚═╝ ╚═╝╚═╝╚══════╝
v0.1.0
No keyboard devices specified via (--devices) option.
xkeysnail picks up keyboard-ish devices from the list below:
-----------------------------------------------------------------------------------
Device Name Phys
-----------------------------------------------------------------------------------
/dev/input/event0 AT Translated Set 2 keyboard isa0060/serio0/input0
/dev/input/event1 Lid Switch PNP0C0D/button/input0
/dev/input/event2 Sleep Button PNP0C0E/button/input0
/dev/input/event3 Power Button LNXPWRBN/button/input0
/dev/input/event4 PC Speaker isa0061/input0
/dev/input/event5 ThinkPad Extra Buttons thinkpad_acpi/input0
/dev/input/event6 Integrated Camera: Integrated C usb-0000:00:14.0-8/button
/dev/input/event7 SynPS/2 Synaptics TouchPad isa0060/serio1/input0
/dev/input/event8 Video Bus LNXVIDEO/video/input0
/dev/input/event9 HDA Digital PCBeep card0/codec#0/beep0
/dev/input/event10 HDA Intel PCH Mic ALSA
/dev/input/event11 HDA Intel PCH Headphone ALSA
/dev/input/event12 HDA Intel PCH HDMI/DP,pcm=3 ALSA
/dev/input/event13 HDA Intel PCH HDMI/DP,pcm=7 ALSA
/dev/input/event14 HDA Intel PCH HDMI/DP,pcm=8 ALSA
/dev/input/event15 HDA Intel PCH HDMI/DP,pcm=9 ALSA
/dev/input/event16 HDA Intel PCH HDMI/DP,pcm=10 ALSA
/dev/input/event17 TPPS/2 IBM TrackPoint synaptics-pt/serio0/input0
/dev/input/event18 py-evdev-uinput py-evdev-uinput
Okay, now enable remapping on the following device(s):
------------------------------------------------------------------------------
Device Name Phys
------------------------------------------------------------------------------
/dev/input/event0 AT Translated Set 2 keyboard isa0060/serio0/input0
自動起動
ここまでをふまえて、ログイン時にxkeysnailを自動的に起動するようにしたいです。
Xサーバへの接続やuinputの読み書きのアクセスコントロールが必要なので、rootでやるのは怖さを感じる。xkeysnail用のユーザを作ることにします。
起動用のユーザを作成
$ sudo groupadd uinput
$ sudo useradd -G input,uinput -s /sbin/nologin xkeysnail
inputグループは/dev/input/*
の所有者グループです。
xkeysnailユーザには/dev/input/*
、/dev/uinput
へのアクセス権限を与えます。
KERNEL=="uinput", GROUP="uinput"
uinput
xkeysnailユーザにsudoし、xkeysnailを実行する時は、パスワードは省略します。
miy4 ALL=(ALL) ALL,\
(xkeysnail) NOPASSWD: /opt/xkeysnail/bin/xkeysnail
10-installer
はAntergos (Arch Linux)導入時に用意されたsudoersファイルです。
設定
GDMはXセッション開始時に~/.xprofile
を実行するので、ここでxkeysnailを起動します。
if [ -x /opt/xkeysnail/bin/xkeysnail ]; then
xhost +SI:localuser:xkeysnail
sudo -u xkeysnail DISPLAY=:1 /opt/xkeysnail/bin/xkeysnail /etc/opt/xkeysnail/config.py &
fi
Linuxを再起動し、GDMからログインし、キーリマップが働いていることを確認します。
課題
Thinkpad keyboardのトラックポイントが効かない
上記のBluetoothキーボードを使っているのだけど、xkeysnailで同キーボードの/dev/input/event*
を指定すると、トラックポイントが使えなくなる。キーボードのリマップはできている。
外付けではない、Thinkpad内臓のキーボードではトラックポイントも問題なく使えているので、同キーボード固有の問題なのだと思う。要調査。←keyイベントとmouseイベントが混在したデバイスに対してのxkeysnailの扱いが影響しているようです。fujimisakariさんのコメントを参照