换了新电脑,装上了 CachyOS,桌面组合最终定为 niri + Noctalia Shell v5 + SDDM。这篇简单记录一下我的 niri 个性化配置,以及一个自己写的小脚本——让 SDDM 登录界面的壁纸跟着桌面壁纸自动同步。
| 项目 |
选择 |
| 发行版 |
CachyOS |
| 窗口管理器 |
niri |
| Shell |
Noctalia Shell v5 |
| 显示管理器 |
SDDM(主题:pixie) |
niri 个性化配置#
动画
damping-ratio < 1 会回弹,= 1 是临界阻尼,epsilon 是弹簧的停止阈值,越小收敛越精确,但是计算量也越大。
// ~/.config/niri/config.kdl
animations {
window-open {
spring damping-ratio=0.6 stiffness=300 epsilon=0.001
}
window-close {
duration-ms 300
curve "ease-out-cubic"
}
window-resize {
spring damping-ratio=0.7 stiffness=800 epsilon=0.0001
}
window-movement {
spring damping-ratio=0.7 stiffness=800 epsilon=0.00001
}
horizontal-view-movement {
spring damping-ratio=1.0 stiffness=300 epsilon=0.0001
}
workspace-switch {
spring damping-ratio=0.7 stiffness=500 epsilon=0.0001
}
config-notification-open-close {
spring damping-ratio=0.6 stiffness=1200 epsilon=0.001
}
screenshot-ui-open {
duration-ms 300
curve "ease-out-quad"
}
overview-open-close {
spring damping-ratio=1.0 stiffness=500 epsilon=0.0001
}
}
| 动画 |
参数 |
手感 |
window-open |
spring 0.6 / 300 / 0.001 |
开窗有轻微回弹 |
window-close |
300ms ease-out-cubic |
干脆退出,不用弹簧 |
window-resize |
spring 0.7 / 800 / 0.0001 |
几乎不回弹,缩放跟手 |
window-movement |
spring 0.7 / 800 / 0.00001 |
与 resize 同刚度,epsilon 更小,更利落 |
horizontal-view-movement |
spring 1.0 / 300 / 0.0001 |
临界阻尼,水平滚动平滑 |
workspace-switch |
spring 0.7 / 500 / 0.0001 |
中等刚度,切换工作区带一点弹性 |
config-notification-open-close |
spring 0.6 / 1200 / 0.001 |
刚度很高,通知弹窗果断利落 |
screenshot-ui-open |
300ms ease-out-quad |
快速淡入,截图 UI 不拖沓 |
overview-open-close |
spring 1.0 / 500 / 0.0001 |
临界阻尼,概览开合平滑无回弹 |
整体取舍可以概括成三条:
- 主体交互用高刚度 + 接近临界阻尼:
window-movement / window-resize 都是 damping-ratio=0.7、stiffness=800,保证拖拽和缩放跟手;水平滚动和概览直接拉到 1.0,彻底消除过冲。
- 装饰性动画故意降阻尼留一点回弹:
window-open 和通知弹窗的 damping-ratio 都是 0.6,开窗口/弹通知时有一点点 Q 弹,但刚度分别只有 300 和 1200,快慢不同——开窗口慢一点更柔和,通知要快。
- 一次性、不需要可中断的动画用 duration + curve:
window-close 和 screenshot-ui-open 直接给固定时长和缓动曲线。关闭不需要弹簧的物理感,截图 UI 只求快速淡入。
SDDM 壁纸自动同步脚本#
背景
SDDM 的 pixie 主题背景固定读一个文件。桌面壁纸一换,登录界面还停在旧图,割裂感很强。于是写了个脚本:把当前壁纸规范化后写到 SDDM 主题的背景路径,再配合 Noctalia 的壁纸切换钩子调用即可。
整体思路
Noctalia 换壁纸
│ 触发 hook
▼
~/.local/bin/sddm-wallpaper-sync
│ 拷贝/转码(无需 sudo)
▼
/usr/local/share/sddm-wallpaper/wallpaper.jpg ← 持久目录,无任何包管理它
│ theme.conf 指向它
▼
pixie 主题(Qt6 greeter 加载)→ 登录界面显示新壁纸 + 自动取色
第 1 步:安装依赖
sudo pacman -S qt6-base qt6-declarative qt6-5compat qt6-svg imagemagick
| 包 |
作用 |
qt6-declarative |
Qt6 QML 引擎(pixie 的 QtQuick.Effects 需要 Qt ≥ 6.5) |
qt6-5compat |
提供 Qt5Compat.GraphicalEffects(部分主题组件用到) |
imagemagick |
同步脚本里把任意格式壁纸统一转成 jpg |
第 2 步:切换 Qt6 greeter + 防回退
CachyOS 的 sddm 包是 Qt6 构建,但 /usr/bin/sddm-greeter 默认是 Qt5 版(加载 pixie 必报 Library import requires a version)。这一步是这个方案能跑起来的前提。
# 确认有 qt6 版可用
ls /usr/bin/sddm-greeter* # 应有 sddm-greeter-qt6
# 换成软链
sudo mv /usr/bin/sddm-greeter /usr/bin/sddm-greeter-qt5.bak
sudo ln -s sddm-greeter-qt6 /usr/bin/sddm-greeter
# pacman hook:sddm 包更新后自动重建软链
sudo tee /etc/pacman.d/hooks/sddm-qt6-greeter.hook >/dev/null <<'EOF'
[Trigger]
Operation = Install
Operation = Upgrade
Type = Package
Target = sddm
[Action]
Description = Redirect sddm-greeter to Qt6 greeter for pixie theme
When = PostTransaction
Exec = /usr/bin/ln -sf sddm-greeter-qt6 /usr/bin/sddm-greeter
EOF
验证:
ldd /usr/bin/sddm-greeter | grep -oE 'libQt[56][A-Za-z]+' | sort -u
# 应输出 libQt6Core 等
第 3 步:安装 pixie 主题
# 从 GitHub 获取后放入
sudo cp -r pixie-sddm /usr/share/sddm/themes/pixie
修正 theme.conf 的背景路径:
sudo sed -i 's|^background=.*|background=/usr/local/share/sddm-wallpaper/wallpaper.jpg|' \
/usr/share/sddm/themes/pixie/theme.conf
其余保持原样(autoColor=true 会自动从壁纸取强调色)。
如果主题里有 Qt5 老写法 import QtGraphicalEffects,需要改成 Qt5Compat.GraphicalEffects:
grep -rln "QtGraphicalEffects" /usr/share/sddm/themes/pixie/ --include='*.qml' \
| xargs sudo sed -i 's/import QtGraphicalEffects/import Qt5Compat.GraphicalEffects/'
第 4 步:壁纸持久目录(关键经验)
sudo install -d -o $USER -g $USER -m 755 /usr/local/share/sddm-wallpaper
绝对不要放在 /var/lib/sddm/ 下——sddm 包的 tmpfiles.d 规则(d /var/lib/sddm 0750 sddm sddm)会在每次开机/更新时把权限重置回去,你的用户进不去,脚本必失败。
/usr/local/share/ 没有任何包管理规则,一劳永逸。
第 5 步:同步脚本
mkdir -p ~/.local/bin
nano ~/.local/bin/sddm-wallpaper-sync
#!/usr/bin/env bash
# 同步当前壁纸到 SDDM pixie 主题背景
# 用法: sddm-wallpaper-sync [壁纸路径] (不传参数时尝试自动探测)
set -euo pipefail
TARGET="/usr/local/share/sddm-wallpaper/wallpaper.jpg"
log() { echo "[$(date '+%F %T')] $*"; }
# ── 1. 取壁纸路径(优先级:参数 > 环境变量 > 自动探测)──
WALL="${1:-}"
[[ -z "$WALL" ]] && WALL="${WALLPAPER:-}"
[[ -z "$WALL" ]] && WALL="${NOCTALIA_WALLPAPER:-}"
[[ -z "$WALL" ]] && WALL="${NOCTALIA_WALLPAPER_PATH:-}"
if [[ -z "$WALL" ]]; then
WALL=$(grep -rhoE '/[^"]+\.(jpg|jpeg|png|webp)' ~/.config/noctalia/ 2>/dev/null \
| while read -r p; do [[ -f "$p" ]] && echo "$p"; done | head -1 || true)
fi
if [[ -z "$WALL" ]]; then
log "未获得壁纸路径,跳过(可传参: sddm-wallpaper-sync /path/to/img)"
exit 0
fi
# ── 2. 路径规范化 ──
WALL=${WALL#file://}
WALL=$(python3 -c "import urllib.parse,sys;print(urllib.parse.unquote(sys.argv[1]))" "$WALL")
if [[ ! -f "$WALL" ]]; then
log "壁纸文件不存在: $WALL" >&2
exit 1
fi
# ── 3. 内容没变就跳过 ──
if cmp -s "$WALL" "$TARGET" 2>/dev/null; then
log "壁纸未变化,跳过"
exit 0
fi
# ── 4. 写入(先写临时文件再原子替换,防止坏文件)──
TMP=$(mktemp "$(dirname "$TARGET")/.wallpaper.XXXXXX")
trap 'rm -f "$TMP"' EXIT
if command -v magick >/dev/null 2>&1; then
magick "${WALL}[0]" -auto-orient -resize '3840x2160>' -quality 90 jpg:"$TMP"
else
cp -f "$WALL" "$TMP"
fi
chmod 664 "$TMP"
mv -f "$TMP" "$TARGET"
trap - EXIT
log "SDDM 背景已更新: $WALL"
chmod +x ~/.local/bin/sddm-wallpaper-sync
脚本要点(都是坑啊)
| 设计 |
原因 |
mktemp "$(dirname "$TARGET")/..." 跟随 TARGET 目录 |
硬编码旧路径是之前失效的原因之一 |
先写临时文件再 mv 原子替换 |
防止中断留下半个坏文件导致登录界面黑屏 |
| 无需 sudo |
目录属主是你;Noctalia hook 里也没有 sudo 可用 |
file:// 前缀剥离 + URL 解码 |
壁纸路径可能带 %20、emoji 等 |
magick "${WALL}[0]" |
[0] 取第一帧,兼容动图 |
cmp 防重复写 |
换壁纸 hook 高频触发时省 IO |
第 6 步:挂到 Noctalia Hook
Noctalia Shell 设置 → Hook → 壁纸改变事件,填入:
~/.local/bin/sddm-wallpaper-sync
第 7 步:验收
# 1. 手动同步一次(无需 sudo)
~/.local/bin/sddm-wallpaper-sync ~/图片/壁纸/某张图.jpg
# 2. 自己读得到
ls -l /usr/local/share/sddm-wallpaper/wallpaper.jpg
file /usr/local/share/sddm-wallpaper/wallpaper.jpg
# 3. sddm 读得到(读不到 = 登录界面黑屏)
sudo -u sddm cat /usr/local/share/sddm-wallpaper/wallpaper.jpg > /dev/null && echo OK
# 4. 预览登录界面(不注销)
sddm-greeter-qt6 --test-mode --theme /usr/share/sddm/themes/pixie
预览日志干净(无 Cannot open、无 import 报错)→ 在 Noctalia 里换一张壁纸 → 再次预览,确认背景和强调色都变了。最后 sudo systemctl restart sddm 正式生效(会注销当前会话,先保存工作)。
配置一致性检查
grep -rn "Current" /etc/sddm.conf /etc/sddm.conf.d/ 2>/dev/null
只保留一处 [Theme] Current=pixie(推荐留 /etc/sddm.conf.d/theme.conf),把 /etc/sddm.conf 里的 [Theme] 段删掉,否则合并顺序不定,主题会莫名其妙跳回旧的。
问题速查
| 事件 |
现象 |
处理 |
| pacman 更新 sddm |
登录界面报 import 错误 |
无需处理(hook 自动重建软链);若没装 hook,重跑 sudo ln -sf sddm-greeter-qt6 /usr/bin/sddm-greeter |
| 手动重装/覆盖 pixie 主题 |
壁纸不跟着换 |
重跑第 3 步的 sed 改回 background= |
| 壁纸不跟着换(hook 失效) |
逐层排查 |
跑脚本看报错 → file 检查目标文件 → --test-mode 看加载日志 |
| 登录界面黑图 |
目标文件损坏/不可读 |
重跑一次同步脚本;sudo -u sddm cat ... 验证可读 |
最终成果展示#
配置是给自己用的,抄作业之前先想清楚自己真正需要什么。