桌面 Shell 元件:狀態列、啟動器與通知
完整桌面環境(GNOME、KDE)把這些元件整合在一起出貨。平鋪式 WM 的桌面是拼裝的——每個位置自己選工具:
| 功能 | 常見工具 | 配置格式 |
|---|---|---|
| 狀態列 | Waybar, Eww, AGS | JSON/JSONC, Yuck, JS |
| 啟動器 | Wofi, Rofi (wayland), Fuzzel | CSS + 設定檔 |
| 通知 | Mako, Dunst, SwayNC | INI/TOML |
| 鎖屏 | Hyprlock, Swaylock | 自定義格式 |
| 桌布 | Hyprpaper, Swww, Mpvpaper | 自定義格式 |
| 剪貼簿 | wl-clipboard + Cliphist | CLI |
| 螢幕截圖 | Grimblast, Grim + Slurp | CLI |
Caelestia 這類「desktop shell 專案」做的就是把上述元件統一設計、統一配色、統一出貨,省去自己一個個挑的功夫。它用的是 Quickshell(QML 框架)把所有元件包成一套風格一致的桌面。本模組教的是自己組裝的方式——理解各元件的配置,之後要用 Caelestia 或自己拼都能做。
Waybar:狀態列
Waybar 是 Hyprland 桌面最常用的狀態列。配置在 ~/.config/waybar/,分兩個檔案:config.jsonc(結構和模組)和 style.css(外觀)。
結構配置
1// ~/.config/waybar/config.jsonc
2{
3 "layer": "top",
4 "position": "top",
5 "height": 36,
6 "spacing": 4,
7
8 // 左中右三區塊各放哪些模組
9 "modules-left": ["hyprland/workspaces", "hyprland/window"],
10 "modules-center": ["clock"],
11 "modules-right": ["pulseaudio", "network", "cpu", "memory", "battery", "tray"],
12
13 // 各模組設定
14 "hyprland/workspaces": {
15 "format": "{id}",
16 "on-click": "activate"
17 },
18 "clock": {
19 "format": "{:%H:%M}",
20 "format-alt": "{:%Y-%m-%d %H:%M}",
21 "tooltip-format": "<tt>{calendar}</tt>"
22 },
23 "battery": {
24 "format": "{capacity}% {icon}",
25 "format-icons": ["", "", "", "", ""],
26 "states": {
27 "warning": 30,
28 "critical": 15
29 }
30 },
31 "network": {
32 "format-wifi": "{essid} ({signalStrength}%)",
33 "format-ethernet": "{ifname}",
34 "format-disconnected": "Disconnected"
35 },
36 "pulseaudio": {
37 "format": "{volume}%",
38 "on-click": "pavucontrol"
39 }
40}format 欄位裡的 icon 字元來自 Nerd Font——終端機與編輯器提到的字型安裝是這裡正常顯示的前提。
外觀 CSS
1/* ~/.config/waybar/style.css */
2
3* {
4 font-family: "MesloLGS Nerd Font", monospace;
5 font-size: 13px;
6}
7
8window#waybar {
9 background-color: rgba(30, 30, 46, 0.85);
10 color: #cdd6f4;
11}
12
13#workspaces button {
14 padding: 0 8px;
15 color: #6c7086;
16 border-radius: 6px;
17}
18
19#workspaces button.active {
20 color: #cdd6f4;
21 background: rgba(137, 180, 250, 0.2);
22}
23
24#clock, #battery, #network, #pulseaudio {
25 padding: 0 10px;
26}
27
28#battery.warning {
29 color: #f9e2af;
30}
31
32#battery.critical {
33 color: #f38ba8;
34}CSS 裡的色碼(#cdd6f4、#89b4fa、#f38ba8)來自配色方案(這個範例用的是 Catppuccin Mocha)。統一使用同一套色碼是 rice 視覺協調的基礎。
Config 裡的字族名必須跟系統實際安裝的字族逐字相符。Nerd Font 的圖示落在專屬碼位範圍,只有對應的那支字帶這些 glyph——指定一個沒裝的字族名,文字排版引擎找不到 glyph 就會顯示豆腐方塊。確認實裝字族名的方式:
1fc-list | grep -i meslo
2# MesloLGSNerdFont-Regular.ttf: "MesloLGS Nerd Font":style=Regular引號內的字串是 config 該填的字族名。
同一份 Waybar config 能同時服務筆電、桌機與 VM,靠的是模組對缺少硬體的自動退化:battery 在沒有電池的機器直接隱藏該模組、不報錯也不留空位;pulseaudio 在沒有音訊服務時顯示為空;network 顯示當下實際在用的介面。不必為不同機器維護多份 config——把可能用到的模組都列上,用不到的那台自己消失。
Wofi / Rofi:啟動器
啟動器是按快捷鍵彈出的搜尋框,用來啟動應用程式、執行指令、搜尋檔案。
Wofi(Wayland 原生)配置:
1# ~/.config/wofi/config
2show=drun
3width=600
4height=400
5prompt=Search...
6insensitive=true
7allow_markup=true 1/* ~/.config/wofi/style.css */
2window {
3 background-color: #1e1e2e;
4 border: 2px solid #89b4fa;
5 border-radius: 12px;
6}
7
8#input {
9 background-color: #313244;
10 color: #cdd6f4;
11 border-radius: 8px;
12 margin: 10px;
13 padding: 8px 12px;
14}
15
16#entry:selected {
17 background-color: rgba(137, 180, 250, 0.2);
18}Rofi(需要 wayland fork rofi-lbonn-wayland)功能更豐富——支援多種 mode(drun、window、ssh、自定義 script)、主題系統更完整。如果需要進階功能(例如 emoji picker、密碼管理器整合),Rofi 是更好的選擇。
Mako / Dunst:通知
Mako 是 Wayland 原生的通知 daemon,負責顯示通知——它監聽 D-Bus 的 org.freedesktop.Notifications 介面、把收到的通知畫出來。產生通知的是應用程式,透過 libnotify 送上 D-Bus。所以一套能用的通知鏈需要兩半:daemon(顯示)和 libnotify(產生與遞送)。缺了 libnotify,連命令列自測用的 notify-send 都沒有。套件清單要同時列 mako 和 libnotify。
配置簡潔:
1# ~/.config/mako/config
2font=MesloLGS Nerd Font 11
3background-color=#1e1e2e
4text-color=#cdd6f4
5border-color=#89b4fa
6border-radius=8
7border-size=2
8padding=12
9default-timeout=5000
10max-visible=3
11
12[urgency=critical]
13border-color=#f38ba8
14default-timeout=0通知的視覺風格(圓角、配色、字型)要跟 waybar 和啟動器一致,這是整體 rice 不散的關鍵。
Nerd Font 的字符集只含 Latin、圖示與 Powerline 符號,不含中日韓。任何 CJK 文字(通知內文、視窗標題)若系統沒有 CJK 字型可 fallback 會變豆腐方塊。修法是安裝 CJK fallback(如 noto-fonts-cjk),fontconfig 會自動補字、不需改各工具的 config。另外,中途補裝字型後已在跑的 daemon 需重啟才看得到——reload 類指令只重讀設定檔、不重建記憶體中的字型快照(原理見 字型的可用集合在 process 啟動時決定)。
Grim + Slurp:截圖
Grim 負責截圖、Slurp 負責框選區域,兩者搭配使用。截圖結果透過 wl-copy 送進剪貼簿時,需要明確指定 MIME 型別:
1# 全螢幕截圖到剪貼簿
2grim - | wl-copy --type image/png
3
4# 框選區域截圖到剪貼簿
5grim -g "$(slurp)" - | wl-copy --type image/png
6
7# 全螢幕截圖存檔
8grim ~/screenshot.pngwl-copy 不帶 --type 時會嘗試透過 xdg-utils(xdg-mime)推斷 stdin 的型別。最小安裝環境沒有 xdg-utils 的情況下,PNG bytes 會被誤標成 text/plain,貼進影像應用程式就拿不到圖。明確帶 --type image/png 讓行為不依賴環境是否安裝了 xdg-utils。確認剪貼簿內容型別:
1wl-paste --list-types
2# 應顯示 image/pngHyprland keybind 範例:
1bind = , Print, exec, grim - | wl-copy --type image/png
2bind = SHIFT, Print, exec, grim -g "$(slurp)" - | wl-copy --type image/png