起因

装完系统只是能开机,桌面才是每天要面对的东西。

安装过程见上一篇:Arch Linux 安装实录:Windows 双系统、Btrfs 与 GRUB。这篇只讲装完之后的桌面:Hyprland、Noctalia、zsh、输入法,还有平时用的一些工具。应用部分单独开一篇,这里先不展开。

我对桌面的要求就几个:深色、圆角、毛玻璃、键盘优先,颜色最好跟着壁纸走。现在这套从 7 月底开始折腾,到现在两个多月,基本稳定,虽然还是经常改。

我认为 Arch Linux 在合理的软件控制下也是十分稳定的。

桌面栈

层 组件 版本 / 说明
登录器 SDDM 0.21.0,X11 greeter,登录后启动 Hyprland Wayland 会话
合成器 Hyprland 0.56.2,Wayland,Lua 配置
桌面壳 Noctalia v5.3.0(noctalia-git),bar、启动器、通知、锁屏、截图、壁纸都归它管
终端 kitty 0.49.2,JetBrainsMono Nerd Font 12pt
Shell zsh 5.9.2 + zinit + starship 1.27.0
输入法 fcitx5 5.1.23 + Rime(雾凇拼音 + 万象语法模型)
编辑器 Neovim 0.12.6,lazy.nvim 管理插件
字体 / 图标 Noto Sans CJK、JetBrainsMono NF、Papirus-Dark 中文、等宽、图标各一套

启动链大概是这样:

1
2
3
4
5
SDDM(X11 greeter)
└─ Hyprland(Wayland)
├─ dbus-update-activation-environment
├─ Noctalia(bar / 通知 / 壁纸 / 锁屏)
└─ fcitx5(输入法)

10 月 11 日之前用的是 greetd + noctalia-greeter,后来发现 greetd 没法解锁密钥环,就换成了 SDDM。现在 sddm.conf.d/10-hyprland.conf 里就两条:DisplayServer=x11 和主题 maldives。SDDM 的会话列表同时读 Wayland / X11 目录,所以 Hyprland 照样会出现;登录后执行的还是 /usr/bin/start-hyprland,会话本身是原生 Wayland。

Hyprland

Hyprland 0.56 用 Lua 写配置,入口是 ~/.config/hypr/hyprland.lua。我把它拆成了 conf/ 下一堆模块,入口只负责 require:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
require("conf.monitors")
require("conf.programs")
require("conf.environment")
require("conf.autostart")
require("conf.appearance")
require("conf.animation")
require("conf.layout")
require("conf.misc")
require("conf.input")
require("conf.keybinding")
require("conf.workspaces")
require("conf.windowrule")

-- Noctalia 生成的颜色模板
require("noctalia").apply_theme()

-- hyprmoncfg 生成的显示器规则最后加载,避免被前面的配置覆盖
do local path = os.getenv("HOME") .. "/.config/hypr/hyprmoncfg-monitors.lua"; local file = io.open(path, "r"); if file then file:close(); dofile(path) end end
模块 负责什么
monitors 默认显示器策略(实际布局由 hyprmoncfg 生成的文件接管)
programs 终端、文件管理器、浏览器、Noctalia IPC 前缀
environment 语言、缩放、Wayland 后端、输入法环境变量
autostart dbus-update-activation-environment、Noctalia、fcitx5
appearance 间隙、边框、圆角、透明度、模糊、阴影
animation bezier 曲线、弹簧动画、各 leaf 的速度
layout Dwindle / Master / Scrolling
misc XWayland、权限、杂项
input 键盘布局、触控板、手势
keybinding 快捷键
workspaces 持久工作区(目前基本用默认)
windowrule 窗口规则、浮动、图层规则

外观

