Search code examples
rustgtk4

How do you set X11 window hints using gtk4-rs?


I am trying to write a GTK4 application in rust that should be compliant with parts of the Extended Window Manager Hints spec, but for that I need to be able to get and set X11 hints. In particular, I want to set _NET_WM_WINDOW_TYPE.

If I were to create a window as follows, how would I get/set X11 window hints?

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

Solution

  • After a few days of trial and error, I arrived to the following solution:

    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,
            );
        }
    }
    

    This will set the replace the values of type XA_ATOM of the X11 Window property prop_name with the atom values prop_values.

    For setting properties of type utf8, it is much simpler and cleaner to use gdk4_x11::X11Surface::set_utf8_property.