发布于 ,更新于 

🔠 修复 Arch Linux 上 electron 应用不跟系统字体的问题

昨天心血来潮把电脑字体换成了霞鹜文楷,于是就发现了一个问题,如果系统中安装了微软雅黑或 Noto Sans,那么那些 electron 应用会优先使用微软雅黑或 Noto Sans,而不是用自定义的字体。现在就使用 bubblewrap 沙盒程序来解决这个问题。

desktop 篇

依赖:bubblewrap

desktop 文件方法适用于 desktop 文件不变的 electron 应用,比如 ElectronNCM、百度网盘、微信、希沃白板等(不适用于 Discord 和 Icalingua++)。Chromium 和 Chrome 浏览器也可以用此方法让部分网页百度贴吧不显示微软雅黑和思源宋体。
此处以 ElectronNCM 为例。

首先把 ElectronNCM 的 desktop 文件复制到自己家里,便于修改。

1
cp /usr/share/applications/electron-netease-cloud-music.desktop ~/.local/share/applications/electron-netease-cloud-music.desktop

之后更改该 desktop 文件,并且修改 Exec= 一行如下:

1
Exec=/usr/bin/bwrap --dev-bind / / --tmpfs /usr/share/fonts --tmpfs /usr/local/share/fonts --tmpfs /etc/fonts/conf.d --ro-bind /usr/share/fonts/lxwk /usr/share/fonts/lxwk electron-netease-cloud-music /usr/bin/electron-netease-cloud-music

此启动命令使用 bubblewrap 创建了一个临时沙盒,以「可访问设备」的模式挂载全盘(--dev-bind / /),并屏蔽掉 Noto 和 Noto CJK 字体文件夹(--tmpfs /usr/share/fonts/noto-cjk --tmpfs /usr/share/fonts/noto,即在沙盒中把这两个文件夹挂载到 tmpfs 而非原有文件夹),这样就实现了字体的屏蔽。

这样只要这个家里的 desktop 文件不被删除,系统就会优先使用这个 desktop 文件而非 /usr/share 中的。

钩子篇

依赖:bubblewrap

Arch Linux 的包管理器 pacman 有钩子(Hooks)功能,可以让包管理器在安装或删除指定软件包的时候执行特定操作。

钩子方法适用于大部分 electron 应用,比如 ElectronNCM、百度网盘、微信、希沃白板等(不适用于 Discord 和 Icalingua++)。Chromium 和 Chrome 浏览器也可以用此方法让部分网页百度贴吧不显示微软雅黑和思源宋体。
此处也以 ElectronNCM 为例。

首先创建一个 shell 脚本,位置随意。

1
vim /usr/local/share/pacman-hooks/electron-ncm.sh # 名字和路径随意

内容如下:

1
2
#!/bin/bash
sed -i 's/Exec\=/Exec\=\/usr\/bin\/bwrap --dev-bind \/ \/ --tmpfs \/usr\/share\/fonts\/noto-cjk --tmpfs \/usr\/share\/fonts\/noto /' /usr/share/applications/electron-netease-cloud-music.desktop

此脚本更改了 ElectronNCM 的桌面启动文件,使用 bubblewrap 创建了一个临时沙盒,以「可访问设备」的模式挂载全盘(--dev-bind / /),并屏蔽掉 Noto 和 Noto CJK 字体文件夹(--tmpfs /usr/share/fonts/noto-cjk --tmpfs /usr/share/fonts/noto,即在沙盒中把这两个文件夹挂载到 tmpfs 而非原有文件夹),这样就实现了字体的屏蔽。

该 shell 脚本将会以 root 权限运行,所以不用担心权限问题。

并将这个脚本赋予可执行权限。

之后,用创建一个 pacman 钩子。

1
sudo vim /etc/pacman.hooks/electron-netease-cloud-music.hook # 钩子名称随意,不一定是包名

写入如下内容。

