QMK 固件 2026-05-31 更新日志解读:isLeftHand 移除、FORCE_NKRO 弃用与 NKRO 默认值的新配置方式
【免费下载链接】qmk_firmwareOpen-source keyboard firmware for Atmel AVR and Arm USB families项目地址: https://gitcode.com/GitHub_Trending/qm/qmk_firmware
本篇围绕 QMK 固件的 2026-05-31 版本更新日志(docs/ChangeLog/20260531.md)展开,解读其中两项影响面最广的弃用变更——isLeftHand全局变量的移除与usb.force_nkro/FORCE_NKRO的弃用——并说明各自的迁移路径与三种新的 NKRO 默认值配置方式。读完后,你可以完成键盘代码的兼容性迁移,并通过keyboard.json、keymap.json或config.h正确地为整键板设置 NKRO 启动默认值。
更新日志在 QMK 文档体系中的定位
QMK 的破坏性变更集中记录在docs/ChangeLog/目录下的日期命名日志中,本篇对应的文件为 docs/ChangeLog/20260531.md。按照 QMK 的支持/弃用政策,较大规模的弃用项需要预留公告周期:日志先发布“Deprecation Notices(弃用通知)”,说明替代方案,随后在后续版本中实际移除。因此这份 2026-05-31 日志实际上对应的是“通知期结束、正式移除”这一阶段:
- 拆分键盘的全局布尔变量
isLeftHand被移除,替代 API 是is_keyboard_left(); - 配置项
usb.force_nkro与宏FORCE_NKRO被移除,NKRO 启动默认值改为通过主机层(host)配置或NKRO_DEFAULT_ON宏指定。
变更一:移除已弃用的 isLeftHand,迁移到 is_keyboard_left()
原问题:全局变量 vs 函数
旧版 QMK 中,拆分键盘(Split Keyboard)通过全局布尔变量isLeftHand判断当前固件实例运行在左半还是右半。这种方式要求键盘侧代码直接引用一个外部符号,且与is_keyboard_master()这类“主从判断”的 API 在风格上不统一。本次更新按 [PR #25897] 移除了该全局变量,统一使用函数调用is_keyboard_left()。
迁移示例
更新日志给出的标准迁移 diff 如下(以 OLED 初始化回调为例):
oled_rotation_t oled_init_user(oled_rotation_t rotation) { - return isLeftHand ? OLED_ROTATION_180 : OLED_ROTATION_0; + return is_keyboard_left() ? OLED_ROTATION_180 : OLED_ROTATION_0; }只需把isLeftHand直接替换为is_keyboard_left()调用,语义不变。
源码层面的佐证
在当前仓库快照中,is_keyboard_left()的声明位于 quantum/keyboard.h,其弱(weak)默认实现在 quantum/keyboard.c 第 378~384 行附近:
/** \brief is_keyboard_left */ __attribute__((weak)) bool is_keyboard_left(void) { return true; }可以看到两点实现细节:
- 函数带有
__attribute__((weak))修饰,即框架提供默认实现,拆分键盘平台会提供覆盖版本;单侧板(非SPLIT_KEYBOARD)下该函数返回true。 - 框架自身代码已全面改用函数形式。例如 quantum/bootmagic/bootmagic.c 中
if (!is_keyboard_left())的左右侧判断,以及 quantum/dip_switch.c 中 DIP 开关的左右侧同步逻辑,均调用is_keyboard_left()而非读取全局变量。
注意:更新日志原文表述为“
is_keyboard_left()可在split_util.h中找到”。在当前仓库快照中,拆分相关工具头文件位于 quantum/split_common/split_util.h,而该函数的原型声明实际位于 quantum/keyboard.h。编写代码时以实际头文件声明为准,包含键盘侧通用头文件即可正常使用该函数。
变更二:移除 usb.force_nkro / FORCE_NKRO,NKRO 默认值改由 host 配置控制
为什么移除
QMK 历史上存在usb.force_nkro配置项与FORCE_NKRO宏,作用是“每次启动时强制启用 NKRO(N-Key Rollover,全键无冲)”。这一设计的隐含前提是:只有 USB 传输的键盘才需要强制 NKRO(因为 USB HID 存在按键去重问题,而某些 PS/2 等传输则不受影响)。
但从日志的说明看,这个假设已经不成立——QMK 不再把 NKRO 视为 USB 独有能力。更关键的是实际使用层面的问题:force_nkro是一个持久化(persist)配置,它会让NK_TOGG等一系列 NKRO 相关键码在用户预期之外改变行为,造成不必要的困惑。因此本次更新移除了“启动即强制”这一机制,改为只允许设置默认值,运行时状态仍可像以前一样通过NK_TOGG等键码切换。
三种配置新默认值的方式
移除FORCE_NKRO后,NKRO 的启动默认值可以通过以下三种方式配置(三者任选其一,效果均为“开机 NKRO 开启”)。
{ "host": { "default": { "nkro": true } } }该字段有 schema 与模板支撑:"nkro"布尔字段已定义在 data/schemas/keyboard.jsonschema("nkro": {"type": "boolean"}),官方键盘模板 data/templates/keyboard/keyboard.json 中也包含"nkro": true示例。对于使用 Configurator/数据驱动配置流程的键盘,这是推荐写法。
{ "config": { "host": { "default": { "nkro": true } } } }keymap.json中同样的host.default.nkro字段允许在键位映射层面覆盖默认值,适合“同一块键盘、不同键位方案使用不同 NKRO 策略”的场景。
#pragma once #define NKRO_DEFAULT_ON true源码层面的佐证
NKRO_DEFAULT_ON的消费点在 quantum/eeconfig.c 中。该文件第 50~52 行定义了回退默认值,第 89 行在初始化键位配置时赋给它:
#ifndef NKRO_DEFAULT_ON # define NKRO_DEFAULT_ON false #endifkeymap_config_t keymap_config = { .swap_control_capslock = false, // ... .nkro = NKRO_DEFAULT_ON, };由此可以确认完整的默认值决策链:
- 若用户通过
keyboard.json/keymap.json设置了host.default.nkro,则数据驱动配置在构建期生成对应定义; - 否则若
config.h中定义了NKRO_DEFAULT_ON,则使用用户定义值; - 若两者都没有,则回退到
false,即启动时 NKRO 关闭,与传统FORCE_NKRO未启用时的行为一致。
同时要注意一个行为差异:旧FORCE_NKRO是“每次启动都强制”,新机制只决定初始默认值,之后NK_TOGG等键码可以正常改变状态,这正是日志中“消除用户困惑”意图的体现。
完整变更清单(Full changelist)
以下为 2026-05-31 更新日志中的完整条目,按原始分类整理(保留 PR 编号以便检索):
Core(核心)
- 移除已弃用的
isLeftHand(#25897) - 支持“输出 Unicode”或“插入 Leader 序列”两种行为(#25940)
- 为 digitizer(数位板类输入设备)添加分辨率信息(#25958)
- 构建时始终生成
.map文件(#25961) - 为 kiibohd 启动器添加
mcu_reset实现(#25963) - 升级 VIA 至 v13(#26001)
- 新增 PixArt PMW-3325 鼠标传感器驱动(#26065)
- AT32 平台 wear leveling(磨损均衡)后备存储从 16 位升级到 32 位(#26066)
- 重构 Pixel Fractal 灯效(#26071)
- combo 代码的小型优化(#26073)
- Speculative Hold 新增约束选项:
SPECULATIVE_HOLD_ONE_KEY与SPECULATIVE_HOLD_FLOW_TERM(#26099) - 添加
std::setw头文件包含(#26153) - gtest 颜色输出绑定到 QMK 的
COLOR变量(#26159) - 修复测试名称打印错误(#26160)
- 测试拆除阶段忽略 Uninteresting test 警告(#26161)
- 移除
FORCE_NKRO(#26206)
CLI(命令行工具)
- lint 检查范围扩展到仓库内所有键位映射(#25970)
- 检测到重复模块名时直接报错失败(#26238)
子模块更新(Submodule updates)
- 更新 ChibiOS、ChibiOS-Contrib(#25730)
- 回滚上述 ChibiOS 更新(#26074)
- ChibiOS、ChibiOS-Contrib 再次更新(#26079)
- googletest 升级到 v1.16.0(#26154)
Keyboards(键盘侧)
url字段不允许为空(#25152)- 新增 nomis/rpi_pico_25x1 宏键盘(#25346)
- 移除对
QK_{LED,RGB}_MATRIX_TOGGLE键码的覆盖(#25672) - SouthPad v2 增加反向布局(#25707)
- 新增 Handwired Bouvet 宏键盘(#26040)
- 移除 blockader 用户键位映射(#26075)
- 移除已弃用的音频引脚定义(#26111)
- 移除
OLED_DISPLAY_128X32配置(#26190) - 迁移
SPLIT_OLED_ENABLE(#26194) - 为 split_data_sync 模块添加 API 版本断言(#26237)
Others(其他)
- 文档站点 VitePress 升级到 1.6.4(#26067)
- docs/features/unicode.md 补充使用方式说明(#26156)
Bugs(缺陷修复)
- 修复
USER_PRINT预处理错误剥离uprintf的问题(#25919) - 修复 repeat key 可能陷入无限递归的问题(#25926)
- 修复
arm-none-eabi-gcc下cc-option行为(#26114) - 修复
arm-none-eabi-gcc的颜色诊断输出(#26115) - 修复 retro tap 后注销按键时未屏蔽仍激活的修饰键(#26127)
- 修复 macOS Tahoe 上
make test:all的失败(#26136) - 为 mingw 工具链下弱符号未定义引用问题添加变通方案(#26167)
ws2812-pwm:允许覆盖WS2812_PWM_TICK_FREQUENCY(#26186)- 将鼠标上报值裁剪到 USB 描述符定义的逻辑范围内(#26195)
- 对齐鼠标 USB 描述符(#26230)
值得关注的其他核心变更解读
VIA 升级到 v13
VIA 是 QMK 的图形化按键配置协议,本次升级至 v13(#26001)。使用 VIA 的键盘固件在升级后,建议同步使用支持该协议版本的 VIA 前端,避免新旧协议混用带来的兼容问题。
鼠标传感器与鼠标上报
本周期与鼠标(数字小键盘/数位输入设备方向)相关的变更较多:新增 PixArt PMW-3325 传感器驱动(#26065)、digitizer 分辨率信息(#25958),以及两处鼠标上报相关的缺陷修复——把上报值裁剪到 USB 描述符逻辑范围内(#26195)和对齐鼠标 USB 描述符(#26230)。从源码结构看,这几项共同收紧了 QMK 作为复合 HID 设备(键盘 + 鼠标)时的边界正确性。
构建与测试基础设施
- 始终生成
.map文件(#25961):.map文件记录符号与段布局,对排查“flash/RAM 溢出”类问题非常有用,此变更让该产物不再依赖特定构建选项。 - 测试体系:googletest 升级 v1.16.0、gtest 颜色绑定
COLOR变量、修复测试名称打印、忽略 teardown 阶段警告(#26153~#26161 区间内的一组 PR),整体改善make test:all的输出可读性,并修复了 macOS Tahoe 上的测试失败(#26136)。 - CLI 严格化:lint 现在会检查仓库内所有键位映射(#25970),且检测到重复模块名时构建直接失败(#26238)。对提交新键盘/键位映射的贡献者而言,重复模块命名将成为硬性错误。
键盘侧清理项
本周期键盘目录还有一组“移除/迁移”类变更,如果你在维护自己的键盘,值得对照检查:
- 音频引脚定义清理:已弃用的
AUDIO_PIN相关旧宏被移除(#26111),应使用新版音频引脚定义方式; - OLED 配置迁移:
OLED_DISPLAY_128X32配置被移除(#26190),SPLIT_OLED_ENABLE完成迁移(#26194),拆分 OLED 键盘需要检查自己的rules.mk/配置是否仍引用旧符号; - 元数据约束:键盘
url字段不允许为空(#25152),信息不完整的键盘定义将无法通过校验。
迁移建议小结
如果你正在升级依赖旧接口的键盘或键位映射,建议按以下顺序自查:
- 全局搜索
isLeftHand,统一替换为is_keyboard_left()(声明见 quantum/keyboard.h,默认实现见 quantum/keyboard.c); - 全局搜索
FORCE_NKRO与force_nkro:若原来依赖“开机强制 NKRO”,改为在keyboard.json/keymap.json的host.default.nkro或config.h的NKRO_DEFAULT_ON中设置默认值(默认值消费逻辑见 quantum/eeconfig.c); - 检查 OLED 与音频配置:确认未再引用已移除的
OLED_DISPLAY_128X32、SPLIT_OLED_ENABLE(旧用法)及已弃用音频引脚宏; - 重新构建并检查
.map输出:现在每次构建都会生成.map文件,可顺手确认 flash/RAM 占用是否仍在余量之内。
以上所有条目与配置方式均以当前仓库中 docs/ChangeLog/20260531.md 的记载及对应源码实现为准;PR 编号(如 #25897、#26206)可用于在变更历史中检索原始讨论。
【免费下载链接】qmk_firmwareOpen-source keyboard firmware for Atmel AVR and Arm USB families项目地址: https://gitcode.com/GitHub_Trending/qm/qmk_firmware
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考