I coded a small programme that shows a warning dialogue when the swap file is used up above a certain threshold. I use gtk-rs to create the dialogue, which can be closed clicking a button. It took a couple of days to "understand" how to do it, thanks to an earlier thread. This is the code I ended up with:
let application = Application::new(
Some("com.github.gtk-rs.examples.basic"),
Default::default(),
).expect("failed to initialize GTK application");
application.connect_activate(|app| {
let window = ApplicationWindow::new(app);
window.set_title("Swap is getting full!");
window.set_default_size(350, 70);
let window_clone = window.clone();
let button = Button::with_label("Click to close me");
button.connect_clicked(move |_| {
println!("Clicked!");
window_clone.close();
});
window.add(&button);
window.show_all();
});
application.run(&[]);
Using the window object directly in the connect_clicked() action springs up the E0382 error. My first question is: why so? The description of this error seems unrelated, move is not even referred.
And finally, is there a more elegant way of accessing the window object inside the button action? As it stands this code is ugly and verbose.
error[E0382]: borrow of moved value: `window`
--> src/main.rs:31:9
|
22 | let window = ApplicationWindow::new(app);
| ------ move occurs because `window` has type `gtk::ApplicationWindow`, which does not implement the `Copy` trait
...
27 | button.connect_clicked(move |_| {
| -------- value moved into closure here
28 | println!("Clicked!");
29 | window.close();
| ------ variable moved due to use in closure
30 | });
31 | window.add(&button);
| ^^^^^^ value borrowed here after move
error: aborting due to previous error
For more information about this error, try `rustc --explain E0382`.
error: could not compile `swap-warn`.
To learn more, run the command again with --verbose.
As @MoAlyousef said, your problem is that the window object is captured / moved to the callback handler, so it's no longer available outside it. The move keyword for closures, AFAICT, forces the capture of the environment variables that are references as values. But this is not the case, as the window object is not a reference.
With window_clone you get a cheap Rc to the underlying window that can be kept in the handler and moved to it, without making the original window object unavailable to the outer scope.
Take a look at the glib clone macro. You'll still have some boilerplate code for every closure, and it's doing internally the same thing, but I find it nicer to work with because you're getting rid of a line of code and the clone is sent into the closure with the same name it started with.
I'm on my phone right now, but I can type up an example later if you're interested.
I'm on my second substantial project with gtk-rs. It takes a little getting used to, but once you get the hang of the little idiosyncrasies it's not too bad to work with.