BUG:omarchycn font apply 后 zh-cn fallback 仍解析为 Liberation Sans #4

Open
opened 2026-08-28 09:38:07 +00:00 by guoxudong · 0 comments

System details

4.0.0.alpha-cn.7

What's wrong?

执行 omarchycn font apply 后,内置检查部分失败:

CJK fonts installed, fontconfig priority applied (~/.config/fontconfig/conf.d/64-omarchycn-cjk.conf)
PASS font: Noto Sans CJK SC
PASS font: Noto Serif CJK SC
PASS font: Noto Sans Mono CJK SC
FAIL fallback: zh-cn sans-serif -> Liberation Sans (expected SC variant)
PASS fallback: untagged CJK -> SC

复现命令:

fc-match "sans-serif:lang=zh-cn"
# 实际: LiberationSans-Regular.ttf: "Liberation Sans" "Regular"
# 预期: Noto Sans CJK SC

环境

  • Omarchy(Arch Linux + fontconfig)
  • 相关文件:
    • /etc/fonts/conf.d/50-omarchy.conf(Omarchy 系统自带)
    • ~/.config/fontconfig/conf.d/64-omarchycn-cjk.conf(由 omarchy-cn-font-apply$OMARCHY_PATH/cn/fontconfig/ 复制)
  • 检查脚本:/usr/share/omarchy/bin/omarchy-cn-font-status

根因

不是字体缺失,也不是用户配置未加载,而是 zh-cn 规则被系统配置静默架空。

1. 50-omarchy.confmode="assign" 整体替换 generic 家族名

<match target="pattern">
  <test name="family" qual="any">
    <string>sans-serif</string>
  </test>
  <edit name="family" mode="assign" binding="strong">
    <string>Liberation Sans</string>
  </edit>
</match>

assign(赋值替换,非追加)把 family 列表中的 sans-serif 直接替换Liberation Sans。serif、monospace 同理:

  • sans-serifLiberation Sans
  • serifLiberation Serif
  • monospaceJetBrainsMono Nerd Font

2. 加载顺序:用户 CJK 配置排在 50-omarchy.conf 之后

用户目录 ~/.config/fontconfig/conf.d/ 是被 /etc/fonts/conf.d/50-user.conf 引入的,而同一目录按字典序加载:50-omarchy.conf < 50-user.conf

FC_DEBUG 日志可证实:

Loading config file from /etc/fonts/conf.d/50-omarchy.conf done
Loading config file from /etc/fonts/conf.d/50-user.conf
Scanning config dir /home/guoxudong/.config/fontconfig/conf.d
Loading config file from /home/guoxudong/.config/fontconfig/conf.d/64-omarchycn-cjk.conf done

3. zh-cn 规则的 family 测试永远命中不了

64-omarchycn-cjk.conf 中的规则:

<match target="pattern">
  <test name="lang" compare="contains"><string>zh-cn</string></test>
  <test name="family"><string>sans-serif</string></test>
  <edit name="family" mode="prepend" binding="strong"><string>Noto Sans CJK SC</string></edit>
</match>

当这条规则执行时,family 列表里的 sans-serif 早已被替换成 Liberation Sans<test name="family">sans-serif</test> 不成立 → 规则静默失效,匹配落回 Liberation Sans。

