Reputation: 679
My Gtk-rs program crashes if I want to run a gtk application multiple times.
use gio::prelude::*;
use gtk::prelude::*;
static APP_ID: &'static str = "com.localserver.app";
fn build_ui(app: >k::Application, fallback_message: Option<&'static str>) {
{
let window = gtk::ApplicationWindow::new(app);
window.set_title("App");
window.set_position(gtk::WindowPosition::Center);
window.set_default_size(350, 70);
window.add(>k::Label::new(Some(
fallback_message.unwrap_or("Hello world"),
)));
window
}
.show_all();
}
fn main() {
let args = std::env::args().collect::<Vec<_>>();
let application: gtk::Application =
gtk::Application::new(Some(APP_ID), Default::default()).unwrap();
application.connect_activate(|app| build_ui(&app, None));
for n in 1 .. 4 {
application.run(&args);
println!("Window loaded {} times.", n);
}
}
When ran, it goes thorough the first iteration in the for loop at the end but crashes the next time:
(dbustest_rs:9805): GLib-GIO-CRITICAL **: 19:23:51.883: g_application_parse_command_line: assertion '!application->priv->options_parsed' failed
Segmentation fault (core dumped)
What's causing this and how can I prevent it?
Upvotes: 2
Views: 564
Reputation: 19662
The issue is a simple misunderstanding in what happens and the hierarchy of objects in GTK.
GTK's object tree starts with an Application
, which you have in your case. It then has 1 or more ApplicationWindow
s, which are the "windows" themselves. From there, all your components live under that.
You've done this hierarchy properly - you create your ApplicationWindow
s under the Application
as you should. However, you then decide to run()
this application four times, and there is a check inside the library to see if the arguments were parsed before. As it is the same (recycled) application, they are, and it errors out.
Consider recreating Application
every time; it follows the natural GTK lifecycle as well.
Upvotes: 5