外观部分就是比较典型的“深色 + 圆角 + 毛玻璃”,参数如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
hl.config({
general = {
gaps_in = 2,
gaps_out = 5,
border_size = 2,
col = {
active_border = { colors = {"rgba(33ccffee)", "rgba(00ff99ee)"}, angle = 45 },
inactive_border = "rgba(595959aa)",
},
resize_on_border = true,
layout = "dwindle",
},
decoration = {
rounding = 10,
rounding_power = 2,
active_opacity = 0.82,
inactive_opacity = 0.75,
shadow = { enabled = true, range = 4, render_power = 3, color = 0xee1a1a1a },
blur = {
enabled = true, size = 6, passes = 3,
new_optimizations = true, ignore_opacity = true,
xray = false, vibrancy = 0.1696,
},
},
})

边框是青色到绿色的 45° 渐变,窗口失焦后透明度会再降一点,配合模糊能看出层级。动画加了个弹簧:

1
2
hl.curve("easy", { type = "spring", mass = 1, stiffness = 238.1191, dampening = 24.21279333 })
hl.animation({ leaf = "windows", speed = 4.79, spring = "easy" })

手势和快捷键

触控板手势是我最喜欢的一部分:

手势 动作
双指捏合 实时缩放(锚点在光标)
三指左右滑 切换工作区
三指上 / 下 音量 + / -
四指左 / 右 亮度 - / +
四指上 打开启动器
四指下 关闭当前窗口

键盘以 SUPER 为主修饰键,常用的几个:

快捷键 动作
Super + Return kitty
Super + E Nautilus
Super + B Firefox(Flatpak)
Super + R / Super + . Noctalia 启动器
Super + Q 关闭窗口
Super + F 切换浮动
Super + A 全屏
Super + L 锁屏
Super + V 剪贴板历史
Super + W 壁纸面板;Super + Shift + W 随机壁纸
Super + Shift + S 区域截图
Super + M 打开 hyprmoncfg
Super + H 快捷键速查面板

窗口规则里比较有用的几条:微信 / QQ 的子窗口默认浮动、主窗口平铺;mpv、imv、kitty 开成 80% 居中浮动;XWayland 的 CSD 窗口去掉 Hyprland 边框、模糊和阴影,避免和客户端自己的装饰叠在一起;另外还有一条专门修 XWayland 拖拽的规则。

显示器和缩放

三块屏的布局是 hyprmoncfg 生成的,最后加载的 hyprmoncfg-monitors.lua 会覆盖前面的默认策略:

输出 分辨率 / 刷新率 位置 说明
eDP-1 2560×1600 @ 240Hz 136×0 笔记本内屏,10-bit
HDMI-A-1 2560×1440 @ 144Hz 1736×0 HKC X71Q
DP-1 2560×1600 @ 160Hz 1736×900 便携屏

三块屏统一 scale = 1.6,默认工作区也按显示器分:工作区 1 在 X71Q,工作区 7 在便携屏,工作区 10 在内屏。XWayland 开了 force_zero_scaling = true,不然老应用会糊。

Noctalia

Noctalia 是桌面壳,bar、启动器、控制中心、通知、剪贴板、锁屏、截图、壁纸都归它管。它不是桌面里最“底层”的东西,但确实是最显眼的。

bar

现在 bar 的分区:

区域 内容
左 工作区、音频可视化
中 时钟(10月25日 星期日 01:37 这种格式)
右 托盘、OBS 状态、网络、蓝牙、电池、隐私、会话

Bar 背景透明度是 0.5,控制中心和壁纸面板用的是浮动 + glass 效果。天气小组件我留着但没启用。

配色

Noctalia 的主题源设成了 wallpaper,也就是从当前壁纸里提取 Material 3 配色,再套到所有支持模板的地方。现在用的是 m3-fruit-salad 方案,壁纸目录在 ~/Pictures/Wallpapers。

它负责生成的模板包括:

  • 内置:btop、gtk3、gtk4、hyprland、kitty、qt
  • 社区:steam、obs、papirus-icons
  • 自定义:starship(用户模板)

生成出来的文件散在各处,比较关键的是这几个:

