关键词:ubuntu, 键位映射

ubuntu 下映射 caps 键

习惯了 Mac 上的 karabiner 键位修改神器之后, 一旦切换到其他平台就会觉得非常难受, 特别是 caps 键位的映射, 所以产生了如下的方案.

需求: 映射 caps 键, 单击时映射为 esc 键, 和其他键一起用时映射为 ctrl 键。

工具: caps2esc

安装必须的依赖

  1. 需要安装 libevdev-dev

sudo apt install -y libevdev-dev

  1. 需要安装 cmake

sudo apt install cmake

  1. 需要安装 libyaml-cpp-dev

sudo apt install libyaml-cpp-dev

  1. 需要安装 libudev-dev

sudo apt install libudev-dev

  1. 安装 caps2esc 的依赖: interception/linux/tools 这个工具, 地址
1
2
3
4
5
6
7
$ git clone [email protected]:interception/linux/tools.git
# 如果不成功的话,需要使用 https 的地址 https://gitlab.com/interception/linux/tools.git
$ cd tools
$ mkdir build
$ cd build
$ cmake ..
$ make

将 build 文件夹里生成的 udevmon, intercept, uinput 放到 /opt/tools/udevmon/, /opt/tools/intercept/, /opt/tools/uinput/ 这几个目录里, 然后软链接到 /usr/local/bin

安装 caps2esc 这个 plugin

1
2
3
4
5
6
$ git clone https://gitlab.com/interception/linux/plugins/caps2esc.git
$ cd caps2esc
$ mkdir build
$ cd build
$ cmake ..
$ make

将 build 文件夹里生成的 caps2esc 放到 /opt/tools/caps2esc/ 里, 然后软链接到 /usr/local/bin

新增配置文件 /etc/udev/udevmon.yaml

1
2
3
4
- JOB: "intercept -g $DEVNODE | caps2esc | uinput -d $DEVNODE"
  DEVICE:
    EVENTS:
      EV_KEY: [KEY_CAPSLOCK, KEY_ESC]

新增 systemctl 配置 /etc/systemd/system/udevmon.service

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
[Unit]
Description=udevmon
Wants=systemd-udev-settle.service
After=systemd-udev-settle.service

[Service]
ExecStart=/usr/bin/nice -n -20 /usr/local/bin/udevmon -c /etc/udev/udevmon.yaml

[Install]
WantedBy=multi-user.target

执行 sudo systemctl enable --now udevmon 开机启动。

注意观察 sudo systemctl status udevmon 如果显示的是如下的:

● udevmon.service - udevmon
     Loaded: loaded (/etc/systemd/system/udevmon.service; enabled; vendor preset: enabled)
     Active: active (running) since Thu 2020-12-17 15:33:15 CST; 18s ago
   Main PID: 8451 (udevmon)
      Tasks: 21 (limit: 38270)
     Memory: 7.1M
     CGroup: /system.slice/udevmon.service
             ├─8451 /usr/local/bin/udevmon -c /etc/udev/udevmon.yaml
             ├─8452 sh -c intercept -g $DEVNODE | caps2esc | uinput -d $DEVNODE
             ├─8453 sh -c intercept -g $DEVNODE | caps2esc | uinput -d $DEVNODE
             ├─8454 intercept -g /dev/input/event4
             ├─8455 caps2esc
             ├─8456 uinput -d /dev/input/event4
             ├─8457 intercept -g /dev/input/event5
             ├─8458 caps2esc
             ├─8459 uinput -d /dev/input/event5
             ├─8460 sh -c intercept -g $DEVNODE | caps2esc | uinput -d $DEVNODE
             ├─8461 intercept -g /dev/input/event8
             ├─8462 caps2esc
             ├─8463 uinput -d /dev/input/event8
             ├─8467 sh -c intercept -g $DEVNODE | caps2esc | uinput -d $DEVNODE
             ├─8468 intercept -g /dev/input/event9
             ├─8469 caps2esc
             ├─8470 uinput -d /dev/input/event9
             ├─8477 sh -c intercept -g $DEVNODE | caps2esc | uinput -d $DEVNODE
             ├─8478 intercept -g /dev/input/event10
             ├─8479 caps2esc
             └─8480 uinput -d /dev/input/event10

12月 17 15:33:15 fupeng systemd[1]: Started udevmon.

表示已经成功了 ~

之前碰到的未起作用的错误如下显示, 具体原因是没有将编译好的 intercept 和 uinput 放到 PATH 下,后来都放到了 /usr/loca/bin 下,就没有问题了:

● udevmon.service - udevmon
     Loaded: loaded (/etc/systemd/system/udevmon.service; enabled; vendor preset: enabled)
     Active: active (running) since Thu 2020-12-17 15:25:00 CST; 16s ago
   Main PID: 8228 (udevmon)
      Tasks: 1 (limit: 38270)
     Memory: 2.1M
     CGroup: /system.slice/udevmon.service
             └─8228 /usr/local/bin/udevmon -c /etc/udev/udevmon.yaml

12月 17 15:25:00 fupeng nice[8231]: sh: 1: intercept: not found
12月 17 15:25:00 fupeng nice[8233]: sh: 1: uinput: not found
12月 17 15:25:00 fupeng nice[8234]: sh: 1: intercept: not found
12月 17 15:25:00 fupeng nice[8236]: sh: 1: uinput: not found
12月 17 15:25:00 fupeng nice[8238]: sh: 1: intercept: not found
12月 17 15:25:00 fupeng nice[8240]: sh: 1: uinput: not found
12月 17 15:25:00 fupeng nice[8242]: sh: 1: intercept: not found
12月 17 15:25:00 fupeng nice[8244]: sh: 1: uinput: not found
12月 17 15:25:00 fupeng nice[8246]: sh: 1: intercept: not found
12月 17 15:25:00 fupeng nice[8248]: sh: 1: uinput: not found


参考文件: