pentamassiv / gtk4-layer-shell-gir

Unsafe bindings and a safe wrapper for gtk4-layer-shell, automatically generated from a .gir file
MIT License
23 stars 2 forks source link

ApplicationWindow.destroy() segfault with layer shell only #21

Closed mytdragon closed 10 months ago

mytdragon commented 1 year ago

Bug description

Segfault only occurs after using init_layer_shell() to setup a window. Using gtk::ApplicationWindow.destroy() (or close() then cause a segfault. I've included a minimal repro to create a window with a button to open a window, initialize it with layer shell, and then destroying it on "esc" event that will trigger the segfault.

If the layer shell part on build_window_2 is commented, the win.destroy won't cause a segfault.

Reproducible code

(Note that I'm a beginner in both rust and gtk, after asking for assistant on the rust server, some people told me that it shouldn't have trigger a segfault and that it might be useful to fill on issue.)

use gtk::{
    glib, gdk, prelude::*,
    Application, ApplicationWindow, EventControllerKey,
    Button, Label
};
use gtk4_layer_shell::{KeyboardMode, Layer, LayerShell};

fn main() {
    let application = Application::builder().application_id("lets.cause.a.segfault").build();
    application.connect_activate(build_window_1);

    application.run();
}

fn build_window_1(application: &Application) {
    let window = ApplicationWindow::new(application);

    let button = Button::builder()
        .label("Show window 2")
        .build();

    let app = application.clone();
    button.connect_clicked(move |_| {
        build_window_2(&app);
    });
    window.set_child(Some(&button));
    window.present();
}

fn build_window_2(application: &Application) {
    let window = ApplicationWindow::new(application);

    window.init_layer_shell();
    window.set_layer(Layer::Top);
    window.set_keyboard_mode(KeyboardMode::Exclusive);

    let event_controller_key = EventControllerKey::builder().build();
    let win = window.clone();
    event_controller_key.connect_key_pressed(move |_event, key, _hardware_keycode, _state| {
        if key == gdk::Key::Escape {
            win.destroy();
        }

        return glib::signal::Propagation::Proceed;
    });
    window.add_controller(event_controller_key);

    let label = Label::builder().label("Window 2").build();
    window.set_child(Some(&label));
    window.present();
}

EDIT 1: I ported this example to gtk3 and gtk-layer-shell, it doesn't trigger a segfault. It only occurs with gtk4 and gtk4-layer-shell

pentamassiv commented 10 months ago

Sorry for taking such a long time to reply. I don't think this is an issue with the Rust crate, but with the underlying C library. There is an issue that seems relevant to your issue already: https://github.com/wmww/gtk4-layer-shell/issues/24 Have you tried using the most recent version of gtk4-layer-shell (the C library)? If you continue to have issues, please open an issue in their repo: https://github.com/wmww/gtk4-layer-shell

mytdragon commented 10 months ago

Hi @pentamassiv, it seems it was fixed with the last version of gtk4-layer-shell. So yeah it seems to be on the underlying C library, my bad sorry.