返回首页

hyprlock 在 NVIDIA RTX 5080 上锁屏黑屏排查复盘

前言

现象一句话概括:电脑睡眠唤醒后黑屏,屏幕上只有一个鼠标指针,但能盲敲密码进系统。

听起来像是典型的 NVIDIA 睡眠唤醒问题,我一开始也是这么以为的。结果这个"典型问题"一路把我带偏,中间做了一堆看起来很对、其实完全没用的事:

  • 启用 NVIDIA 官方的 suspend/resume/hibernate 服务
  • 升级显卡驱动(610.43.02 → 610.43.03)
  • 从 hyprlock 换成 swaylock
  • 尝试把睡眠模式从 S3(deep) 切成 s2idle
  • 改 hypridle 的锁屏时机(睡前锁 / 唤醒后延迟锁)
  • 甚至一度打算手动编译 hyprlock git 版

以上全部无效

最后真正的原因,简单到有点好笑:锁屏主题(hyprlock.conf)里有几个配置项,在 RTX 5080 这张卡上会导致渲染失败,画面直接黑掉,而 hyprlock 进程本身不报任何错。

这篇把整个排查过程完整记下来,一方面给同样踩坑的人(NVIDIA 新卡 + Hyprland 的组合越来越多),另一方面也提醒自己:排查时不要被"看起来最像"的方向绑架。

环境

  • 显卡:NVIDIA RTX 5080(GB203,Blackwell 架构,很新)
  • 驱动:nvidia-open-dkms 610.43.03(Blackwell 必须用开源内核模块)
  • 桌面:Hyprland 0.55 + aquamarine 0.12,Wayland 会话
  • 锁屏:hyprlock 0.9.5 + hypridle 0.1.7
  • 显示器:双屏 AOC Q27B30E(HDMI-A-1 左 / DP-1 右,均 2560×1440@60)
  • 引导器:rEFInd

先说结论

如果你也是 NVIDIA 新卡 + Hyprland 锁屏黑屏,直接看这里:

问题几乎一定在锁屏主题的渲染项,而不是睡眠 / 驱动。 hyprlock 的这些配置在部分 NVIDIA 卡上会渲染失败导致全黑(进程不报错):

  1. background { blur_passes } —— GPU 模糊 shader,本卡上直接黑。
  2. background { path = xxx.png } 用了超大分辨率的图 —— 我那张壁纸是 6600×3600,超过 GPU 纹理尺寸上限,加载失败黑屏。缩到屏幕分辨率 2560×1440 就正常了。
  3. placeholder_text 里的 <i>...</i> 斜体标签 —— 斜体文本渲染失败。
  4. label 段的 font_family = Inter —— 指定这个字体后黑屏(系统里装的是 Inter Variable/ttc,疑似 hyprlock 吃不下可变字体)。

把这几项规避掉,锁屏、睡眠自动锁屏、唤醒全部恢复正常

一个最有用的调试技巧:hyprlock -c /tmp/test.conf 单独测某个配置,不影响正式设置,改一处测一次,二分定位到底哪一行导致黑屏。

排查过程

第一阶段:以为是 NVIDIA 睡眠问题

先看日志。journalctl 里能看到系统正常进 S3、也正常唤醒(ACPI: PM: Low-level resume complete),NVIDIA 的 resume 服务也执行了。系统其实是活的——我能盲敲密码进系统就是证明。

按 Arch Wiki 的 NVIDIA 建议做了一轮标准配置:

# 启用三个电源管理服务
sudo systemctl enable nvidia-suspend.service nvidia-resume.service nvidia-hibernate.service

确认显存保留也开着(PreserveVideoMemoryAllocations: 2)、nvidia-drm.modeset=1fbdev=1 都在内核命令行里。这些都是正确的基线配置,但跟这次黑屏一点关系都没有

启用服务后再测,还是黑屏。

第二阶段:发现"系统正常,只是画面黑"

关键转折是意识到:我能盲敲密码解锁进桌面,说明系统、输入、认证全都活着,只是画面没出来。

这时才想到查会话类型和锁屏。日志里翻到这几行:

hyprlock[xxxxx]: pam_unix(hyprlock:auth): authentication failure

原来睡眠时触发了 hyprlock 锁屏,唤醒后 hyprlock 渲染成了黑屏,但它的输入逻辑还活着——所以我一直是在对着一块黑屏盲敲 hyprlock 的密码框,敲对了就解锁进桌面。

方向从"NVIDIA 睡眠"转到了"hyprlock 锁屏"。

