docs(cap_wlr): 中文注释 wlr-screencopy 协议绑定
This commit is contained in:
@@ -1,3 +1,20 @@
|
|||||||
|
//! 文件:wlr-screencopy-unstable-v1 协议客户端绑定(`CaptureSource` 实现)
|
||||||
|
//!
|
||||||
|
//! 本文件实现 `CapWlrScreencopy`,作为 `state.rs` 中 `State<S>` 的泛型参数 `S`
|
||||||
|
//! 的两个具体实现之一(另一个是 `CapPortal`)。wlr-screencopy 是 wlroots 原生
|
||||||
|
//! 协议,优先于 XDG Portal/PipeWire:无需 D-Bus、无需用户授权对话框。
|
||||||
|
//!
|
||||||
|
//! 协议绑定来源:`wayland_protocols_wlr::screencopy::v1::client::*` 由
|
||||||
|
//! wayland-scanner 工具根据 `wlr-screencopy-unstable-v1.xml` 自动生成(类似 Go
|
||||||
|
//! 用 cgo 绑定 C 库,但 Rust 通过 wayland-client crate 暴露 type-safe wrapper,
|
||||||
|
//! 无需手写 C FFI)。
|
||||||
|
//!
|
||||||
|
//! 异步模型:客户端无法主动"截屏",只能:(1) 绑定全局 manager、(2) 调用
|
||||||
|
//! `manager.capture_output()` 创建帧对象、(3) 等待内核推送 buffer/format 事件、
|
||||||
|
//! (4) 调用 `frame.copy(buffer)` 请求拷贝。因此本文件的 `alloc_frame()` 永远
|
||||||
|
//! 返回 `None`,真正的帧创建逻辑在 `state.rs` 的 Dispatch impl 中(英文注释
|
||||||
|
//! 标记为 T6b)。
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use wayland_client::globals::GlobalList;
|
use wayland_client::globals::GlobalList;
|
||||||
use wayland_client::protocol::wl_buffer::WlBuffer;
|
use wayland_client::protocol::wl_buffer::WlBuffer;
|
||||||
@@ -7,6 +24,9 @@ use wayland_protocols_wlr::screencopy::v1::client::zwlr_screencopy_frame_v1::Zwl
|
|||||||
|
|
||||||
use crate::state::{CaptureSource, OutputInfo, State};
|
use crate::state::{CaptureSource, OutputInfo, State};
|
||||||
|
|
||||||
|
// L2: `CaptureSource` trait 的具体实现——wlroots 原生 wlr-screencopy 协议后端。
|
||||||
|
// 仅持有"当前在飞"的帧对象;协议管理器 `ZwlrScreencopyManagerV1` 的绑定存放
|
||||||
|
// 在 `State` 的状态机字段中(需要 Dispatch impl,见下方英文注释)。
|
||||||
/// wlr-screencopy capture backend.
|
/// wlr-screencopy capture backend.
|
||||||
///
|
///
|
||||||
/// Holds the current in-flight frame protocol object. The
|
/// Holds the current in-flight frame protocol object. The
|
||||||
@@ -17,15 +37,27 @@ pub struct CapWlrScreencopy {
|
|||||||
/// The active frame object for the current capture cycle.
|
/// The active frame object for the current capture cycle.
|
||||||
/// Set by Dispatch impls after `manager.capture_output()`, cleared
|
/// Set by Dispatch impls after `manager.capture_output()`, cleared
|
||||||
/// by `on_done_with_frame()`.
|
/// by `on_done_with_frame()`.
|
||||||
|
// L3: `Option<T>` 类似 Go 的 `*T`(指针)——要么持有 T 的值,要么是 None(空)。
|
||||||
pub current_frame: Option<ZwlrScreencopyFrameV1>,
|
pub current_frame: Option<ZwlrScreencopyFrameV1>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// L2: 为 `CapWlrScreencopy` 实现 `CaptureSource` trait。
|
||||||
|
// Rust 的 `impl Trait for Type` 块类比 Go 的 method receiver——
|
||||||
|
// Go: `func (r *Type) Method(args)`(receiver 作为第一个参数显式声明)
|
||||||
|
// Rust: `fn method(&self, args)`(`&self` 是 `self: &Self` 的语法糖,等价 Go receiver)
|
||||||
|
// trait impl 要求方法签名与 trait 定义严格一致,编译器会校验。
|
||||||
impl CaptureSource for CapWlrScreencopy {
|
impl CaptureSource for CapWlrScreencopy {
|
||||||
/// Unit type: wlr-screencopy is fully asynchronous — `alloc_frame()`
|
/// Unit type: wlr-screencopy is fully asynchronous — `alloc_frame()`
|
||||||
/// always returns `None`. The frame object is created by Dispatch
|
/// always returns `None`. The frame object is created by Dispatch
|
||||||
/// impls calling `manager.capture_output()`, not by this method.
|
/// impls calling `manager.capture_output()`, not by this method.
|
||||||
|
// L3: `type Frame = ();` 关联类型(associated type):将"帧"的具体类型延迟到
|
||||||
|
// impl 处决定。wlr-screencopy 用 unit `()` 因为帧对象生命周期由 Dispatch 控制。
|
||||||
type Frame = ();
|
type Frame = ();
|
||||||
|
|
||||||
|
// L3: 构造函数。`Self` 在 impl 块内是 `CapWlrScreencopy` 的类型别名。
|
||||||
|
// 参数名以 `_` 前缀表示"有意未使用"——manager 绑定不在此处发生,故这些
|
||||||
|
// 参数(GlobalList/WlOutput/OutputInfo/QueueHandle)暂未消费。返回
|
||||||
|
// `Result<Self>`,失败由调用方用 `?` 操作符传播(类比 Go 的 `if err != nil`)。
|
||||||
fn new(
|
fn new(
|
||||||
_gm: &GlobalList,
|
_gm: &GlobalList,
|
||||||
_output: &WlOutput,
|
_output: &WlOutput,
|
||||||
@@ -35,11 +67,15 @@ impl CaptureSource for CapWlrScreencopy {
|
|||||||
// Manager binding happens in state.rs during the ProbingOutputs →
|
// Manager binding happens in state.rs during the ProbingOutputs →
|
||||||
// EverythingButFmt stage transition (T6b). It requires a Dispatch
|
// EverythingButFmt stage transition (T6b). It requires a Dispatch
|
||||||
// impl that doesn't exist yet, so we cannot call gm.bind() here.
|
// impl that doesn't exist yet, so we cannot call gm.bind() here.
|
||||||
|
// `Ok(...)` 是 `Result::Ok(...)` 的简写,将成功值包装为 Result 返回;
|
||||||
|
// `Self { ... }` 等价于 `CapWlrScreencopy { ... }`,impl 块内可用。
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
current_frame: None,
|
current_frame: None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// L3: 分配帧对象。返回 `Option<Self::Frame>`(此处 Frame = (),故永远返回 None)。
|
||||||
|
// `&mut self` 是 `self: &mut Self` 的简写(类比 Go 指针 receiver `*Type`)。
|
||||||
fn alloc_frame(&mut self) -> Option<Self::Frame> {
|
fn alloc_frame(&mut self) -> Option<Self::Frame> {
|
||||||
// wlr-screencopy is asynchronous: the Dispatch impl creates a new
|
// wlr-screencopy is asynchronous: the Dispatch impl creates a new
|
||||||
// ZwlrScreencopyFrameV1 which triggers the buffer allocation flow
|
// ZwlrScreencopyFrameV1 which triggers the buffer allocation flow
|
||||||
@@ -48,16 +84,23 @@ impl CaptureSource for CapWlrScreencopy {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// L3: 提交拷贝请求:将已分配的 DMA-BUF(WlBuffer)关联到当前帧对象。
|
||||||
fn queue_copy(&mut self, buffer: &WlBuffer, _qh: &QueueHandle<State<Self>>) {
|
fn queue_copy(&mut self, buffer: &WlBuffer, _qh: &QueueHandle<State<Self>>) {
|
||||||
|
// `if let Some(x) = &expr`:pattern matching,当 expr 是 Some 时绑定内部值。
|
||||||
|
// 此处 `&self.current_frame` 不可变借用,调用 `frame.copy(buffer)` 提交拷贝。
|
||||||
if let Some(frame) = &self.current_frame {
|
if let Some(frame) = &self.current_frame {
|
||||||
frame.copy(buffer);
|
frame.copy(buffer);
|
||||||
} else {
|
} else {
|
||||||
|
// `tracing::warn!` 是结构化日志宏(类比 Go log.Printf,但支持字段)。
|
||||||
tracing::warn!("queue_copy: no current wlr-screencopy frame");
|
tracing::warn!("queue_copy: no current wlr-screencopy frame");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// L3: 帧处理完成后的清理。`_frame: Self::Frame` 前缀 `_` 表示参数未使用(Frame 是 unit)。
|
||||||
fn on_done_with_frame(&mut self, _frame: Self::Frame) {
|
fn on_done_with_frame(&mut self, _frame: Self::Frame) {
|
||||||
|
// `Option::take()`:取出 Some 并将原位置替换为 None,原值所有权转移给返回值。
|
||||||
if let Some(frame) = self.current_frame.take() {
|
if let Some(frame) = self.current_frame.take() {
|
||||||
|
// `frame.destroy()` 发送 wayland 析构请求,释放服务端协议对象资源。
|
||||||
frame.destroy();
|
frame.destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user