Files
wl-webrtc/examples/list_globals.rs

74 lines
4.2 KiB
Rust
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.
//! 列出当前 Wayland 桌面广播的全部全局对象(registry globals)。
//!
//! Wayland 协议采用"客户端发现"模型:客户端连接到 compositor 后,第一件事是从
//! registry 中枚举所有被广播的 interface(如 `wl_compositor`、`wl_shm`、
//! `zwlr_screencopy_manager_v1`、`zxdg_portal_screencast` 等),每个 global 带有
//! 唯一数字 name、interface 名字符串、最高支持版本号。本示例即打印这三元组。
//!
//! 类比 Go 的 `xcursor` / wayland-client 示例:用最小可运行代码确认运行环境。
//!
//! 运行(参见 AGENTS.md "Useful manual commands"):
//! ```sh
//! cargo run --example list_globals
//! ```
//!
//! 该示例也是 `src/backend_detect.rs` 中检测 `zwlr_screencopy_manager_v1` 是否存在的
//! 同款机制(参见 `check_screencopy_available`),用于决定走 wlr-screencopy 还是 Portal。
// 引入 wayland-client 的快捷初始化辅助函数:内部完成 connect + registry bind + 同步枚举。
use wayland_client::globals::registry_queue_init;
// GlobalListContents 是 registry_queue_init 返回的"已收集好的 global 列表"句柄类型。
use wayland_client::globals::GlobalListContents;
// WlRegistry 是 Wayland 协议对象;Event 是其产生的枚举事件(global/global_remove)。
use wayland_client::protocol::wl_registry::{Event, WlRegistry};
// Connection 表示与 compositor 的 socket 连接;QueueHandle 是事件队列句柄;
// Dispatch 是 trait,用户必须为关心的协议对象实现它以接收事件回调。
use wayland_client::{Connection, Dispatch, QueueHandle};
// 示例用的极简 state:无字段。Wayland 客户端需要至少一个 state 类型作为
// Dispatch trait 的 `Self`,这里就用零大小类型 `Ls`list globals 的缩写)。
struct Ls;
// 为 Ls 实现 WlRegistry 的 Dispatch:本示例只需枚举 globals,不需要响应任何
// registry 事件,因此 event 函数留空。wayland-client 要求即便不处理事件也必须
// 实现 Dispatchtrait contract 强制),否则 `registry_queue_init::<Ls>` 无法编译。
//
// Go 类比:类似 `type Ls struct{}` + `func (Ls) HandleEvent(...) {}`——
// 显式声明"我接收事件但不响应"。
impl Dispatch<WlRegistry, GlobalListContents> for Ls {
// 所有参数加 `_` 前缀表示本实现不读取任何参数(Rust 中 `_x` 与 `x` 区分:
// 前者显式标记未使用,避免 dead_code 警告)。
fn event(
_state: &mut Self,
_registry: &WlRegistry,
_event: Event,
_data: &GlobalListContents,
_conn: &Connection,
_qhandle: &QueueHandle<Self>,
) {
}
}
// 程序入口。Rust 的 `fn main()` 不能返回 `Result`(标准约定),故用 `.unwrap()`
// 简单 panic;示例程序通常省略错误处理以突出主线逻辑。
fn main() {
// 从 `WAYLAND_DISPLAY` / `XDG_RUNTIME_DIR` 环境变量建立与 compositor 的 socket 连接。
// 类比 Go 的 `net.Dial("unix", path)`。`.unwrap()` 在连接失败时 panic(示例代码约定)。
let conn = Connection::connect_to_env().unwrap();
// registry_queue_init 是 wayland-client 的高层辅助:内部发送 sync request 并阻塞
// 直到 registry 全部 global 事件到达。返回 (GlobalList, EventQueue)。
// `::<Ls>` 是 turbofish 显式指定 state 类型,对应上面 `impl Dispatch for Ls`。
// 类比 Go 的 `globals, queue := wayland.RegistryQueueInit[Ls](conn)`(泛型实例化)。
let (globals, _queue) = registry_queue_init::<Ls>(&conn).unwrap();
// 遍历所有已收集的 globals。`globals.contents()` 返回内部快照引用,
// `.clone_list()` 复制成 `Vec<GlobalListEntry>`(每个 entry 含 name/interface/version)。
// 类比 Go `for _, g := range globals { ... }`——Rust 的 `for ... in` 直接消费迭代器。
for g in globals.contents().clone_list() {
// `println!` 是 Rust 标准宏(不是函数),类比 Go `fmt.Printf("%d: %s v%d\n", ...)`。
// `{}` 自动调用参数的 `Display` traitname 是 u32、interface 是 String、version 是 u32。
println!("{}: {} v{}", g.name, g.interface, g.version);
}
}