第三阶段:一堆无效尝试

这一阶段走了很多弯路,简单列一下,都没用

  • 升级驱动 610.43.02 → 610.43.03:顺便做了个大系统更新,驱动、内核都更新了,重启后测——还是黑。
  • 换 swaylock:结果 swaylock 在这套环境上更糟,白屏 + 密码验证失败 + 退不出来,只能切 TTY 杀进程。(顺带一提,swaylock 的 PAM 配置 /etc/pam.d/swaylock 是正常的,问题不在这。)
  • 切 s2idle 睡眠模式:想着深度睡眠 S3 断电太狠,换浅睡眠试试——也不行。
  • 改锁屏时机:睡前不锁、唤醒后延迟几秒再全新启动锁屏——还是黑。

期间还发现自己把问题搞复杂了:排查时手动 hypridle & 起了多个实例,两个 hypridle 抢 org.freedesktop.ScreenSaver 接口互相打架。这是个干扰项,清成单实例后排除掉。

(另外还翻出一个之前埋的雷:为了解决"DP-1 唤醒后掉分辨率",我曾在内核命令行加过 drm.edid_firmware=DP-1:... 强制锁 EDID。这个参数反而让情况更糟,一并删掉了。)

第四阶段:一个关键对比

真正的突破口是一次偶然的对比:

  • 终端里直接敲 hyprlock → 完全正常,能看到锁屏界面、能解锁。
  • 通过快捷键 / 睡眠触发 hyprlock → 黑屏。

一开始我以为是"启动环境变量差异",但对比下来 GBM_BACKEND__GLX_VENDOR_LIBRARY_NAME 这些 NVIDIA 相关变量,终端和 Hyprland 配置里是一致的。不是环境问题。

那到底差在哪?我把锁屏主题换成一个极简纯色配置(纯色背景、无任何效果),用 hyprlock -c 单独测:

hyprlock -c /tmp/hyprlock-min.conf

正常显示了。

那问题就锁定在主题的某些配置项上,跟睡眠、驱动都无关。剩下的就是二分法:从极简配置开始,一项一项加回来,看加到哪一项黑屏。

第五阶段:逐个揪出"毒药"

二分下来,揪出了四个会导致黑屏的配置项:

1. blur_passes(模糊 shader)

background {
    blur_passes = 4    # ← 黑屏元凶
    blur_size = 10
}

这是 GPU 模糊 shader,在 RTX 5080 上渲染失败。去掉后手动锁屏就正常了。这也是"手动锁屏都黑"的真凶,非常不直觉。

2. background { path = 超大图 }

去掉 blur 后,带背景图还是黑。查了下那张壁纸:

ocean-glass.png: PNG image data, 6600 x 3600

6600×3600 —— 远超屏幕分辨率,也超过 GPU 纹理尺寸上限,hyprlock 加载纹理失败。验证方法很直接:用 path = screenshot(锁屏那刻的桌面截图,2560×1440)就能正常渲染,说明贴图本身没问题,是图太大

解法:把壁纸缩到屏幕分辨率。

magick 原图.png -resize 2560x1440^ -gravity center -extent 2560x1440 lock-bg.png

缩完就正常显示了。换锁屏壁纸务必先缩到屏幕分辨率。

3. <i> 斜体标签

placeholder_text = <i>输入密码解锁</i>   # ← 斜体渲染失败

改成普通文本即可。

4. font_family = Inter

label {
    font_family = Inter   # ← 指定后黑屏
}

系统里 Inter 装的是 Variable/ttc 格式,hyprlock 疑似吃不下可变字体。去掉,用默认字体就好。

第六阶段:意外收获——睡眠锁屏也修好了

清干净主题后,我本来已经接受"睡眠不自动锁屏 + 手动锁屏"的妥协方案了。因为之前测睡眠自动锁屏时,从 hyprlock 的 debug 日志里看到 S3 唤醒时双屏会先断开再重连(output 编号递增、重建 lock surface),我一度判定这是"显示器热插拔 + session-lock 协议 + NVIDIA 三方时序 bug,配置绕不过"。

但既然主题里的毒药清干净了,抱着试试的心态又测了一次睡前锁屏 ——

正常了。

原来根本没有什么"无解的 S3 时序 bug"。之前睡眠锁屏黑屏,纯粹是因为那时候主题还带着 blur / 超大背景图这些毒药,唤醒后 hyprlock 重建画面时渲染崩了。主题干净后,S3 唤醒时那个 output churn,hyprlock 本来就能扛过去

