如何使用 gtk4-rs 设置 X11 窗口提示?

问题描述

我正在尝试用 Rust 编写一个 GTK4 应用程序,它应该符合 Extended Window Manager Hints 规范的一部分,但为此我需要能够获取和设置 X11 提示。特别是,我想设置 _NET_WM_WINDOW_TYPE

如果我按如下方式创建一个窗口,我将如何获取/设置 X11 窗口提示

let app = Application::new(Some("id"),Default::default());
let window = applicationwindow::new(app);

解决方法

经过几天的反复试验,我得出了以下解决方案:

use gdk_x11::x11::xlib::{PropModeReplace,XChangeProperty,XInternAtom,XA_ATOM};

fn set_window_props(window: &gtk::Window,prop_name: &str,prop_values: &Vec<&str>) {
    let display = window.display();
    let surface = window.surface().unwrap();
    let prop_name_cstr = CString::new(prop_name).unwrap();
    let prop_values_cstr: Vec<CString> = prop_values
        .iter()
        .map(|val| CString::new(*val).unwrap())
        .collect();
    unsafe {
        let xid: xlib::Window = surface.unsafe_cast::<X11Surface>().xid();
        let xdisplay: *mut xlib::Display = display.unsafe_cast::<X11Display>().xdisplay();
        let prop_name_atom = XInternAtom(xdisplay,prop_name_cstr.as_ptr(),xlib::False);
        let mut prop_values_atom: Vec<u64> = prop_values_cstr
            .into_iter()
            .map(|cstr| XInternAtom(xdisplay,cstr.as_ptr(),xlib::False))
            .collect();
        let num_values = prop_values_atom.len();
        let prop_values_c = prop_values_atom.as_mut_ptr();
        XChangeProperty(
            xdisplay,xid,prop_name_atom,XA_ATOM,32,PropModeReplace,prop_values_c as *const u8,num_values as i32,);
    }
}

这会将 X11 Window 属性 XA_ATOM 的类型为 prop_name 的值替换为原子值 prop_values

对于设置 utf8 类型的属性,使用 gdk4_x11::X11Surface::set_utf8_property 更加简单和干净。