如何运行嵌套的 X 服务器(通常来自 Rust/代码)来测试我的窗口管理器?

How can I run a nested X server (from Rust/code in general) to test my window manager?

提问人:Antikyth 提问时间:11/2/2023 最后编辑:Antikyth 更新时间:11/2/2023 访问量:44

问:

我正在寻找可以在从代码启动的嵌套 X 服务器中测试我的窗口管理器的方法,理想情况下。当我在 Rust 工作时,我怀疑这将是一个独立于语言的任务。

我正在 Rust 中开发一个跨平台的 Wayland 合成器和 X11 窗口管理器。使用 Smithay,一个用于创建 Wayland 合成器的 Rust 库,我可以轻松地在 winit 窗口中测试合成器,这是 Smithay 的内置功能。不过,Rust XCB 板条箱中没有这样的功能。

我试图通过生成一个 Xephyr 进程并在其显示输出上运行我的窗口管理器来做到这一点。不幸的是,似乎没有办法确定 Xephyr 何时完成启动,因此在尝试连接窗口管理器之前,我必须等待任意延迟。这显然不理想,并且可能需要不同的时间才能启动,具体取决于操作系统。

如果您有兴趣,以下是我使用的代码(对于发现此问题的任何人:如果没有更好的答案,请随时复制此解决方案):

#[cfg(any(feature = "testing", debug_assertions))]
let _process = testing.then_some({
    const TESTING_DISPLAY: &str = ":1";

    match Command::new("Xephyr").arg("-resizeable").arg(TESTING_DISPLAY).spawn() {
        Ok(process) => {
            event!(Level::DEBUG, "Initialised Xephyr");

            // Set the `DISPLAY` env variable to `TESTING_DISPLAY`.
            env::set_var("DISPLAY", TESTING_DISPLAY);

            // Sleep for 3s to wait for Xephyr to launch. Not ideal.
            thread::sleep(Duration::from_secs(3));

            testing::Xephyr(process)
        },

        Err(error) => {
            event!(Level::ERROR, "Failed to initialise Xephyr: {error}");

            return Err(error.into());
        },
    }
});

// Connect to the X server using the `DISPLAY` env variable.
let (connection, screen_num) = xcb::Connection::connect(None)?;

testing::Xephyr只是我使用的一个结构,因此当窗口管理器关闭时,我可以尝试在其 drop 函数中杀死 Xephyr 窗口。

rust 嵌套 命令 x11 xserver

评论

1赞 Colonel Thirty Two 11/2/2023
尝试使用参数。它可能会等到服务器准备就绪后,再将显示名称写入文件描述符。你需要在没有 Rust 默认添加的 CLOEXEC 标志的情况下打开文件——unix 扩展特征可能会有所帮助。--displayfd=FD
0赞 rodrigo 11/3/2023
我从本地包中查看了该工具,因此请检查它是如何做到的......令人失望的是,它确实如此(可配置)。/usr/bin/xvfb-runxorg-server-xvfbsleep 3

答: 暂无答案