这里给自己记个教训:在一个变量还是脏的情况下得出的"无解"结论,往往是错的。 我误判"S3 时序无解",就是因为当时主题这个变量一直没清干净。

最终配置

锁屏主题 ~/.config/hypr/lock-themes/ocean-glass.conf

要点:纯缩放过的背景图(或静态模糊图)+ 非斜体文本 + 不指定 font_family。

general {
    hide_cursor = true
    disable_loading_bar = true
}
background {
    monitor =
    # 背景图必须 ≤ 屏幕分辨率(2560x1440),超大图会超 GPU 纹理上限而黑屏。
    # blur_passes 的 GPU shader 在本卡黑屏,勿加。
    path = $HOME/.local/share/hypr-themes/wallpapers/lock-bg-blur.png
    color = rgba(0f172aff)
}
input-field {
    monitor =
    size = 310, 52
    outline_thickness = 2
    outer_color = rgba(c4b5fdcc)
    inner_color = rgba(0f172ae6)
    font_color = rgba(e0e7ffff)
    fade_on_empty = true
    placeholder_text = 输入密码解锁
    fail_text = 密码错误,请重试 ($ATTEMPTS)
    position = 0, -46
    halign = center
    valign = center
}
label {
    monitor =
    text = $TIME
    color = rgba(e0e7ffff)
    font_size = 60
    position = 0, 108
    halign = center
    valign = center
}
label {
    monitor =
    text = cmd[update:60000] date '+%m月%d日 %A'
    color = rgba(e0e7ffcc)
    font_size = 20
    position = 0, 40
    halign = center
    valign = center
}

想要毛玻璃效果怎么办?

blur_passes 那个 GPU shader 用不了,但可以用 imagemagick 预先把壁纸做成静态模糊图,走的是普通贴图不是 shader,所以不黑屏:

magick 壁纸.png -resize 2560x1440^ -gravity center -extent 2560x1440 \
  -blur 0x18 -modulate 82 lock-bg-blur.png

视觉上跟毛玻璃很接近,代价是背景固定、不会随桌面实时变化——但锁屏背景本来也不需要实时。

hypridle 配置 ~/.config/hypr/hypridle.conf

主题去毒后,完整的闲置 / 睡眠策略就都能用了:

general {
    lock_cmd = pidof hyprlock || hyprlock
    before_sleep_cmd = loginctl lock-session     # 睡前锁屏
    after_sleep_cmd = hyprctl dispatch dpms on   # 唤醒后恢复显示输出
}

listener {
    timeout = 600                    # 10 分钟:锁屏
    on-timeout = loginctl lock-session
}
listener {
    timeout = 630                    # 10.5 分钟:关屏
    on-timeout = hyprctl dispatch dpms off
    on-resume = hyprctl dispatch dpms on
}
listener {
    timeout = 900                    # 15 分钟:休眠
    on-timeout = systemctl suspend
}

hypridle 靠 hyprland.conf 里的 exec-once = hypridle 自启单实例。注意别手动重复起,多实例会抢 ScreenSaver 接口。

总结

复盘这次排查,几个值得记下来的点:

  1. "系统活着但画面黑" 要往渲染 / 合成层查,而不是电源 / 睡眠层。 能盲敲密码进系统,就说明问题在最上面那层显示,不在底下。

  2. 善用最小复现。 hyprlock -c /tmp/test.conf 单独测配置,再用二分法一项项加回去,是这次真正解决问题的方法。比在完整环境里反复重启试要快得多。

  3. 不要被"看起来最像"的方向绑架。 NVIDIA + 睡眠 + 黑屏,看起来 100% 是驱动 / 电源问题,我在这个方向上浪费了最多时间(换驱动、切 s2idle、换锁屏程序)。真正的原因是主题配置。

  4. 在脏变量下得出的"无解"结论不可信。 我一度判定睡眠锁屏是无解的 S3 时序 bug,其实只是因为主题还没清干净。变量没隔离干净时,别急着下"绕不过"的结论。

  5. NVIDIA 新卡(Blackwell)对某些 GPU 特性更挑剔。 GPU 模糊 shader、超大纹理、可变字体,在这张卡上都会静默渲染失败。遇到 hyprlock 黑屏,优先怀疑主题里这几类东西。

折腾了一下午,最后落地的效果其实很好:毛玻璃壁纸背景、大时钟 + 中文日期、输错密码红字提示,手动锁屏、睡眠自动锁屏、唤醒全都正常。虽然过程绕,但至少把这张新卡的脾气摸清楚了。