1
2
3
4
5
6
7
8
~/.config/hypr/noctalia.lua              # Hyprland 的边框色、组颜色
~/.config/gtk-3.0/noctalia.css # gtk.css 里 @import
~/.config/gtk-4.0/noctalia.css
~/.config/kitty/themes/noctalia.conf # kitty 配色
~/.config/btop/themes/noctalia.theme
~/.config/qt5ct/colors/noctalia.conf
~/.config/qt6ct/colors/noctalia.conf
~/.config/kdeglobals # ColorScheme=Noctalia

Hyprland 的颜色文件长这样:

1
2
3
4
5
local primary = "rgb(53d7f1)"
local surface = "rgb(0f131c)"
local on_surface = "rgb(dfe2ef)"
local secondary = "rgb(83d2e5)"
local error = "rgb(ffb4ab)"

kitty 的主题也是同一组颜色:

1
2
3
4
5
background #0f131c
foreground #dfe2ef
cursor #dfe2ef
active_border_color #53d7f1
inactive_border_color #3f4759

starship 模板

Noctalia 自带一套 starship 模板,但它的调色板命名和我的 powerline 配置对不上,所以我在 ~/.config/noctalia/templates.toml 里另写了一个用户模板:

1
2
3
4
5
[theme.templates.user.starship]
input_path = "$XDG_CONFIG_HOME/noctalia/templates/starship.toml"
output_path = "$XDG_CONFIG_HOME/noctalia/output/starship_palette.toml"
post_hook = "python3 '<config_dir>/scripts/merge_starship_palette.py'" # 实际是 Noctalia 模板变量,这里用 <config_dir> 表示配置目录
hook_async = false

这里有个坑:Noctalia 自带的 starship 模板必须关掉。两个模板都会改 ~/.config/starship.toml,同时开会互相覆盖;内置模板写的是扁平的 Catppuccin 命名,没有 on_* 对比色,和我的 pastel-powerline 配色对不上。自定义模板 + 一个小的 Python 合并脚本,才能只替换 [palettes.noctalia] 这一段。

生成后的 starship.toml 末尾会多出一段注释是“do not edit by hand”的调色板:

1
2
3
4
5
6
[palettes.noctalia]
primary_fixed = "#a7eeff"
tertiary_fixed_dim = "#acc7ff"
secondary_fixed_dim = "#83d2e5"
primary_fixed_dim = "#53d7f1"
surface_container_high = "#262a33"

其他

  • 壁纸引擎用的是 AUR 的 linux-wallpaperengine-git,Noctalia 里启用了 tadomika_ari/w-engine 插件;Super + Ctrl + W 打开面板,Super + Shift + W 随机换壁纸。
  • 截图目录设在 ~/Pictures/screenshot,区域截图走 Noctalia 的 screenshot-region。
  • Noctalia 的 hooks 里还接管了本地 Docker:登录时 docker compose up -d,注销 / 重启 / 关机时 docker stop。这个纯属个人习惯,不是必须。
  • 另一个插件是 ayagmar/obs-control,状态直接显示在 bar 右侧。

开机流程

现在大概是这样:

1
2
3
4
5
6
7
8
UEFI
└─ Bronya(GRUB)
├─ Arch Linux
├─ Windows Boot Manager
└─ Snapshots(grub-btrfs)
└─ SDDM(X11 greeter)
└─ Hyprland(Wayland)
└─ Noctalia + fcitx5

GRUB 的结构、bilibili 主题和快照菜单在安装篇里写过:ESP 里只放 grubx64.efi + 一个 110 字节的转发配置,真正的菜单在 btrfs 的 /boot/grub,所以改主题、加快照入口都不用碰 EFI 分区。

Shell 和终端

zsh

~/.bashrc 到现在还是 Arch 默认的那几行:alias ls='ls --color=auto'、alias grep=...、一个 PS1。日常已经 chsh -s /usr/bin/zsh,bash 只留着当急救 shell。

zsh 配置是参照 UP主 SHORiN(SHORiN_KiWATA)的配置改的,主要就几块:

  • zinit 管插件:语法高亮、补全、自动建议、fzf-tab;
  • 补全带预览,目录用 eza --tree,文件用 bat;
  • 历史 5000 条,appendhistory + sharehistory;
  • 常用 alias:ls/ll 走 eza,vim 走 nvim,lzg/lzd 是 lazygit/lazydocker;
  • 启动时 pokemon-colorscripts 随机打印一只宝可梦,然后 starship init zsh。

