main
Reported: with a separate Latin font the Latin text sat even higher than before. Measuring the user's pair (KaiTi + DejaVu Sans at 40px) explains why: DejaVu's ink box is -50..13 while KaiTi's is -46..8, so their centres differ by only 0.5px but the Latin box extends further both up and down. Centre alignment therefore leaves the extra ~4px of Latin hanging above the CJK glyphs, which is exactly what reads as 'Latin too high'. Line-box baselines for the same size are KaiTi 7, DejaVu Sans 1, Noto CJK 5. Aligning on the baseline keeps the glyph bottoms together (measured: 12 vs 13 for KaiTi+DejaVu, 16 vs 16 for Noto CJK+DejaVu). The run field is carried through explicitly and a missing value falls back to 'no shift', so the earlier stacking regression cannot recur silently. Also skip _syncSize() once the overlay is being finalized, which removes the remaining shutdown warnings. Tests: 35 unit tests updated for baseline semantics.
LX Music Lyrics
一个面向 LX Music(洛雪音乐助手)+ GNOME Shell(Wayland) 的外置桌面歌词 GNOME Shell 扩展。
- 永远悬浮在普通窗口之上,不受 Super+D(显示桌面)影响
- 锁定后完全鼠标穿透(不可拖动、不可点击)
- 支持 逐字卡拉OK高亮(lxlyric)、翻译(tlyric)、粤拼/罗马音(rlyric)
- 鼠标悬停在歌词上时自动淡出隐藏,离开后恢复
- 可配置字体、字号、已播放/正在播放/未播放/翻译/粤拼颜色、描边/背景
- 顶栏菜单控制:显示/锁定/翻译开关、播放/暂停、上一首/下一首、重新加载歌词
- 全局快捷键
为什么是 GNOME Shell 扩展而不是普通窗口?
GNOME 50 的 Mutter 仍不支持 wlr-layer-shell,普通 Wayland 客户端无法可靠地自行定位、置顶、点击穿透;Electron 桌面歌词在 Wayland 下问题更多。扩展直接把歌词绘制在 Main.uiGroup 上,因此可以同时做到:永远在普通窗口之上、不受显示桌面影响、锁定后完全穿透、用 global.get_pointer() 实现悬停隐藏、自由定位并支持多显示器。
依赖与前置条件
- GNOME Shell 50 / 51(Ubuntu 26.04+ 或同等版本),Wayland 或 X11 均可
- LX Music 桌面版 2.x,已开启 开放 API:
- LX Music → 设置 → 开放 API → 开启
- 默认地址
http://127.0.0.1:23330,可在本扩展设置中修改
glib-compile-schemas(安装脚本需要,libglib2.0-bin 自带)
安装
./install.sh
gnome-extensions enable lx-music-lyrics@dhenry
Wayland 下新安装的扩展通常需要注销并重新登录后才能加载。
卸载:
./uninstall.sh
使用说明
- 显示/隐藏:顶栏菜单开关,或快捷键
Super+Alt+L - 锁定/解锁:默认锁定(完全穿透)。解锁方式:顶栏菜单“锁定歌词”开关,或
Super+Alt+K;解锁后歌词出现虚线边框,可用鼠标左键拖动位置,松手自动保存并重新钳制到屏幕内 - 悬停隐藏:锁定状态下鼠标进入歌词区域,约 250ms 后淡出;离开后恢复(可在设置中调整或关闭)
- 播放控制:顶栏菜单或
Super+Alt+P(播放/暂停)、Super+Alt+Right(下一首)、Super+Alt+Left(上一首) - 歌词内容:
- 主歌词:
lyric;若存在lxlyric且开启“逐字高亮”,则按字点亮 - 没有 lxlyric 时按整行进度擦除,播放头用“正在播放”颜色标出
- 翻译:
tlyric;粤拼/罗马音:rlyric(粤语歌即为粤拼,如《光辉岁月》)
- 主歌词:
- 字体:歌词字体与字号分开设置(字体选择器只管字体族,字号用独立滑块);可另设西文字体,只影响英文/数字部分,中英文可各用一种字体
- 动画:换行时新行从「起始缩放」放大到 100% 并逐渐加亮,上一行同步缩小变暗;动画时长、起始缩放可调,设为 0 / 1.0 即关闭
- 长歌词:当前行超宽时跟随正在演唱的字平滑滚动,不会跳格
- 设置:顶栏菜单“设置…”打开偏好窗口(中文),可调字体、颜色、布局、动画、行为、快捷键、API 地址
故障排查
# 1. LX Music API 是否可达
curl http://127.0.0.1:23330/status?filter=status,name
# 2. 扩展状态
gnome-extensions info lx-music-lyrics@dhenry
# 3. 查看 gnome-shell 日志中的扩展输出
journalctl --user -b -o cat | grep -i "lx-music\|lx lyrics"
- 歌词不显示:先确认 API 可达;确认顶栏菜单里“显示歌词”已开启;确认 LX Music 正在播放
- 扩展未加载:确认 schema 已编译(install.sh 会执行
glib-compile-schemas);重新登录 - 快捷键冲突:设置 → 快捷键 中修改
开发与测试
npm test # 纯 JS 模块(lib/lrc.js)单元测试,无需 GNOME 环境
性能说明
- 动画只在换行后的时间窗内全速重绘:换行后约 600ms 以 60fps 跑完放大/加亮/滚动,之后立刻回到「只在换字时重绘」的省电模式。逐字歌词静止期约占单核 3%,动画期短暂升高。
- 没有逐字歌词时使用连续整行擦除,需要按
refresh-interval(默认 16ms)持续重绘,CPU 占用会更高;可在设置中把重绘间隔调大到 50–66ms 换取更低占用。 - 长行滚动使用临界阻尼插值(每帧 25%),跟随演唱进度平稳移动,不做匀速跑马灯。
- SSE 短暂断开会保留 3 秒宽限期,避免歌词闪烁。
已知限制
- 仅支持 GNOME Shell 50 / 51
- 依赖 GNOME Shell 扩展机制,Shell 大版本升级可能需要适配
- 不是所有歌都有 lxlyric / tlyric / rlyric,缺失时自动退化为整行进度或隐藏对应行
- 歌词进度依赖 LX Music 开放 API 推送(约 4Hz),并用单调时钟插值,同步精度约为毫秒级
- 许可证:GPL-3.0-or-later(见 LICENSE 与 NOTICE)
致谢 / Attribution
- tuberry/desktop-lyric(GPL-3.0-or-later)—— 本项目的 GNOME Shell 覆盖层绘制思路(St.DrawingArea + Cairo/Pango 透明绘制、锁定/解锁与
Shell.util_set_hidden_from_pick用法)参考了该项目。 - LX Music Open API 文档
Languages
JavaScript
97.7%
Shell
2%
CSS
0.3%