Migrate full DMS personalization on Ubuntu 24.04

This commit is contained in:
wuyang
2026-07-27 15:40:02 +08:00
parent fd0fcd3437
commit a0030934c0
24 changed files with 1769 additions and 469 deletions
+204 -33
View File
@@ -5,6 +5,8 @@ readonly PROJECT="niri-beyond-glass"
readonly NIRI_TAG="v26.04"
readonly XWS_TAG="v0.8.2"
readonly RUST_TOOLCHAIN="1.85.1"
readonly DMS_REV="069ddab041c738236a8910e4c39b65d9628d3018"
readonly NIXPKGS_REV="d407951447dcd00442e97087bf374aad70c04cea"
readonly ARCHIVE_URL="https://git.k1412.top/wuyang/niri-beyond-glass/archive/main.tar.gz"
wallpaper=""
@@ -13,13 +15,14 @@ dry_run=0
rebuild=0
source_dir="${NBG_SOURCE_DIR:-}"
tmp_dir=""
selected_wallpaper=""
usage() {
cat <<'EOF'
用法:install.sh [选项]
--wallpaper PATH 使用指定的静态壁纸
--config-only 只更新配置,不安装/编译软件
--config-only 只更新配置(要求 DMS 运行层已经安装)
--rebuild 强制重新编译 Niri 和 Xwayland Satellite
--dry-run 显示将执行的主要步骤,不修改系统
-h, --help 显示帮助
@@ -127,10 +130,58 @@ install_packages() {
libxcb1-dev libxcb-composite0-dev libxcb-randr0-dev \
libxcb-res0-dev libxcb-xfixes0-dev libxcb-cursor-dev \
xwayland xdg-desktop-portal-gnome xdg-desktop-portal-gtk \
alacritty fuzzel waybar swaybg swaylock swayidle mako-notifier \
alacritty \
nautilus policykit-1-gnome pipewire-pulse wireplumber \
brightnessctl playerctl grim slurp wl-clipboard wlogout \
fonts-noto-core fonts-noto-cjk fonts-noto-color-emoji fonts-font-awesome
brightnessctl playerctl grim slurp wl-clipboard libnotify-bin \
accountsservice jq nix-bin nix-setup-systemd \
fonts-noto-core fonts-noto-cjk fonts-noto-color-emoji fonts-font-awesome \
fonts-inter fonts-jetbrains-mono
}
install_dms_runtime() {
local state_home="${XDG_STATE_HOME:-$HOME/.local/state}"
local profile="$state_home/$PROJECT/nix-profile"
local dms_flake="github:AvengeMedia/DankMaterialShell/$DMS_REV"
local nixpkgs="github:NixOS/nixpkgs/$NIXPKGS_REV"
if [[ -x "$profile/bin/dms" && -x "$profile/bin/quickshell" &&
-x "$profile/bin/matugen" && -x "$profile/bin/dgop" &&
-x "$profile/bin/dsearch" ]]; then
log "DMS 运行层已经安装,跳过"
return
fi
log "安装隔离的 DMS 1.5.3 与 Quickshell 0.3.0"
run sudo usermod -aG nix-users "$USER"
run sudo systemctl enable --now nix-daemon.socket
run mkdir -p "$state_home/$PROJECT"
if (( dry_run )); then
printf '+ sudo -u %q -g nix-users nix profile install --profile %q ...\n' \
"$USER" "$profile"
return
fi
local attempt
for attempt in 1 2 3 4 5; do
if sudo -u "$USER" -g nix-users env \
HOME="$HOME" USER="$USER" \
NIX_CONFIG="experimental-features = nix-command flakes" \
nix profile install --profile "$profile" \
"$dms_flake#dms-shell" \
"$nixpkgs#quickshell" \
"$nixpkgs#matugen" \
"$nixpkgs#dgop" \
"$nixpkgs#dsearch"; then
break
fi
(( attempt < 5 )) || die "DMS 运行层安装失败,请检查网络后重新运行脚本。"
log "下载中断,正在重试($attempt/5"
sleep 3
done
[[ -x "$profile/bin/dms" && -x "$profile/bin/quickshell" ]] ||
die "DMS 或 Quickshell 安装不完整。"
}
install_rust() {
@@ -238,9 +289,12 @@ backup_and_install_config() {
local state_home="${XDG_STATE_HOME:-$HOME/.local/state}"
local stamp
stamp="$(date +%Y%m%d-%H%M%S)"
local backup="$state_home/$PROJECT/backups/$stamp/config"
local backup_root="$state_home/$PROJECT/backups/$stamp"
local backup="$backup_root/config"
local original="$state_home/$PROJECT/original"
local names=(niri waybar fuzzel mako swaylock niri-beyond-glass)
local names=(niri waybar fuzzel mako swaylock niri-beyond-glass DankMaterialShell alacritty)
select_wallpaper "$config_home/niri-beyond-glass/wallpaper"
log "备份并安装用户配置"
run mkdir -p "$backup"
@@ -250,42 +304,127 @@ backup_and_install_config() {
run cp -a "$config_home/$name" "$backup/$name"
fi
done
if [[ ! -e "$original/.captured" ]]; then
run mkdir -p "$original/config"
for name in "${names[@]}"; do
if [[ -e "$config_home/$name" ]]; then
run cp -a "$config_home/$name" "$original/config/$name"
fi
done
run touch "$original/.captured"
if [[ -d "$state_home/DankMaterialShell" ]]; then
run mkdir -p "$backup_root/state"
run cp -a "$state_home/DankMaterialShell" "$backup_root/state/DankMaterialShell"
fi
run mkdir -p \
run mkdir -p "$original/config" "$original/absent"
for name in "${names[@]}"; do
if [[ ! -e "$original/config/$name" && ! -e "$original/absent/$name" ]]; then
if [[ -e "$config_home/$name" ]]; then
run cp -a "$config_home/$name" "$original/config/$name"
else
run touch "$original/absent/$name"
fi
fi
done
run touch "$original/.captured"
if (( dry_run )); then
printf '+ install DMS, Niri and Alacritty style while preserving wallpaper %q\n' \
"$selected_wallpaper"
return
fi
mkdir -p \
"$config_home/niri" \
"$config_home/waybar" \
"$config_home/fuzzel" \
"$config_home/mako" \
"$config_home/swaylock" \
"$config_home/niri/dms" \
"$config_home/niri-beyond-glass" \
"$config_home/DankMaterialShell/themes" \
"$config_home/alacritty" \
"$config_home/systemd/user" \
"$state_home/DankMaterialShell" \
"$HOME/.local/bin" \
"$HOME/Pictures/Screenshots"
run install -m644 "$source_dir/config/niri/config.kdl" "$config_home/niri/config.kdl"
run install -m644 "$source_dir/config/waybar/config.jsonc" "$config_home/waybar/config.jsonc"
run install -m644 "$source_dir/config/waybar/style.css" "$config_home/waybar/style.css"
run install -m644 "$source_dir/config/fuzzel/fuzzel.ini" "$config_home/fuzzel/fuzzel.ini"
run install -m644 "$source_dir/config/mako/config" "$config_home/mako/config"
run install -m644 "$source_dir/config/swaylock/config" "$config_home/swaylock/config"
run install -m755 "$source_dir/scripts/niri-beyond-wallpaper" "$HOME/.local/bin/niri-beyond-wallpaper"
install -m644 "$source_dir/config/niri/config.kdl" "$config_home/niri/config.kdl"
sed "s|__HOME__|$HOME|g" "$source_dir/config/niri/beyond-glass.kdl" \
> "$config_home/niri/beyond-glass.kdl"
install -m644 "$source_dir"/config/niri/dms/*.kdl "$config_home/niri/dms/"
select_wallpaper "$config_home/niri-beyond-glass/wallpaper"
local theme_file="$config_home/DankMaterialShell/themes/beyond-glass.json"
install -m644 "$source_dir/config/dms/beyond-glass.json" "$theme_file"
local settings_tmp session_tmp
settings_tmp="$(mktemp)"
session_tmp="$(mktemp)"
jq --arg wallpaper "$selected_wallpaper" --arg theme "$theme_file" '
.customThemeFile = $theme
| .greeterWallpaperPath = $wallpaper
| .lockScreenWallpaperPath = $wallpaper
| .lockScreenVideoPath = ""
' "$source_dir/config/dms/settings.json" > "$settings_tmp"
jq --arg wallpaper "$selected_wallpaper" '
.wallpaperPath = $wallpaper
| .wallpaperPathLight = $wallpaper
| .wallpaperPathDark = $wallpaper
| .monitorWallpapers = {}
| .monitorWallpapersLight = {}
| .monitorWallpapersDark = {}
| .perMonitorWallpaper = false
' "$source_dir/config/dms/session.json" > "$session_tmp"
install -m644 "$settings_tmp" "$config_home/DankMaterialShell/settings.json"
install -m644 "$session_tmp" "$state_home/DankMaterialShell/session.json"
rm -f "$settings_tmp" "$session_tmp"
touch "$config_home/DankMaterialShell/.firstlaunch" \
"$config_home/DankMaterialShell/.changelog-1.5"
install -m644 "$source_dir/config/alacritty/alacritty.toml" \
"$config_home/alacritty/alacritty.toml"
install -m644 "$source_dir/config/systemd/dms.service" \
"$config_home/systemd/user/dms.service"
install -m755 "$source_dir/scripts/niri-beyond-browser" \
"$HOME/.local/bin/niri-beyond-browser"
install -m755 "$source_dir/scripts/niri-beyond-refresh" \
"$HOME/.local/bin/niri-beyond-refresh"
local profile="$state_home/$PROJECT/nix-profile"
local binary
for binary in dms quickshell qs matugen dgop dsearch; do
if [[ -x "$profile/bin/$binary" ]]; then
ln -sfn "$profile/bin/$binary" "$HOME/.local/bin/$binary"
fi
done
printf '%s\n' "$selected_wallpaper" > "$config_home/niri-beyond-glass/wallpaper"
}
select_wallpaper() {
local state_file="$1"
local selected="$wallpaper"
if [[ -z "$selected" ]]; then
local existing=""
if [[ -r "$state_file" ]]; then
existing="$(head -n1 "$state_file")"
fi
if [[ -n "$existing" && -f "$existing" ]]; then
selected="$existing"
fi
fi
if [[ -z "$selected" ]]; then
local session="${XDG_STATE_HOME:-$HOME/.local/state}/DankMaterialShell/session.json"
local existing=""
if [[ -r "$session" ]]; then
existing="$(jq -r '.wallpaperPath // empty' "$session" 2>/dev/null || true)"
fi
if [[ -n "$existing" && -f "$existing" ]]; then
selected="$existing"
fi
fi
if [[ -z "$selected" ]] && command -v gsettings >/dev/null 2>&1; then
local uri=""
uri="$(gsettings get org.gnome.desktop.background picture-uri-dark 2>/dev/null \
| tr -d "'" || true)"
uri="${uri#file://}"
if [[ -n "$uri" && -f "$uri" ]]; then
selected="$uri"
fi
fi
if [[ -z "$selected" ]]; then
local candidates=(
/usr/share/backgrounds/warty-final-ubuntu.png
@@ -306,10 +445,35 @@ select_wallpaper() {
-print -quit 2>/dev/null || true)"
fi
[[ -n "$selected" && -f "$selected" ]] ||
die "没有找到可用壁纸;可用 --wallpaper PATH 指定目标机上的图片。"
selected_wallpaper="$selected"
log "保留目标机壁纸:$selected_wallpaper"
}
activate_dms() {
local profile="${XDG_STATE_HOME:-$HOME/.local/state}/$PROJECT/nix-profile"
if (( dry_run )); then
printf '+ write wallpaper path %q to %q\n' "$selected" "$state_file"
else
printf '%s\n' "$selected" > "$state_file"
printf '+ stop legacy shell processes and enable dms.service\n'
return
fi
if ! systemctl --user daemon-reload 2>/dev/null; then
log "当前没有可用的 systemd 用户会话;DMS 将在下次 Niri 登录时启动"
return
fi
systemctl --user disable --now waybar.service mako.service 2>/dev/null || true
pkill -x waybar 2>/dev/null || true
pkill -x mako 2>/dev/null || true
pkill -x swaybg 2>/dev/null || true
pkill -x swayidle 2>/dev/null || true
systemctl --user enable dms.service
"$profile/bin/dms" auth resolve-lock --quiet >/dev/null 2>&1 || true
if [[ -n "${WAYLAND_DISPLAY:-}" ]]; then
systemctl --user restart dms.service
fi
}
@@ -331,14 +495,21 @@ main() {
install_libdisplay_info
install_niri
install_xwayland_satellite
install_dms_runtime
else
local profile="${XDG_STATE_HOME:-$HOME/.local/state}/$PROJECT/nix-profile"
[[ -x "$profile/bin/dms" && -x "$profile/bin/quickshell" ]] ||
die "--config-only 需要先完成一次完整安装。"
fi
backup_and_install_config
validate_config
activate_dms
log "安装完成"
printf '\n请注销,在 GDM 会话菜单中选择“Niri”后登录。\n'
printf 'GNOME 和 GDM 均未被修改;快捷键说明:Super+Shift+/。\n'
printf '\nDMS 个性化已迁移,目标机原壁纸和显示器布局未修改。\n'
printf '当前若在 Niri 中,顶栏会自动重启;否则注销后选择“Niri”登录。\n'
printf 'GNOME 和 GDM 均未修改;快捷键说明:Super+Shift+/。\n'
}
main