I'm making a mini web browser with gtk. This code works fine, but I want to avoid all the cloning that is using.
I can't just use the web_view
object multiple times because of ownership errors on the closures.
extern crate gio;
extern crate gtk;
extern crate webkit2gtk;
use gio::prelude::*;
use gtk::prelude::*;
use gtk::{Application, ApplicationWindow, Button, Entry};
use webkit2gtk::{WebView, WebViewExt};
fn main() {
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("Web Browser");
window.set_default_size(1024, 768);
let button_back = Button::new_with_label("Back");
let button_next = Button::new_with_label("Next");
let button_reload = Button::new_with_label("Reload");
let url_entry = Entry::new();
url_entry.set_text("https://www.google.com");
let button_go = Button::new_with_label("Go");
let web_view = WebView::new();
web_view.load_uri("https://www.google.com");
let clone1: WebView = web_view.clone();
let clone2: WebView = web_view.clone();
let clone3: WebView = web_view.clone();
let clone4: WebView = web_view.clone();
button_back.connect_clicked(move |_| {
clone1.go_back();
});
button_next.connect_clicked(move |_| {
clone2.go_forward();
});
button_reload.connect_clicked(move |_| {
clone3.reload();
});
button_go.connect_clicked(move |_| {
clone4.load_uri(&url_entry.get_buffer().get_text());
});
window.show_all();
});
application.run(&[]);
}
These are my dependency versions:
[dependencies]
gtk = "0.8.1"
gio = "0.8.1"
webkit2gtk = "0.9.2"
The signature for the method connect_clicked
of the trait gtk::ButtonExt
is
fn connect_clicked<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId
No, there isn't.
'static
on the callback definition forbids it from referencing any temporary variables, and forces it to move and own any values it uses. That's deliberate, because the callback will outlive the function that creates it.
gtk's WebView
behaves like Rc
, so the clone is very cheap, and doesn't make a copy of anything. It only performs bookkeeping to help the callbacks agree which one of them will be the last to be destroyed, and therefore the one to free the underlying WebView
data.
There's a clone!
macro in glib that helps making these clones without having to name extra variables by hand.