Eww 安装、构建与运行完全指南:用 Rust 搭建与窗口管理器无关的 Widget 系统
【免费下载链接】ewwElKowars wacky widgets项目地址: https://gitcode.com/gh_mirrors/ew/eww
导读:本文是一份围绕 Eww(ElKowar's Wacky Widgets)的实战入门指南,覆盖从环境准备、源码构建、daemon 启动到首次打开窗口的完整流程。Eww 是一个用 Rust 编写的独立 widget 系统,配置语言为 yuck、样式使用 CSS/SCSS,且与窗口管理器无关——无论你使用 i3、bspwm 还是 Wayland 合成器,都能获得一致的自定义桌面组件能力。读完本文,你将能够从零构建 Eww 二进制、理解 X11/Wayland 后端的编译差异,并熟练使用
daemon、open等核心命令搭建自己的第一个桌面小组件。
Eww 是什么:一句话理解它的设计定位
Eww(ElKowar's Wacky Widgets,官方读法带着足够的嫌弃感)是一个用 Rust 实现的 widget 系统,让你可以像在 AwesomeWM 中那样自由地创建属于自己的小组件,而其关键差异在于:它独立于你的窗口管理器。
- 配置使用名为yuck的 S-expression 语言(类似 Lisp 语法);
- 主题样式使用CSS/SCSS(底层由 GTK 的 CSS 引擎解析,而非浏览器引擎);
- 因为是独立进程,它可以同时服务于 X11 与 Wayland 会话,也能轻松配合任何 WM 的快捷键或脚本进行交互。
安装前置条件
Rust 工具链
安装 Eww 需要rustc与cargo。官方文档强烈建议使用 rustup 安装 Rust 工具链,而不是依赖系统包管理器提供的版本——这不仅保证版本足够新,也能避免发行版 Rust 包与 Eww 依赖的 crate 版本要求不匹配。
系统动态库
Eww 还依赖若干系统动态库,各发行版中提供这些库的包名可能不同。以下是适用于Arch Linux的包名清单:
| 包名 | 提供的动态库 |
|---|---|
gtk3 | libgdk-3、libgtk-3 |
gtk-layer-shell | 仅 Wayland 需要 |
pango | libpango |
gdk-pixbuf2 | libgdk_pixbuf-2 |
libdbusmenu-gtk3 | libdbusmenu-gtk3 |
cairo | libcairo、libcairo-gobject |
glib2 | libgio、libglib-2、libgobject-2 |
gcc-libs | libgcc |
glibc | glibc |
注意:要成功编译 Eww,你通常还需要各发行版对应的-devel 变体(开发头文件包),例如 Debian/Ubuntu 系中的
*-dev、Fedora 系中的*-devel。
这些依赖在源码中同样可以得到印证:查看 crates/eww/Cargo.toml 可以发现,Eww 的编译特性与系统库一一对应——x11特性开启gdkx11与x11rb(后者启用randr特性用于多显示器支持),wayland特性则引入gtk-layer-shell,这是 Wayland 下层窗口(layer shell)协议的关键绑定。
构建 Eww:区分 X11 与 Wayland 特性
准备好前置条件后,即可克隆并构建:
git clone https://gitcode.com/gh_mirrors/ew/eww cd eww在 X11 下构建
cargo build --release --no-default-features --features x11在 Wayland 下构建
cargo build --release --no-default-features --features=wayland注意:文档明确要求使用--no-default-features手动指定后端,因为默认特性同时包含 X11 与 Wayland 两个后端。查看 crates/eww/Cargo.toml 可以确认这一点:
[features] default = ["x11", "wayland"] x11 = ["gdkx11", "x11rb"] wayland = ["gtk-layer-shell"]只在目标平台启用对应特性,可以避免为不需要的后端拉取额外的编译依赖。
运行时后端如何被选择
即便同时编译了两个后端,Eww 在运行时也会自动选择。在 main.rs 中可以看到具体逻辑:它读取XDG_SESSION_TYPE与WAYLAND_DISPLAY环境变量判断当前会话类型,若检测到 Wayland 则优先使用WaylandBackend,否则回退到X11Backend。若编译时仅包含 X11 特性而系统实际运行在 Wayland,Eww 会打印警告并回退到 X11 模式(见 main.rs 的编译分支)。此外还提供了--force-wayland全局参数,用于在自动检测失败时强制指定后端。
运行 Eww:daemon 与 open
构建完成后,进入产物目录并赋予执行权限:
cd target/release chmod +x ./ewwEww 采用常驻 daemon + 命令行客户端的架构,最基本的启动流程只有两条命令:
./eww daemon ./eww open <window_name>eww daemon启动后台守护进程,负责加载配置、监听 IPC 请求并渲染所有窗口;eww open <window_name>打开配置中定义的指定名称窗口。
值得一提的是,eww open这类需要服务端配合的命令在检测到 daemon 尚未运行时,会自动尝试拉起一个 daemon 后再执行(这一行为在 main.rs 的run函数中有完整实现),所以日常使用中即使先执行eww open也能正常工作。
常用命令速查:一个 daemon、一套完整控制面
Eww 的 CLI 基于 clap 定义,所有子命令都集中在 opts.rs。除了daemon与open,以下命令在实战中同样高频:
| 命令(别名) | 作用 |
|---|---|
eww open-many "win1:instance1" "win2" | 一次打开多个窗口,可携带实例 id |
eww close <window...>/eww close-all | 关闭指定窗口 / 关闭全部窗口(不杀 daemon) |
eww update var="value" | 更新运行中实例的变量值(如eww update volume=50) |
eww poll <var...> | 强制触发某个轮询变量立即按脚本刷新 |
eww reload | 重新加载 yuck 配置与 CSS,修改配置后无需重启 daemon |
eww kill | 关闭 Eww daemon |
eww state [-a] | 打印当前变量状态,-a包含未被窗口使用的变量 |
eww get <var> | 获取单个变量的值 |
eww logs | 打印并持续跟踪 eww 日志,排查配置错误的首选 |
eww list-windows/eww active-windows | 列出已定义窗口 / 当前打开的窗口实例 |
eww ping | 探测 daemon 是否可达(返回pong) |
eww inspector(别名debugger) | 打开 GTK 调试器,检查窗口内 widget 树 |
eww debug | 打印 eww 眼中的 widget 结构,提交 bug 时很有用 |
eww graph | 以 graphviz dot 格式输出作用域图(scope graph)结构 |
eww shell-completions --shell <shell> | 生成 shell 补全脚本 |
open子命令还支持丰富的参数:--id(窗口实例 id)、--screen(目标显示器)、--pos/--size(位置与尺寸,格式如200x100)、--anchor(锚点,如"top right")、--toggle(已开则关)、--duration(自动关闭倒计时,如1s)、--arg "var=value"(为窗口实例注入变量)——这些都可以在 opts.rs 中逐一查到。
全局参数
以下参数对所有子命令生效(定义见 opts.rs):
| 参数 | 作用 |
|---|---|
--debug | 输出调试日志(配合eww logs查看) |
--force-wayland | 强制使用 Wayland 后端(未编译 Wayland 时无效果) |
-c, --config <dir> | 覆盖配置目录路径(该目录需包含eww.yuck与eww.(s)css) |
--logs | 执行命令后持续跟踪日志输出 |
--no-daemonize | 禁止 daemon 后台化(前台运行,便于调试) |
--restart | 在执行命令前完整重启 daemon |
配置文件放哪里:路径约定与 daemon 内部结构
Eww 的默认配置目录遵循 XDG 规范。根据 paths.rs 的实现,配置目录为$XDG_CONFIG_HOME/eww(未设置时回退为~/.config/eww),启动时 Eww 会在其中寻找eww.yuck(窗口与 widget 定义)以及eww.scss或eww.css(样式)。
此外,从 paths.rs 可以看到几个对排障有帮助的实现细节:
- IPC socket:daemon 与命令行客户端通过 Unix socket 通信,socket 文件放在
$XDG_RUNTIME_DIR(回退/tmp)下,文件名由配置目录路径哈希生成(eww-server_<hash>),既避免多实例冲突,也规避了 Unix socket 108 字节路径长度限制; - 日志文件:日志写入
$XDG_CACHE_HOME/eww/eww_<hash>.log,也就是eww logs所跟踪的文件; - 哈希隔离:每个配置目录对应独立 daemon,因此可以为不同配置分别启动实例。
从一个真实示例看配置文件长什么样
仓库的 examples/eww-bar 目录提供了一个可直接参考的顶栏示例,包含eww.yuck与eww.scss两个文件,正好对应上文图片中的效果。其核心结构展示了 yuck 的四个顶层关键字:
(defwidget bar [] (centerbox :orientation "h" ...)) ; 自定义 widget,可被复用 (defwindow bar ; 窗口定义:几何、锚点、dock 类型 :monitor 0 :windowtype "dock" :geometry (geometry :x "0%" :y "0%" :width "90%" :height "10px" :anchor "top center") :reserve (struts :side "top" :distance "4%") (bar)) (deflisten music :initial "" ; 由脚本持续推送的变量 "playerctl --follow metadata ...") (defpoll volume :interval "1s" ; 按固定间隔轮询的变量 "scripts/getvol")defwidget定义可复用的 widget 结构(此例中的bar、metric等);defwindow声明窗口及其几何、堆叠、strut 等属性;deflisten/defpoll定义动态数据源,前者由脚本持续推送(如播放器曲目),后者按时间间隔轮询(如音量、时间)。
对应的 eww.scss 则用普通 CSS 语法为.bar、.workspaces、.metric等 class 设置颜色、圆角与内边距。样式引擎由 GTK 提供,因此可以放心使用大部分 CSS 选择器与属性,但需要注意:动画特性以及 flexbox、float、绝对定位、width/height等布局属性不被支持。
常见问题与排障入口
- 改了配置不生效:先
eww reload(重新解析 yuck 与 CSS),再eww open <window>重开窗口; - 窗口没出现或行为异常:运行
eww logs跟踪实时日志,配置解析错误会以带源码定位的诊断信息输出;必要时用eww inspector打开 GTK 调试器检查 widget 树,或用eww debug查看 eww 实际解析出的结构; - 后端选择错误:Wayland 会话下窗口无法定位或悬浮异常,先确认构建时启用了
wayland特性,并可用--force-wayland显式指定; - daemon 状态异常:
eww ping探测连通性,eww kill后重新eww daemon,或直接用--restart一条命令完成"杀进程 + 重启 + 执行"。
至此,你已经完成了 Eww 从源码构建到首次开窗的完整闭环。下一步可以继续阅读仓库中的 配置指南(窗口属性、monitor 匹配、geometry 详解)、表达式语言(yuck 内嵌的动态表达式)与 Widget 文档(内置组件清单),把顶栏示例逐步扩展成属于你自己的桌面组件。
【免费下载链接】ewwElKowars wacky widgets项目地址: https://gitcode.com/gh_mirrors/ew/eww
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考