Search code examples
rustgtkgtk-rs

Type must satisfy the static lifetime


I'm trying to increase the structure of a Rust and GTK-RS application, but I cannot figure out how to deal with event connections. I see that the problem is in wrong lifetime, but I do not really understand how it could be fixed.

#[derive(Debug)]
struct CreatingProfileUI {
    window: gtk::MessageDialog,
    profile_name_entry: gtk::Entry,
    add_btn: gtk::Button,
    cancel_btn: gtk::Button,
}

#[derive(Debug)]
struct UI {
    window: gtk::Window,

    // Header
    url_entry: gtk::Entry,
    open_btn: gtk::Button,

    // Body
    add_profile_btn: gtk::Button,
    remove_profile_btn: gtk::Button,
    profiles_textview: gtk::TextView,

    // Creating profile
    creating_profile: CreatingProfileUI,

    // Statusbar
    statusbar: gtk::Statusbar,
}

impl UI {
    fn init(&self) {
        self.add_profile_btn
            .connect_clicked(move |_| { &self.creating_profile.window.run(); });
    }
}

And I get this error:

error[E0477]: the type `[closure@src/main.rs:109:46: 111:6 self:&UI]` does not fulfill the required lifetime
   --> src/main.rs:109:30
    |
109 |         self.add_profile_btn.connect_clicked(move |_| {
    |                              ^^^^^^^^^^^^^^^
    |
    = note: type must satisfy the static lifetime

Solution

  • You can't move non-static references into GTK callbacks. You need something static or something heap allocated (e.g. in a Box/RefCell/Rc/etc.).

    Callbacks are not called from the scope where you connect to the signal, but at some later point from the main loop. It is required that whatever you pass into the closure is still alive then, which would be anything 'static, heap-allocated or allocated on the stack between main and where the main loop runs. The last part can't currently be nicely expressed with Rust/GTK-rs.

    See the example at the bottom in the gtk-rs docs for an example. It uses an Rc<RefCell<_>>.