NixOS 亮度滑块无效的修复记录
问题现象
系统设置中的亮度滑块可以正常显示,也可以拖动,但屏幕实际亮度没有变化。表面上看像是 GNOME 滑块事件失效,实际上滑块背后的亮度节点选错了。
本次环境如下:
- NixOS 26.05
- GNOME 50.4,Wayland 会话
- NVIDIA GeForce RTX 4060 Laptop GPU
- NVIDIA 专有驱动 595.71.05
- Intel 核显 + NVIDIA 独显混合显卡
初步检查
先查看内核暴露的背光设备:
ls -l /sys/class/backlight
for d in /sys/class/backlight/*; do
[ -d "$d" ] || continue
echo "== $d =="
cat "$d/type"
cat "$d/brightness"
cat "$d/actual_brightness"
cat "$d/max_brightness"
readlink -f "$d"
done最初系统只有:
nvidia_wmi_ec_backlight
type=firmware
brightness=100
actual_brightness=100
max_brightness=100这个节点可以接受写入,读回值也会变化。例如设置为 50 后,brightness 和 actual_brightness 都会变成 50。但读回成功不等于屏幕物理亮度已经变化,实际屏幕仍然保持原来的亮度。
这一步排除了几个常见原因:
- 亮度滑块事件没有触发
logind没有权限写入亮度节点- sysfs 文件完全不可写
真正的问题是 WMI 节点虽然能保存数值,却没有控制当前内屏的实际背光。
Ubuntu 方案的适用性
参考的 Ubuntu 方案主要包括 acpi_backlight=vendor、NVIDIA 的 EnableBrightnessControl=1,以及直接操作 /sys/class/backlight 的方法:
这些方法不能直接全部照搬到当前环境:
acpi_backlight=vendor
测试后 /sys/class/backlight 变为空,GNOME 亮度滑块也随之消失。因此这个参数不适合当前硬件,随后撤销。
EnableBrightnessControl=1
在 NixOS 中可以通过 NVIDIA 模块参数配置:
hardware.nvidia.moduleParams = {
nvidia.NVreg_RegistryDwords = "EnableBrightnessControl=1";
};但当前使用的是 NVIDIA 595 驱动和 GNOME Wayland,会话并不是 Ubuntu 文章中的 Xorg 场景。加入该参数后,内核仍然提示没有 NVIDIA 原生背光控制,屏幕亮度没有恢复。
因此,问题不在于简单地给滑块增加权限,而在于内核选择了错误的背光控制路径。
找到真正的背光节点
最终使用的内核参数是:
boot.kernelParams = [
"acpi_backlight=native"
];重新构建并重启:
sudo nixos-rebuild switch
sudo systemctl reboot重启后出现了新的节点:
nvidia_0
type=raw
brightness=48
actual_brightness=48
max_brightness=100这里的 nvidia_0 是 NVIDIA 原生背光节点,而原来的 nvidia_wmi_ec_backlight 是 WMI 固件节点。通过 logind 直接测试原生节点:
sudo busctl call \
org.freedesktop.login1 \
/org/freedesktop/login1/session/_32 \
org.freedesktop.login1.Session \
SetBrightness ssu backlight nvidia_0 20测试结果为:
nvidia_0 brightness=20
nvidia_0 actual_brightness=20这证明原生节点能够正确接收系统亮度服务的调用。
为什么还要移除 WMI 强制参数
第一次测试 acpi_backlight=native 时,为了保留回退路径,额外加入了:
nvidia_wmi_ec_backlight.force=1这样系统同时出现 nvidia_0 和 nvidia_wmi_ec_backlight 两个节点。两个节点同时存在时,桌面环境仍可能选到 WMI 节点,导致滑块看起来在工作,但屏幕亮度不变。
因此最终配置只保留:
boot.kernelParams = [
"acpi_backlight=native"
];移除 WMI 强制加载参数后,GNOME 亮度滑块使用 NVIDIA 原生控制器,拖动亮度已经可以正常生效。
最终验证
可以使用下面的命令确认系统当前使用的节点:
ls -l /sys/class/backlight
for d in /sys/class/backlight/*; do
[ -d "$d" ] || continue
printf '%s: ' "$(basename "$d")"
printf 'type='; cat "$d/type"
printf 'brightness='; cat "$d/brightness"
printf 'actual='; cat "$d/actual_brightness"
done重点是确认亮度滑块写入的是 nvidia_0,而不是只检查某个文件的数值是否变化。对于这类问题,“写入成功并读回”只能证明控制节点接受了数据,最终还需要观察屏幕物理亮度是否变化。
结论
本次故障的根因是 NVIDIA 混合显卡环境下,系统默认使用了无效的 WMI 背光节点。最终修复方法是:
- 不使用会导致背光设备消失的
acpi_backlight=vendor。 - 使用
acpi_backlight=native让内核创建 NVIDIA 原生节点nvidia_0。 - 不强制加载
nvidia_wmi_ec_backlight,避免桌面环境选错控制器。 - 重建 NixOS 配置并重启。
这个修复针对当前 NVIDIA RTX 4060 Laptop + GNOME Wayland 环境。其他电脑如果显卡型号、驱动版本或内核不同,应该先检查 /sys/class/backlight,再决定实际使用哪个节点。