[gtk-rs] How to apply can-join-all-spaces behavior in macOS to the gdk window?

Hi all :wave:

I’ve developed a gtk-3 / gtk-rs application called Zoha, and I’m trying to port it to macOS. The selling point of this app is that with a click of a button, a drop-down terminal appears, just like Tilda, no matter which space the user is in right now (space in macOS == desktops in GNOME).

To do that I use the gdk_quartz_window_get_nswindow(&GdkWindow) call to get the native window implementation and apply NSWindowCollectionBehaviorMoveToActiveSpace behavior on it. This behavior works in a plain objective-c macOS application, but in GTK application it has no effect.

Does anybody experienced with macOS know what I’m doing wrong?

I also tried my luck with chatGPT and it says I have to set the behaivor early on the window, before it is painted on the screen. The problem is until I call application_window.show_all(), there’s no GdkWindow assigned to the ApplicationWindow instance.

Here is my Rust code:

#[cfg(target_os = "macos")]
pub fn macos_hack(window: &gdk::Window) {
    unsafe {
        let win = gdk_quartz_window_get_nswindow(window.to_glib_none().0) as id;

        eprintln!("WIN ID: {:?}", win);

        // Neither of these masks work. *I know* they are set on the native window instance,
        // since if I sent an invalid mask according to apple docs, say 1 | 1<<6 | 1<<8, it prints
        // the corresponding error: invalid mask for window and panics.

        // let mask: u32 = 1 << 0; // NSWindowCollectionBehaviorCanJoinAllSpaces
        let mask: u32 = 1 << 1; // NSWindowCollectionBehaviorMoveToActiveSpace

        let _: () = msg_send![win, setCollectionBehavior:mask];

        // Blind shot, trying to see if it would make any difference. It didn't.
        // let mask: u32 = 1 << 1;
        // let mask: u32 = 1 << 1 | 1 << 3;
        // eprintln!("STYLE MASK: {}", mask);
        // let _: () = msg_send![win, setStyleMask:mask];

        if mask > 0 {
            let _: () = msg_send![win, orderFrontRegardless];
        }
    };
}

#[cfg(target_os = "macos")]
extern "C" {
    fn gdk_quartz_window_get_nswindow(window: *mut GdkWindow) -> *mut c_void;
}

Connect to the “realized” signal on the window, and call the Quartz API there.

2 Likes

Thanks for the help!

But unfortunately it didn’t make any difference. Any other ideas?

I tried to modify GTK directly here: gdkmacostoplevelsurface.c#L663, and linked against my custom GTK build. Anything else I do to the NSWindow takes effect (such as a [setTitle NSString(...)] call); but NSWindowCollectionBehaviorCanJoinAllSpaces does not!

This is not a gtk-rs issue anymore I’d say.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.