I’m not really familiar with gtk-rs but the method connect_show_menubar_notify
seems to accept a callback that is intended to be called at a later time than when the call to connect_show_menubar_notify
itself happened. Thus its type
fn connect_show_menubar_notify<F: Fn(&Self) + 'static>(
&self,
f: F
) -> SignalHandlerId
features a 'static
bound which basically outlaws the passed closure from capturing short-lived things like references. The reference type in Rust, i.e. &T
is intended for short-lived referencing and offers low/zero overhead (because it’s implemented to just use pointers), but there are restrictions coming from Rust’s memory model around ownership and borrowing. Long story short: The closure argument of connect_show_menubar_notify
is not allowed to capture values that aren’t “owned”, in particular not a reference like in your example test: &ApplicationWindow
.
Capturing refers to local variables that are mentioned in the body of a clusure, like test
appearing in
move |_| {
example(test);
}
The move
keyword indicates that the closure takes ownership of the value in the variable test
, however this way the closure still only owns a reference. In this particular example the type ApplicationWindow
itself is a smart pointer, so you can rather cheaply create a new, owned ApplicationWindow
from a reference to an existing one. This will create a setting of shared ownership not unlike usage of an Rc<T>
in Rust. More on this way of representing gtk objects can be found here:
gtk-rs.org - glib - Objects
So to fix your code example all you’d need to do is change
fn example(test: &ApplicationWindow) {
test.connect_show_menubar_notify(move |_| {
example(test);
});
}
into
fn example(test: &ApplicationWindow) {
let test_owned = test.clone();
test.connect_show_menubar_notify(move |_| {
example(&test_owned);
});
}
There’s also the alternative possibility to have example
take an owned ApplicationWindow
in the first place
fn example(test: ApplicationWindow) {
test.connect_show_menubar_notify(move |_| {
example(test);
});
}
which then means that the caller of example
may need to clone the smart pointer / object here,
e.g. example(win.clone());
instead of example(&win));
. I also suspect that there may be similar problems in your main
function in the win.connect_add
call which, as far as Google could tell me, might also require a : 'static
closure.