#wayland #clipboard #listen #copy #paste #wlr-data-control-unstable-v1

wayland-clipboard-listener

实现 wlr-data-control-unstable-v1,监听剪贴板

10 个版本

0.2.5 2023 年 6 月 20 日
0.2.4 2023 年 6 月 18 日
0.1.3 2023 年 6 月 16 日

GUI 中排名第 936

Download history 33/week @ 2024-03-31 247/week @ 2024-04-21 10/week @ 2024-04-28

每月下载量 56

GPL-3.0 许可证

30KB
411

wayland-clipboard-listener

我本来想用 animate girl 来命名这个 crate,但它不能很好地展示这个 crate 的功能

它实现了 wlr-data-control-unstable-v1,你可以在 wlr-data-control-unstable-v1 下查看协议

你可以在 sway 或 kde 上使用它

这是 GPL-v3,如果你使用这段代码,你需要提供你的代码,你不应该用这段代码去监听人们的剪贴板并将其上传到你的公司或政府,你必须开源你的代码。

一般介绍

实现 wlr-data-control-unstable-v1,在 sway,hyperland 或 kde 上处理剪贴板。你可以在 wlr-data-control-unstable-v1 中查看协议

此协议涉及以下注册:WlSeat、ZwlrDataControlManagerV1、ZwlrDataControlDeviceV1 和 zwlrDataControlOfferV1,seat 用于创建设备,并将处理复制和粘贴

当你想使用此协议时,你需要先初始化这些,然后进入事件循环,你可以在我们的代码中查看,部分如下:

init()

粘贴

复制主要在设备调度和数据提供部分,完成复制事件有两个路径,这取决于你发送 ZwlrDataControlDeviceV1 的接收请求的时间;

路径 1

    1. 首先,事件进入 zwlrDataControlOfferV1 的 DataOffer 事件,它将发送一个 zwlrDataControlOfferV1 对象,这将包含剪贴板的数据消息,如果你在这个时间发送,你将不知道 mime 类型。在这个时间,数据包括所选文本和复制的文本,这里你可以传递一个文件描述来接收,和 TEXT 的 mime 类型,因为在这个时间你不知道数据的任何 mime 类型
    1. 它将进入 zwlrDataControlOfferV1 的事件,在那里 mime 类型被发送,但在发送之前,你忽略 mime 类型
    1. 它进入选择,遵循协议文档,你需要销毁提供,如果有的话;
    1. 主循环结束,然后你需要运行往返,再次,为了管道完成,然后你将收到文本。注意,在这个例程中,你需要在最后检查 mime 类型,因为管道中的数据可能不是文本

路径 2

与路径 1 类似,但在接收选择事件时发送接收请求,这次你将接收到 mime 类型。这里你只能接收到通过复制操作的数据

复制

使用wlr-data-control-unstable-v1粘贴时,需要数据提供者处于活动状态,您可以进行一个实验,如果您从Firefox复制一段文本然后关闭Firefox,您会发现,您无法粘贴!这很神奇,不是吗?因此,如果数据仍然可用,复制事件需要保持活动状态。您会发现,如果您使用wl-copy复制文本,它将在htop中始终处于活动状态,如果您查看代码,您会发现它自己分叉并存在于后端,直到您从其他地方复制另一段文本,它才会结束。

那么问题是,如何复制数据,何时结束进程?

复制事件涉及ZwlrDataControlDeviceV1和ZwlrDataControlSourceV1。

    1. 如果您想发送数据,您需要创建一个新的ZwlrDataControlSourceV1,使用zwlr_data_control_manager_v1的create_data_source函数创建一个新的,并将其mimetype设置给它,使用offer请求。您可以设置多次,
    1. 启动一个永无止境的阻塞分发循环,但这并不是永无止境的循环,它应该在接收到ZwlrDataControlSourceV1的取消事件时停止,这意味着其他数据正在复制,进程不再需要
    • 2.1 在阻塞分发开始时,您将接收到一些发送信号,包括mimetype和文件描述符,将数据写入fd,然后复制将完成,数据将进入剪贴板
    • 2.2 当接收到取消时,退出进程

创建剪贴板监听器的一个简单示例如下

use wayland_clipboard_listener::WlClipboardPasteStream;
use wayland_clipboard_listener::WlListenType;

fn main() {
    let mut stream = WlClipboardPasteStream::init(WlListenType::ListenOnCopy).unwrap();
    for context in stream.paste_stream().flatten().flatten() {
        println!("{context:?}");
    }
}

创建wl-copy的一个简单示例如下

use wayland_clipboard_listener::{WlClipboardCopyStream, WlClipboardListenerError};
fn main() -> Result<(), WlClipboardListenerError> {
    let args = std::env::args();
    if args.len() != 2 {
        println!("You need to pass a string to it");
        return Ok(());
    }
    let context: &str = &args.last().unwrap();
    let mut stream = WlClipboardCopyStream::init()?;
    stream.copy_to_clipboard(context.as_bytes().to_vec())?;
    Ok(())
}

感谢wl-clipboard-rs和smithay。

您可以查看以下仓库

依赖关系

~5–13MB
~149K SLoC