I'm trying to use GTK's argv-handling, but there seem to be some issues with the main loop.
My goal is to parse the command line after GTK removed its options (like --display
), but before opening a window, because I want my app to be usable with a CLI-only interface, too, with both variants making use of Glib etc. This is why I'm trying to open the window in the command_line
signal handler.
This works as expected, exits when the window is closed.
#include <gtkmm.h>
int main(int argc, char **argv) {
auto app = Gtk::Application::create(argc, argv, "my.app");
Gtk::ApplicationWindow win;
return app->run(win);
}
But simply adding the HANDLES_COMMAND_LINE
flag destroys that: The window is never shown.
#include <gtkmm.h>
int on_cmd(const Glib::RefPtr<Gio::ApplicationCommandLine> &) {
return 0;
}
int main(int argc, char **argv) {
auto app = Gtk::Application::create(argc, argv, "my.app",
Gio::APPLICATION_HANDLES_COMMAND_LINE);
app->signal_command_line().connect(sigc::ptr_fun(on_cmd), false);
Gtk::ApplicationWindow win;
return app->run(win);
}
So I figured that the command_line
handler isn't actually suppposed to return? But the documentation says run
starts the main loop. I haven't found a method that simply waits for the main loop to finish, so I crank it manually. The window is being shown again, but of course the loop continues once it's closed, which is the least problem with that code:
#include <gtkmm.h>
int on_cmd(const Glib::RefPtr<Gio::ApplicationCommandLine> &,
Glib::RefPtr<Gtk::Application> &app) {
Gtk::ApplicationWindow win(app);
// app->run(win); --- lands here again -> stack overflow.
win.show();
// This looks very wrong but seems to work?!
while(true)
Glib::MainContext::get_default()->iteration(true);
// never reach this
return 0;
}
int main(int argc, char **argv) {
auto app = Gtk::Application::create(argc, argv, "my.app",
Gio::APPLICATION_HANDLES_COMMAND_LINE);
app->signal_command_line().connect(
sigc::bind(sigc::ptr_fun(on_cmd), app), false);
return app->run();
}
(gtkmm-3.0 version 3.5.13)
Turns out, the key is calling
activate
on the application. The default handler which is executed whenHANDLES_COMMAND_LINE
is not given does that automatically.My second example was just missing one line:
Here's a subclassed application which parses the command line using Glib, and if
--gui
is present, opens a window and only terminates after the window is closed.Using
gtk_get_option_group
adds the GTK options (and help) to it, so--help-all
really shows all applicable options, and we don't have to rely ongtk_main(argc, argv)
to remove the GTK options, i.e. the argments can be deferred to therun(argc, argv)
call (but don't have to. If the application constructor is given the arguments, it will remove the GTK options, except--help-gtk
, our handler just never sees them but can still display help for it. Doesn't seem to matter either way)