utils/language_utils.py 的 initialize_global_language() 在任何情况下都会置 _global_language_initialized = True,包括系统语言探测没拿到有效信号、只能回落默认值的时候:
# 优先级2:从系统设置获取
system_lang = _get_system_language()
_global_language = normalize_language_code(system_lang, format='short')
_global_language_full = normalize_language_code(system_lang, format='full')
logger.info(f"全局语言已初始化(来自系统设置): {_global_language}")
_global_language_initialized = True
return _global_language
而 _get_system_language() 自带兜底(最终 return 'en'),所以"探测失败"不表现为异常,而是回落值被当成探测结果存下。此后 get_global_language() / get_global_language_full() 命中 _global_language_initialized 直接返回该值,不会再探测 —— 语言(以及 _is_china_region() 定下的 _global_region)被钉死到进程重启。
触发场景
启动瞬间所有信号都不可用时:Steamworks 尚未就绪、NEKO_LANGUAGE 未设、进程继承中性 C.UTF-8、且平台探测恰好失败(macOS 上 defaults 超时、Windows 上 GetUserDefaultLocaleName 异常)。结果是用户明明把系统设成中文,却拿到英文界面 + non-china 选源,重启才能恢复。
说明
这是既有设计,不是某个 PR 引入的回归 —— 92ed2818b~1(#1542 合入前)的 initialize_global_language() 已经是同样的写法。#1542 新增的 macOS defaults 探测只是让"探测可能失败"的路径多了一条。
#2523 把 _get_macos_locale() 改成不缓存失败结果(只缓存确定性结论),消除了该函数自身的永久化;但只要上层已经初始化完成,就不会再调到它 —— 所以那层修复对 initialize_global_language() 这条主链路无效,是 Greptile 在 #2523 上指出的。
可能的方向(需要评估,不建议顺手改)
区分「探测到的值」与「兜底默认值」,只在前者置 _global_language_initialized;兜底时保持未初始化,让下一次 getter 重新探测。风险点:
_get_system_language() 目前不区分这两种返回,要先给它一个"没探测到"的表达方式
- 若某平台永远探测不到,每次 getter 都会重跑整个初始化(含
_is_china_region),需要配一个重试上限或时间窗
- 改的是所有平台共用的初始化语义,不只 macOS
相关:#2523、#1542
utils/language_utils.py的initialize_global_language()在任何情况下都会置_global_language_initialized = True,包括系统语言探测没拿到有效信号、只能回落默认值的时候:而
_get_system_language()自带兜底(最终return 'en'),所以"探测失败"不表现为异常,而是回落值被当成探测结果存下。此后get_global_language()/get_global_language_full()命中_global_language_initialized直接返回该值,不会再探测 —— 语言(以及_is_china_region()定下的_global_region)被钉死到进程重启。触发场景
启动瞬间所有信号都不可用时:Steamworks 尚未就绪、
NEKO_LANGUAGE未设、进程继承中性C.UTF-8、且平台探测恰好失败(macOS 上defaults超时、Windows 上GetUserDefaultLocaleName异常)。结果是用户明明把系统设成中文,却拿到英文界面 +non-china选源,重启才能恢复。说明
这是既有设计,不是某个 PR 引入的回归 ——
92ed2818b~1(#1542 合入前)的initialize_global_language()已经是同样的写法。#1542 新增的 macOSdefaults探测只是让"探测可能失败"的路径多了一条。#2523 把
_get_macos_locale()改成不缓存失败结果(只缓存确定性结论),消除了该函数自身的永久化;但只要上层已经初始化完成,就不会再调到它 —— 所以那层修复对initialize_global_language()这条主链路无效,是 Greptile 在 #2523 上指出的。可能的方向(需要评估,不建议顺手改)
区分「探测到的值」与「兜底默认值」,只在前者置
_global_language_initialized;兜底时保持未初始化,让下一次 getter 重新探测。风险点:_get_system_language()目前不区分这两种返回,要先给它一个"没探测到"的表达方式_is_china_region),需要配一个重试上限或时间窗相关:#2523、#1542