另外有几个 Python 虚拟环境函数(mkvenv / venv / pwnvenv),以及后面要说的 app / myenv / sysbak 这些工具。完整内容在 ~/.zshrc 里,这里就不逐行贴了。

starship 和 kitty

starship 用的是 pastel-powerline 风格,颜色全部来自 Noctalia 生成的调色板。format 里依次是 OS、用户名、目录、git、语言版本、Docker、时间,最后是提示符。Arch 的 Nerd Font 图标是单独写死的,因为 starship 新版本默认会给 Arch 配一个 emoji。

kitty 的配置很短:

1
2
3
4
5
6
include themes/noctalia.conf

font_family JetBrainsMono Nerd Font
bold_font JetBrainsMono Nerd Font Bold
italic_font JetBrainsMono Nerd Font Italic
font_size 12.0

sysup

Arch 是滚动更新,更新本身不麻烦,麻烦的是“更新前忘了看新闻、更新到一半冲突、部分升级”。sysup 是 UP主 SHORiN 的脚本,我拿来放在 ~/.local/bin 用,流程大概是:

  1. Btrfs 上先 quicksave 打一个快照;
  2. 检查 mirrorlist 的生成时间,超过 30 天就调 mirror-update 重新跑 reflector;
  3. 同步数据库、更新 archlinux-keyring 和 archlinuxcn-keyring;
  4. paru / yay -Su 交互式升级;
  5. 更新 Flatpak、玲珑、APM;
  6. 重新生成 GRUB 配置。

它还会抓 Arch 官方新闻(或者 archlinuxcn 新闻),把带 manual intervention / intervention 的条目标红。升级失败时会直接打印“禁止部分升级”的警告。配套脚本还有 checkallupdates、mirror-update、clean、battery-care、getown、timer、video2gif,都是平时顺手用的。

自己的小工具

~/.my_shell_expansion 是一套 Python 小工具,统一用 base/bin/python 跑:

命令 作用
app 统一软件管理:pacman / yay / flatpak / 玲珑 / APM 的 search、install、list、update
myenv Java / Node.js / Python 多版本管理,java use 21 这种
sysbak 基于 snapper 的系统快照备份管理
deb .deb 转成 APM 包再安装
pyvenv Python 虚拟环境管理,use / activate 会自动 eval 到当前 shell

app 的 update 默认排除 pacman 和 yay,避免绕过 sysup 直接做系统级升级。

Neovim

Neovim 用 lazy.nvim 管理,配置在 ~/.config/nvim。插件不算多,但日常够用:

  • 补全 / LSP:blink.cmp、mason + nvim-lspconfig
  • 搜索:telescope
  • 文件树:neo-tree
  • 语法:treesitter、rainbow-delimiters、colorizer
  • 界面:lualine、dashboard、render-markdown、catppuccin
  • 编辑:gitsigns、toggleterm、mini.nvim、formatting、snacks
  • 配色:base16 + matugen

matugen.lua 里写了一套 base16 颜色和 Telescope 高亮,监听 SIGUSR1,收到信号就重新加载配色。理论上可以跟着壁纸一起变,不过目前更多是手动同步。

中文和输入法

输入法

用的是 fcitx5 + Rime:

1
2
pacman -S fcitx5 fcitx5-configtool fcitx5-chinese-addons \
fcitx5-rime rime-ice-git rime-wanxiang-gram-zh-hans
  • rime-ice-git:雾凇拼音;
  • rime-wanxiang-gram-zh-hans:万象拼音的语法模型,长句输入更顺;
  • fcitx5 profile 里默认输入法是 rime,keyboard-us 作为第二项。

环境变量分两处:

