Files
arch/scripts/04c-dms-quickshell.sh
2026-03-31 20:13:15 +08:00

361 lines
13 KiB
Bash
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
# 04c-quickshell-setup.sh
# 1. 引用工具库
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PARENT_DIR="$(dirname "$SCRIPT_DIR")"
if [[ -f "$SCRIPT_DIR/00-utils.sh" ]]; then
source "$SCRIPT_DIR/00-utils.sh"
else
echo "Error: 00-utils.sh not found in $SCRIPT_DIR."
exit 1
fi
# ==============================================================================
# 核心辅助函数定义
# ==============================================================================
# --- 函数:强制安全拷贝(解决覆盖冲突) ---
force_copy() {
local src="$1"
local target_dir="$2"
if [[ -z "$src" || -z "$target_dir" ]]; then
warn "force_copy: Missing arguments"
return 1
fi
local item_name
item_name=$(basename "$src")
# 只有当拷贝的不是 "目录下的所有内容" (即路径不以 /. 结尾) 时,才执行精确删除
if [[ "$src" != */. ]]; then
# 清理 target_dir 结尾多余的斜杠或 /.
local clean_target="${target_dir%/}"
clean_target="${clean_target%/.}"
# 先安全删除目标路径的同名内容,防止目录覆盖文件的冲突
as_user rm -rf "${clean_target}/${item_name}"
fi
# 执行安全拷贝
exe as_user cp -rf "$src" "$target_dir"
}
# --- 函数:静默删除 niri 绑定 ---
niri_remove_bind() {
local target_key="$1"
local config_file="$HOME_DIR/.config/niri/dms/binds.kdl"
if [[ ! -f "$config_file" ]]; then
return 1
fi
# 使用 Python 处理,无日志,无备份
python3 -c "
import sys, re
file_path = '$config_file'
target_key = sys.argv[1]
try:
with open(file_path, 'r') as f:
content = f.read()
pattern = re.compile(r'(?m)^\s*(?!//).*?' + re.escape(target_key) + r'(?=\s|\{)')
while True:
match = pattern.search(content)
if not match:
break
start_idx = match.start()
open_brace_idx = content.find('{', start_idx)
if open_brace_idx == -1:
break
balance = 0
end_idx = -1
for i in range(open_brace_idx, len(content)):
char = content[i]
if char == '{':
balance += 1
elif char == '}':
balance -= 1
if balance == 0:
end_idx = i + 1
break
if end_idx != -1:
if end_idx < len(content) and content[end_idx] == '\n':
end_idx += 1
content = content[:start_idx] + content[end_idx:]
else:
break
with open(file_path, 'w') as f:
f.write(content)
except Exception:
pass
" "$target_key"
}
VERIFY_LIST="/tmp/shorin_install_verify.list"
rm -f "$VERIFY_LIST"
log "Installing DMS..."
# ==============================================================================
# Identify User & DM Check
# ==============================================================================
log "Identifying user..."
detect_target_user
if [[ -z "$TARGET_USER" || ! -d "$HOME_DIR" ]]; then
error "Target user invalid or home directory does not exist."
exit 1
fi
info_kv "Target" "$TARGET_USER"
# DM Check
check_dm_conflict
log "Target user for DMS installation: $TARGET_USER"
# 下载并执行安装脚本
INSTALLER_SCRIPT="/tmp/dms_install.sh"
DMS_URL="https://install.danklinux.com"
log "Downloading DMS installer wrapper..."
if curl -fsSL "$DMS_URL" -o "$INSTALLER_SCRIPT"; then
chmod +x "$INSTALLER_SCRIPT"
chown "$TARGET_USER" "$INSTALLER_SCRIPT"
log "Executing DMS installer as user ($TARGET_USER)..."
log "NOTE: If the installer asks for input, this script might hang."
pacman -S --noconfirm vulkan-headers
if runuser -u "$TARGET_USER" -- bash -c "cd ~ && $INSTALLER_SCRIPT"; then
success "DankMaterialShell installed successfully."
else
warn "DMS installer returned an error code. You may need to install it manually."
exit 1
fi
rm -f "$INSTALLER_SCRIPT"
else
warn "Failed to download DMS installer script from $DMS_URL."
fi
# ==============================================================================
# dms 随图形化环境自动启动
# ==============================================================================
section "Config" "dms autostart"
DMS_AUTOSTART_LINK="$HOME_DIR/.config/systemd/user/niri.service.wants/dms.service"
DMS_NIRI_CONFIG_FILE="$HOME_DIR/.config/niri/config.kdl"
DMS_HYPR_CONFIG_FILE="$HOME_DIR/.config/hypr/hyprland.conf"
if [[ -L "$DMS_AUTOSTART_LINK" ]]; then
log "Detect DMS systemd service enabled, disabling ...."
rm -f "$DMS_AUTOSTART_LINK"
fi
DMS_NIRI_INSTALLED="false"
DMS_HYPR_INSTALLED="false"
if command -v niri &>/dev/null; then
DMS_NIRI_INSTALLED="true"
elif command -v hyprland &>/dev/null; then
DMS_HYPR_INSTALLED="true"
fi
if [[ "$DMS_NIRI_INSTALLED" == "true" ]]; then
if ! grep -E -q "^[[:space:]]*spawn-at-startup.*dms.*run" "$DMS_NIRI_CONFIG_FILE"; then
log "Enabling DMS autostart in niri config.kdl..."
echo 'spawn-at-startup "dms" "run"' >> "$DMS_NIRI_CONFIG_FILE"
echo 'spawn-at-startup "xhost" "+si:localuser:root"' >> "$DMS_NIRI_CONFIG_FILE"
else
log "DMS autostart already exists in niri config.kdl, skipping."
fi
elif [[ "$DMS_HYPR_INSTALLED" == "true" ]]; then
log "Configuring Hyprland autostart..."
if ! grep -q "exec-once.*dms run" "$DMS_HYPR_CONFIG_FILE"; then
log "Adding DMS autostart to hyprland.conf"
echo 'exec-once = dms run' >> "$DMS_HYPR_CONFIG_FILE"
echo 'exec-once = xhost +si:localuser:root'>> "$DMS_HYPR_CONFIG_FILE"
else
log "DMS autostart already exists in Hyprland config, skipping."
fi
fi
# ==============================================================================
# fcitx5 configuration and locale
# ==============================================================================
section "Config" "input method"
if [[ "$DMS_NIRI_INSTALLED" == "true" ]]; then
if ! grep -q "fcitx5" "$DMS_NIRI_CONFIG_FILE"; then
log "Enabling fcitx5 autostart in niri config.kdl..."
echo 'spawn-at-startup "fcitx5" "-d"' >> "$DMS_NIRI_CONFIG_FILE"
else
log "Fcitx5 autostart already exists, skipping."
fi
if grep -q "^[[:space:]]*environment[[:space:]]*{" "$DMS_NIRI_CONFIG_FILE"; then
log "Existing environment block found. Injecting fcitx variables..."
if ! grep -q 'XMODIFIERS "@im=fcitx"' "$DMS_NIRI_CONFIG_FILE"; then
sed -i '/^[[:space:]]*environment[[:space:]]*{/a \ LC_CTYPE "en_US.UTF-8"\n XMODIFIERS "@im=fcitx"\n LANG "zh_CN.UTF-8"' "$DMS_NIRI_CONFIG_FILE"
else
log "Environment variables for fcitx already exist, skipping."
fi
else
log "No environment block found. Appending new block..."
cat << EOT >> "$DMS_NIRI_CONFIG_FILE"
environment {
LC_CTYPE "en_US.UTF-8"
XMODIFIERS "@im=fcitx"
LANGUAGE "zh_CN.UTF-8"
LANG "zh_CN.UTF-8"
}
EOT
fi
chown -R "$TARGET_USER:" "$PARENT_DIR/quickshell-dotfiles"
# === [ 核心修复点 ] ===
# 精准清除目标路径中会导致冲突的非目录文件(软链接)
as_user rm -rf "$HOME_DIR/.local/share/fcitx5"
as_user rm -rf "$HOME_DIR/.config/fcitx5"
# =======================
force_copy "$PARENT_DIR/quickshell-dotfiles/." "$HOME_DIR/"
elif [[ "$DMS_HYPR_INSTALLED" == "true" ]]; then
if ! grep -q "fcitx5" "$DMS_HYPR_CONFIG_FILE"; then
log "Adding fcitx5 autostart to hyprland.conf"
echo 'exec-once = fcitx5 -d' >> "$DMS_HYPR_CONFIG_FILE"
cat << EOT >> "$DMS_HYPR_CONFIG_FILE"
# --- Added by Shorin-Setup Script ---
# Fcitx5 Input Method Variables
env = XMODIFIERS,@im=fcitx
env = LC_CTYPE,en_US.UTF-8
# Locale Settings
env = LANG,zh_CN.UTF-8
# ----------------------------------
EOT
else
log "Fcitx5 configuration already exists in Hyprland config, skipping."
fi
chown -R "$TARGET_USER:" "$PARENT_DIR/quickshell-dotfiles"
# === [ 核心修复点 ] ===
as_user rm -rf "$HOME_DIR/.local/share/fcitx5"
as_user rm -rf "$HOME_DIR/.config/fcitx5"
# 这里我顺手修正了原本脚本的一个小 Bug:
# 如果 quickshell-dotfiles 包含 .config 和 .local应复制到 ~ 下,而不是 ~/.config/ 下,否则会变成 ~/.config/.config
force_copy "$PARENT_DIR/quickshell-dotfiles/." "$HOME_DIR/"
fi
# ==============================================================================
# filemanager
# ==============================================================================
section "Config" "file manager"
if [[ "$DMS_NIRI_INSTALLED" == "true" ]]; then
log "DMS niri detected, configuring nautilus"
FM_PKGS="ffmpegthumbnailer gvfs-smb nautilus-open-any-terminal xdg-terminal-exec file-roller gnome-keyring gst-plugins-base gst-plugins-good gst-libav nautilus"
echo "$FM_PKGS" >> "$VERIFY_LIST"
exe as_user paru -S --noconfirm --needed $FM_PKGS
# 默认终端处理
if ! grep -q "kitty" "$HOME_DIR/.config/xdg-terminals.list"; then
echo 'kitty.desktop' >> "$HOME_DIR/.config/xdg-terminals.list"
fi
# if [ ! -f /usr/local/bin/gnome-terminal ] || [ -L /usr/local/bin/gnome-terminal ]; then
# exe ln -sf /usr/bin/kitty /usr/local/bin/gnome-terminal
# fi
sudo -u "$TARGET_USER" dbus-run-session gsettings set com.github.stunkymonkey.nautilus-open-any-terminal terminal kitty
as_user mkdir -p "$HOME_DIR/Templates"
as_user touch "$HOME_DIR/Templates/new"
as_user touch "$HOME_DIR/Templates/new.sh"
as_user bash -c "echo '#!/bin/bash' >> '$HOME_DIR/Templates/new.sh'"
chown -R "$TARGET_USER:" "$HOME_DIR/Templates"
configure_nautilus_user
elif [[ "$DMS_HYPR_INSTALLED" == "true" ]]; then
log "DMS hyprland detected, skipping file manager."
fi
# ==============================================================================
# screenshare
# ==============================================================================
section "Config" "screenshare"
if [[ "$DMS_NIRI_INSTALLED" == "true" ]]; then
log "DMS niri detected, configuring xdg-desktop-portal"
echo "xdg-desktop-portal-gnome" >> "$VERIFY_LIST"
exe pacman -S --noconfirm --needed xdg-desktop-portal-gnome
if ! grep -q '/usr/lib/xdg-desktop-portal-gnome' "$DMS_NIRI_CONFIG_FILE"; then
log "Configuring environment in niri config.kdl"
echo 'spawn-sh-at-startup "dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP=niri & /usr/lib/xdg-desktop-portal-gnome"' >> "$DMS_NIRI_CONFIG_FILE"
fi
elif [[ "$DMS_HYPR_INSTALLED" == "true" ]]; then
log "DMS hyprland detected, configuring xdg-desktop-portal"
echo "xdg-desktop-portal-hyprland" >> "$VERIFY_LIST"
exe pacman -S --noconfirm --needed xdg-desktop-portal-hyprland
if ! grep -q '/usr/lib/xdg-desktop-portal-hyprland' "$DMS_HYPR_CONFIG_FILE"; then
log "Configuring environment in hyprland.conf"
echo 'exec-once = dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP=hyprland & /usr/lib/xdg-desktop-portal-hyprland' >> "$DMS_HYPR_CONFIG_FILE"
fi
fi
# ==============================================================================
# Validation Check: DMS & Core Components (Blackbox Audit)
# ==============================================================================
section "Config" "components validation"
log "Verifying DMS and core components installation..."
MISSING_COMPONENTS=()
if ! command -v dms &>/dev/null ; then
MISSING_COMPONENTS+=("dms")
fi
if ! command -v quickshell &>/dev/null; then
MISSING_COMPONENTS+=("quickshell")
fi
if [[ ${#MISSING_COMPONENTS[@]} -gt 0 ]]; then
error "FATAL: Official DMS installer failed to provide core binaries!"
warn "Missing core commands: ${MISSING_COMPONENTS[*]}"
write_log "FATAL" "DMS Blackbox installation failed. Missing: ${MISSING_COMPONENTS[*]}"
echo -e " ${H_YELLOW}>>> Exiting installer. Please check upstream DankLinux repo or network. ${NC}"
exit 1
else
success "Blackbox components validated successfully."
fi
# ==============================================================================
# Dispaly Manager
# ==============================================================================
section "Config" "Dispaly Manager"
log "Cleaning up legacy TTY autologin configs..."
rm -f /etc/systemd/system/getty@tty1.service.d/autologin.conf 2>/dev/null
if [ "$SKIP_DM" = true ]; then
log "Display Manager setup skipped (Conflict found or user opted out)."
warn "You will need to start your session manually from the TTY."
else
setup_ly
fi
log "Module 04c completed."