本页目录

Hyprland Waybar 配置与主题

这套 Waybar 是 Hyprland 桌面的备用状态栏⁠。当前主桌面使用 Quickshell,Waybar 的 systemd 服务保持 disabled/inactive,但配置仍能独立启动,适合在调试 Quickshell、恢复桌面或需要轻量状态栏时使用。

本文基于本机实际配置,重点不是堆一份巨大 JSON,而是解释怎样把 Waybar 拆成可维护的模块、样式和交互脚本。

1. 文件结构

~/.config/waybar/
├── config                 # 主布局,只决定模块顺序与全局行为
├── style.css              # CSS 入口
├── theme.css              # 当前静态配色(Catppuccin Mocha)
├── styles/
│   ├── fonts.css
│   ├── modules-left.css
│   ├── modules-center.css
│   ├── modules-right.css
│   └── states.css
├── modules/
│   ├── hyprland/*.jsonc   # workspace、窗口、输入法
│   ├── custom/*.jsonc     # 用户、分隔符、电源
│   └── *.jsonc            # CPU、内存、网络、蓝牙、音量等
└── scripts/               # 点击、滚轮和弹窗控制脚本

主配置通过 include 引入模块片段:

{
  "include": [
    "~/.config/waybar/modules/*.jsonc",
    "~/.config/waybar/modules/custom/*.jsonc",
    "~/.config/waybar/modules/hyprland/*.jsonc"
  ]
}

这样新增模块时只需要增加一个 JSONC 文件;主配置不会逐渐膨胀成难以维护的单文件。

2. 三段式布局

实际布局分成 left、center、right 三组:

"modules-left": [
  "custom/user",
  "hyprland/workspaces",
  "hyprland/window"
],
"modules-center": [
  "hyprland/language",
  "temperature",
  "memory",
  "cpu",
  "idle_inhibitor",
  "clock#time",
  "clock#date",
  "network",
  "bluetooth"
],
"modules-right": [
  "mpris",
  "group/pulseaudio",
  "battery",
  "custom/power"
]

真实配置还在模块之间加入左右斜角分隔符。它们只是 presentation module,不承担状态逻辑;删掉分隔符后,业务模块仍能正常工作。

全局选项中值得保留的是:

"layer": "top",
"mode": "dock",
"spacing": 0,
"reload_style_on_change": true

reload_style_on_change 会在 CSS 文件变化时重新载入样式,调主题时不必反复重启 Waybar。

3. Hyprland Workspaces

workspace 模块固定保留 5 个工作区,并允许滚轮切换:

{
  "hyprland/workspaces": {
    "format": "{icon}",
    "format-icons": {
      "active": "",
      "default": ""
    },
    "persistent-workspaces": {
      "*": 5
    },
    "on-scroll-up": "hyprctl dispatch workspace +1",
    "on-scroll-down": "hyprctl dispatch workspace -1",
    "cursor": true
  }
}

这里依赖 Nerd Font 图标。如果 Waybar 显示方框,先检查字体,而不是修改 JSON。

4. 音量:drawer + 点击/滚轮脚本

输出和输入音量放在一个横向 drawer 中:

"group/pulseaudio": {
  "orientation": "horizontal",
  "modules": [
    "pulseaudio#output",
    "pulseaudio#input"
  ],
  "drawer": {
    "transition-left-to-right": false
  }
}

输出模块把三类操作分开:

"on-click": "~/.config/waybar/scripts/volume output mute",
"on-scroll-up": "~/.config/waybar/scripts/volume output raise",
"on-scroll-down": "~/.config/waybar/scripts/volume output lower"

输入模块复用同一个脚本,只把对象改为 input。这种接口比在 JSON 中复制 wpctl/pactl 命令更容易测试,也能统一处理步长、默认设备和错误提示。

5. 网络与控制面板

网络模块保持图标紧凑,把详细信息放进 tooltip:

{
  "network": {
    "interval": 10,
    "format-ethernet": "󰈀",
    "format-wifi": "{icon}",
    "format-disconnected": "󰤯",
    "on-click": "ghostty -e ~/.config/waybar/scripts/network",
    "on-click-right": "~/.config/waybar/scripts/network off",
    "tooltip-format-wifi": "<b>Network</b>: {essid}\n<b>IP</b>: {ipaddr}/{cidr}\n<b>Strength</b>: {signalStrength}%"
  }
}

音量和蓝牙按钮通过统一的 panel_toggle.sh 打开 GTK 面板。脚本遵守三条规则:

  1. 再次点击同一个按钮会关闭面板。
  2. 打开另一个面板前先关闭当前面板,避免多个控制中心重叠。
  3. panel_watch.sh 观察 Hyprland active window,焦点离开面板后自动关闭。

判断面板是否存在时应查询 hyprctl clients -j 的窗口 class,而不是只用 pgrep。Blueman 之类的程序可能由 Python 启动,进程名并不能可靠代表用户实际看到的窗口。

6. CSS 分层

style.css 只负责组合:

@import "theme.css";

* {
  all: initial;
  color: @main-fg;
}

@import "styles/fonts.css";
@import "styles/modules-center.css";
@import "styles/modules-left.css";
@import "styles/modules-right.css";
@import "styles/states.css";

当前 theme.css 是静态 Catppuccin Mocha,先定义基础色,再映射成语义色:

@define-color lavender #b4befe;
@define-color text     #cdd6f4;
@define-color crust    #11111b;

@define-color accent   @lavender;
@define-color main-bg  @crust;
@define-color main-fg  @text;
@define-color warning  @yellow;
@define-color critical @red;

业务样式只引用 @main-bg@accent@critical 等语义色,不直接写十几处十六进制值。换主题时只替换 theme.css

7. 可选:让 Matugen 生成 Waybar 主题

当前本机的 Matugen 管理 Quickshell、Hyprland、Hyprlock、Fuzzel、Fcitx5、GTK、Ghostty、KDE 和 Zellij,⁠尚未生成 Waybar 的 theme.css。若希望 Waybar 跟随壁纸,可以新增模板:

[templates.waybar]
input_path = '~/.config/matugen/templates/waybar/theme.css'
output_path = '~/.config/waybar/theme.css'
post_hook = 'pkill -SIGUSR2 waybar 2>/dev/null || true'

模板只输出语义色,保持现有模块 CSS 不变:

@define-color accent  #{{colors.primary.default.hex}};
@define-color main-bg #{{colors.surface.default.hex}};
@define-color main-fg #{{colors.on_surface.default.hex}};
@define-color main-br #{{colors.outline.default.hex}};
@define-color warning #{{colors.tertiary.default.hex}};
@define-color critical #{{colors.error.default.hex}};

Matugen 的模板变量语法会随版本变化;接入前应先用当前安装版本渲染到临时文件,确认没有空变量,再覆盖正式 theme.css

8. systemd 启动与回退

Waybar 的用户服务:

[Unit]
Description=Highly customizable Wayland bar for Hyprland
PartOf=graphical-session.target
After=graphical-session.target
ConditionEnvironment=WAYLAND_DISPLAY

[Service]
ExecStart=/usr/bin/waybar
ExecReload=kill -SIGUSR2 $MAINPID
Restart=on-failure

[Install]
WantedBy=hyprland-session.target

手动试运行:

waybar -l info

切换成默认状态栏:

systemctl --user enable --now waybar.service

恢复为备用状态:

systemctl --user disable --now waybar.service

在启用 Waybar 前先停掉占用同一屏幕边缘的其他 bar,避免 exclusive zone、点击区域或层级互相覆盖。

9. 排错顺序

  1. waybar -l trace:先看 JSONC、模块和 CSS 解析错误。
  2. hyprctl clients -j:确认点击脚本依赖的窗口 class。
  3. fc-match:检查 Nerd Font 与图标字体。
  4. 单独运行 scripts/ 下的命令,区分 Waybar 问题和脚本问题。
  5. 临时移除 @import,逐层定位 CSS 解析失败。
  6. 使用 systemctl --user status waybar.service 和 journal 检查会话环境。

这套结构的核心是把布局、模块行为、交互脚本和颜色主题分开⁠。Waybar 可以保持轻量备用,也可以独立演进;是否接入 Matugen只是主题来源选择,不应影响模块本身。