附带说明

  • "untagged CJK -> SC" 之所以 PASS,是因为该规则不带任何 <test>,无条件 append,不受 assign 影响。
  • ja/ko 规则(同样测试 sans-serif以相同方式失效,只是 omarchy-cn-font-status 没有检查它们。
  • 文件尾部的三个 <alias>(针对 sans-serif/serif/monospace)同样失效——此时请求里已不存在这些 generic 家族名。

修复方案(用户侧 workaround)

不能改 /etc/fonts/conf.d/50-omarchy.conf(系统文件,升级会被覆盖)。在用户配置中为每条 lang 规则增加并行的 match 块,同时测试被替换后的具体家族

<!-- 保留原规则(防御 generic 名未被替换的环境) -->
<match target="pattern">
  <test name="lang" compare="contains"><string>zh-cn</string></test>
  <test name="family"><string>sans-serif</string></test>
  <edit name="family" mode="prepend" binding="strong"><string>Noto Sans CJK SC</string></edit>
</match>
<!-- 新增:测试 assign 之后的具体家族 -->
<match target="pattern">
  <test name="lang" compare="contains"><string>zh-cn</string></test>
  <test name="family"><string>Liberation Sans</string></test>
  <edit name="family" mode="prepend" binding="strong"><string>Noto Sans CJK SC</string></edit>
</match>

serif/monospace 以及 ja/ko 规则同理,分别补测 Liberation SerifJetBrainsMono Nerd Font

修复后验证:

PASS font: Noto Sans CJK SC
PASS font: Noto Serif CJK SC
PASS font: Noto Sans Mono CJK SC
PASS fallback: zh-cn sans-serif -> Noto Sans CJK SC
PASS fallback: untagged CJK -> SC

上游修复建议

缺陷在 omarchycn 随包分发的模板 $OMARCHY_PATH/cn/fontconfig/64-omarchycn-cjk.conf:其规则默认 generic 家族名在执行时仍然存在,这一前提在 Omarchy 系统上不成立(被自家 50-omarchy.conf 破坏)。建议上游任选其一:

  1. 模板规则同时测试 Liberation Sans 等替换后的具体家族(同上述 workaround);或
  2. zh-cn 规则不测试 family,仅按 lang prepend 对应 CJK 变体(会连带影响 serif/mono 请求,需权衡);或
  3. 50-omarchy.conf 改用 prepend 而非 assign 保留 generic 名(影响面最大,需谨慎)。

另外注意:用户自行修复 ~/.config/ 下的副本后,重跑 omarchycn font apply 会用随包模板覆盖修复,需在上游修复前避免重跑。

### System details 4.0.0.alpha-cn.7 ### What's wrong? 执行 `omarchycn font apply` 后,内置检查部分失败: ``` CJK fonts installed, fontconfig priority applied (~/.config/fontconfig/conf.d/64-omarchycn-cjk.conf) PASS font: Noto Sans CJK SC PASS font: Noto Serif CJK SC PASS font: Noto Sans Mono CJK SC FAIL fallback: zh-cn sans-serif -> Liberation Sans (expected SC variant) PASS fallback: untagged CJK -> SC ``` 复现命令: ```bash fc-match "sans-serif:lang=zh-cn" # 实际: LiberationSans-Regular.ttf: "Liberation Sans" "Regular" # 预期: Noto Sans CJK SC ``` ## 环境 - Omarchy(Arch Linux + fontconfig) - 相关文件: - `/etc/fonts/conf.d/50-omarchy.conf`(Omarchy 系统自带) - `~/.config/fontconfig/conf.d/64-omarchycn-cjk.conf`(由 `omarchy-cn-font-apply` 从 `$OMARCHY_PATH/cn/fontconfig/` 复制) - 检查脚本:`/usr/share/omarchy/bin/omarchy-cn-font-status` ## 根因 **不是字体缺失,也不是用户配置未加载,而是 zh-cn 规则被系统配置静默架空。** ### 1. `50-omarchy.conf` 用 `mode="assign"` 整体替换 generic 家族名 ```xml <match target="pattern"> <test name="family" qual="any"> <string>sans-serif</string> </test> <edit name="family" mode="assign" binding="strong"> <string>Liberation Sans</string> </edit> </match> ``` `assign`(赋值替换,非追加)把 family 列表中的 `sans-serif` **直接替换**为 `Liberation Sans`。serif、monospace 同理: - `sans-serif` → `Liberation Sans` - `serif` → `Liberation Serif` - `monospace` → `JetBrainsMono Nerd Font` ### 2. 加载顺序:用户 CJK 配置排在 `50-omarchy.conf` 之后 用户目录 `~/.config/fontconfig/conf.d/` 是被 `/etc/fonts/conf.d/50-user.conf` 引入的,而同一目录按字典序加载:`50-omarchy.conf` < `50-user.conf`。 FC_DEBUG 日志可证实: ``` Loading config file from /etc/fonts/conf.d/50-omarchy.conf done Loading config file from /etc/fonts/conf.d/50-user.conf Scanning config dir /home/guoxudong/.config/fontconfig/conf.d Loading config file from /home/guoxudong/.config/fontconfig/conf.d/64-omarchycn-cjk.conf done ``` ### 3. zh-cn 规则的 family 测试永远命中不了 `64-omarchycn-cjk.conf` 中的规则: ```xml <match target="pattern"> <test name="lang" compare="contains"><string>zh-cn</string></test> <test name="family"><string>sans-serif</string></test> <edit name="family" mode="prepend" binding="strong"><string>Noto Sans CJK SC</string></edit> </match> ``` 当这条规则执行时,family 列表里的 `sans-serif` 早已被替换成 `Liberation Sans`,`<test name="family">sans-serif</test>` 不成立 → **规则静默失效**,匹配落回 Liberation Sans。 ### 附带说明 - "untagged CJK -> SC" 之所以 PASS,是因为该规则不带任何 `<test>`,无条件 `append`,不受 `assign` 影响。 - ja/ko 规则(同样测试 `sans-serif`)**以相同方式失效**,只是 `omarchy-cn-font-status` 没有检查它们。 - 文件尾部的三个 `<alias>`(针对 sans-serif/serif/monospace)同样失效——此时请求里已不存在这些 generic 家族名。 ## 修复方案(用户侧 workaround) 不能改 `/etc/fonts/conf.d/50-omarchy.conf`(系统文件,升级会被覆盖)。在用户配置中为每条 lang 规则增加并行的 match 块,**同时测试被替换后的具体家族**: ```xml <!-- 保留原规则(防御 generic 名未被替换的环境) --> <match target="pattern"> <test name="lang" compare="contains"><string>zh-cn</string></test> <test name="family"><string>sans-serif</string></test> <edit name="family" mode="prepend" binding="strong"><string>Noto Sans CJK SC</string></edit> </match> <!-- 新增:测试 assign 之后的具体家族 --> <match target="pattern"> <test name="lang" compare="contains"><string>zh-cn</string></test> <test name="family"><string>Liberation Sans</string></test> <edit name="family" mode="prepend" binding="strong"><string>Noto Sans CJK SC</string></edit> </match> ``` serif/monospace 以及 ja/ko 规则同理,分别补测 `Liberation Serif`、`JetBrainsMono Nerd Font`。 修复后验证: ``` PASS font: Noto Sans CJK SC PASS font: Noto Serif CJK SC PASS font: Noto Sans Mono CJK SC PASS fallback: zh-cn sans-serif -> Noto Sans CJK SC PASS fallback: untagged CJK -> SC ``` ## 上游修复建议 缺陷在 omarchycn 随包分发的模板 `$OMARCHY_PATH/cn/fontconfig/64-omarchycn-cjk.conf`:其规则默认 generic 家族名在执行时仍然存在,这一前提在 Omarchy 系统上不成立(被自家 `50-omarchy.conf` 破坏)。建议上游任选其一: 1. 模板规则同时测试 `Liberation Sans` 等替换后的具体家族(同上述 workaround);或 2. zh-cn 规则不测试 family,仅按 `lang` prepend 对应 CJK 变体(会连带影响 serif/mono 请求,需权衡);或 3. `50-omarchy.conf` 改用 `prepend` 而非 `assign` 保留 generic 名(影响面最大,需谨慎)。 另外注意:用户自行修复 `~/.config/` 下的副本后,重跑 `omarchycn font apply` 会用随包模板覆盖修复,需在上游修复前避免重跑。
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: ZacharyZhang-NY/omarchycn#4