文件 内容
~/.pam_environment GTK_IM_MODULE=fcitx5、QT_IM_MODULE=fcitx5、XMODIFIERS=@im=fcitx5
~/.config/hypr/conf/environment.lua QT_IM_MODULE=fcitx5、XMODIFIERS=@im=fcitx5、INPUT_METHOD=fcitx5、SDL_IM_MODULE=fcitx5(没有设 GTK_IM_MODULE)

Hyprland 的 autostart 里会拉起 fcitx5。GTK / Qt 应用如果输入法没反应,先看这两处环境变量有没有被覆盖,再看 fcitx5-diagnose。

Locale 和时间

  • 系统 /etc/locale.conf 是 LANG=en_US.UTF-8;en_US.UTF-8 和 zh_CN.UTF-8 都在 /etc/locale.gen 里生成了;
  • zsh 里把 LANG / LC_ALL 设成 zh_CN.UTF-8;Hyprland 里同样设置,并把 LC_CTYPE 保持 en_US.UTF-8;
  • 时区 Asia/Shanghai,systemd-timesyncd 负责 NTP。

字体和图标

用途 字体
中文 Noto Sans CJK SC / Noto Serif CJK(noto-fonts-cjk)
等宽 / 终端 JetBrainsMono Nerd Font
Emoji Noto Color Emoji
图标 Papirus-Dark
光标 默认 24px

Nautilus 还装了 nautilus-admin-gtk4、folder-color-nautilus、nautilus-open-any-terminal,右键里可以直接用 kitty 打开目录。

现在的状态

截至 2026-10-25,这台机器的快照:

1
2
3
4
5
6
7
8
9
10
11
OS: Arch Linux x86_64
Host: Legion Y9000P IRX9
Kernel: Linux 7.2.11-arch1-1
WM: Hyprland 0.56.2 (Wayland)
Shell: zsh 5.9.2
CPU: Intel Core i9-14900HX
GPU: NVIDIA GeForce RTX 4060 Laptop (nvidia-open 615.78.08)
Memory: 31.12 GiB
Displays: 2560x1600@240 + 2560x1440@144 + 2560x1600@160
Packages: 864 (pacman), 28 (flatpak), 5 (AppImage)
Boot: 28.5s total, 9.4s userspace
  • 系统年龄:97 天;
  • 根分区:301G / 572G(Btrfs,compress=zstd:3);
  • 最新的 timeline 快照编号:488;
  • 日常启动到桌面大概 9.4 秒 userspace,固件 + GRUB 占了大头。

踩坑总结

坑 现象 处理
登录器 greetd 没法解锁密钥环 换成 SDDM,X11 greeter + Wayland 会话没问题,配置文件只留一个 10-hyprland.conf
输入法环境 GTK / Qt 应用里切不出中文 检查 GTK_IM_MODULE / QT_IM_MODULE / XMODIFIERS,别让应用覆盖;fcitx5-diagnose 很好用
Noctalia 模板冲突 starship 配色反复被改回去 关掉内置 starship 模板,只保留自定义模板 + 合并脚本
生成文件 手改 noctalia.lua / noctalia.css 后下次换壁纸就没了 这些是 Noctalia 生成的,改模板和配置,不要直接改产物
XWayland 模糊 老应用字体发虚 xwayland.force_zero_scaling = true,配合统一的缩放系数
NVIDIA + 内核 内核升级后图形起不来 装 linux-headers,确认 dkms status,必要时重编 nvidia-open-dkms
壁纸引擎 Wallpaper Engine 资源加载失败 AUR 包 + Steam 创意工坊资源都要在,Noctalia 的 w-engine 插件只是控制端
滚动更新 更新后配置/插件行为变化 更新前看 Arch News;用 sysup 先打快照,Noctalia 是 git 包,schema 偶尔会变

配置这东西没有“完成”的那天。现在这套也不是终点:壁纸换了颜色会跟着变,Hyprland 和 Noctalia 更新了配置项也可能变。能做的就是把结构拆清楚、生成物和手写配置分开、每次大改前留个快照。

参考

安装过程见:Arch Linux 安装实录:Windows 双系统、Btrfs 与 GRUB。