1
2
3
4
5
6
7
8
9
[Trigger]
Operation = Install
Operation = Upgrade
Type = Package
Target = electron-netease-cloud-music

[Action]
When = PostTransaction
Exec = /usr/local/share/pacman-hooks/electron-ncm.sh

Target 中填写软件包包名,可以填写多个,用空格分割;Exec 中填写之前创建的 shell 脚本路径。

之后在下次更新该软件包时,这个钩子就会被触发,进而执行之前的 shell 脚本,实现在软件启动时屏蔽字体。

当然,还可以使用更极端的做法,比如屏蔽掉几乎所有字体文件夹(/usr/share/fonts/usr/local/share/fonts 等),只留一个字体文件夹,并且把需要的字体放在其中。

Icalingua++

依赖:bubblewrapasar

Icalingua++ 在软件包内置了微软雅黑和 Circular Spotify TxT 字体,因此无法通过上述方法屏蔽,只能修改包体来进行屏蔽。

这是shell脚本
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#!/bin/bash
mkdir -p "/tmp/icalingua.d"
asar e "/usr/lib/icalingua/icalingua.asar" "/tmp/icalingua.d"
rm "/tmp/icalingua.d/dist/electron/fonts/CircularSpotifyTxT-Black--fonts.eot"
rm "/tmp/icalingua.d/dist/electron/fonts/CircularSpotifyTxT-Black--fonts.ttf"
rm "/tmp/icalingua.d/dist/electron/fonts/CircularSpotifyTxT-Black--fonts.woff"
rm "/tmp/icalingua.d/dist/electron/fonts/CircularSpotifyTxT-Black--fonts.woff2"
rm "/tmp/icalingua.d/dist/electron/fonts/CircularSpotifyTxT-BlackItalic--fonts.eot"
rm "/tmp/icalingua.d/dist/electron/fonts/CircularSpotifyTxT-BlackItalic--fonts.ttf"
rm "/tmp/icalingua.d/dist/electron/fonts/CircularSpotifyTxT-BlackItalic--fonts.woff"
rm "/tmp/icalingua.d/dist/electron/fonts/CircularSpotifyTxT-BlackItalic--fonts.woff2"
rm "/tmp/icalingua.d/dist/electron/fonts/CircularSpotifyTxT-Bold--fonts.eot"
rm "/tmp/icalingua.d/dist/electron/fonts/CircularSpotifyTxT-Bold--fonts.ttf"
rm "/tmp/icalingua.d/dist/electron/fonts/CircularSpotifyTxT-Bold--fonts.woff"
rm "/tmp/icalingua.d/dist/electron/fonts/CircularSpotifyTxT-Bold--fonts.woff2"
rm "/tmp/icalingua.d/dist/electron/fonts/CircularSpotifyTxT-BoldItalic--fonts.eot"
rm "/tmp/icalingua.d/dist/electron/fonts/CircularSpotifyTxT-BoldItalic--fonts.ttf"
rm "/tmp/icalingua.d/dist/electron/fonts/CircularSpotifyTxT-BoldItalic--fonts.woff"
rm "/tmp/icalingua.d/dist/electron/fonts/CircularSpotifyTxT-BoldItalic--fonts.woff2"
rm "/tmp/icalingua.d/dist/electron/fonts/CircularSpotifyTxT-Book--fonts.eot"
rm "/tmp/icalingua.d/dist/electron/fonts/CircularSpotifyTxT-Book--fonts.ttf"
rm "/tmp/icalingua.d/dist/electron/fonts/CircularSpotifyTxT-Book--fonts.woff"
rm "/tmp/icalingua.d/dist/electron/fonts/CircularSpotifyTxT-Book--fonts.woff2"
rm "/tmp/icalingua.d/dist/electron/fonts/CircularSpotifyTxT-BookItalic--fonts.eot"
rm "/tmp/icalingua.d/dist/electron/fonts/CircularSpotifyTxT-BookItalic--fonts.ttf"
rm "/tmp/icalingua.d/dist/electron/fonts/CircularSpotifyTxT-BookItalic--fonts.woff"
rm "/tmp/icalingua.d/dist/electron/fonts/CircularSpotifyTxT-BookItalic--fonts.woff2"
rm "/tmp/icalingua.d/dist/electron/fonts/CircularSpotifyTxT-Light--fonts.eot"
rm "/tmp/icalingua.d/dist/electron/fonts/CircularSpotifyTxT-Light--fonts.ttf"
rm "/tmp/icalingua.d/dist/electron/fonts/CircularSpotifyTxT-Light--fonts.woff"
rm "/tmp/icalingua.d/dist/electron/fonts/CircularSpotifyTxT-Light--fonts.woff2"
rm "/tmp/icalingua.d/dist/electron/fonts/CircularSpotifyTxT-LightItalic--fonts.eot"
rm "/tmp/icalingua.d/dist/electron/fonts/CircularSpotifyTxT-LightItalic--fonts.ttf"
rm "/tmp/icalingua.d/dist/electron/fonts/CircularSpotifyTxT-LightItalic--fonts.woff"
rm "/tmp/icalingua.d/dist/electron/fonts/CircularSpotifyTxT-LightItalic--fonts.woff2"
rm "/tmp/icalingua.d/dist/electron/fonts/CircularSpotifyTxT-Medium--fonts.eot"
rm "/tmp/icalingua.d/dist/electron/fonts/CircularSpotifyTxT-Medium--fonts.ttf"
rm "/tmp/icalingua.d/dist/electron/fonts/CircularSpotifyTxT-Medium--fonts.woff"
rm "/tmp/icalingua.d/dist/electron/fonts/CircularSpotifyTxT-Medium--fonts.woff2"
rm "/tmp/icalingua.d/dist/electron/fonts/CircularSpotifyTxT-MediumItalic--fonts.eot"
rm "/tmp/icalingua.d/dist/electron/fonts/CircularSpotifyTxT-MediumItalic--fonts.ttf"
rm "/tmp/icalingua.d/dist/electron/fonts/CircularSpotifyTxT-MediumItalic--fonts.woff"
rm "/tmp/icalingua.d/dist/electron/fonts/CircularSpotifyTxT-MediumItalic--fonts.woff2"
rm "/tmp/icalingua.d/dist/electron/fonts/msyh--assets.ttf"
ls "/tmp/icalingua.d/dist/electron/fonts"
sed -i "s/font, 'CircularSpotifyTxT Book Web', msyh, twemoji, 'PingFang SC', /'LXGW Bold WenKai','Noto Sans CJK SC',/" "/tmp/icalingua.d/dist/electron/renderer.js"
sed -i "s/'CircularSpotifyTxT Light Web'/'LXGW Bold WenKai','Noto Sans CJK SC'/" "/tmp/icalingua.d/dist/electron/renderer.js"
sed -i "s/'msyh'/'LXGW Bold WenKai','Noto Sans CJK SC'/" "/tmp/icalingua.d/dist/electron/renderer.js"

mv "/usr/lib/icalingua/icalingua.asar" "/usr/lib/icalingua/icalingua.asar.bak"
asar p "/tmp/icalingua.d" "/usr/lib/icalingua/icalingua.asar"
rm -rf "/tmp/icalingua.d"

######此处 LXGW Bold WenKai 请换成自己所需的字体

pacman 钩子可以按照上文方法创建。

该脚本使用 asar 工具解包 Icalingua++,删除其中的字体并且替换指定的 css,让 Icalingua++ 只加载指定字体(本文中为 LXGW Bold WenKai)和 Noto Sans CJK SC(为了显示特殊符号)。

只适用于 icalingua++ icalingua+±electron icalingua+±electron-git 包,不适用于 icalingua+±git 包。

附件:我修改好的霞鹜文楷粗体字独立版,可以当作系统字体使用。


2022.4.19 更新日志:勘误,并且增加了 desktop 文件方法。