gtk_init too late for G_APPLICATION_HANDLES_COMMAND_LINE
When trying to run the following program with 娃.tar.gz
as an argument, g_option_context_parse
will fail with Invalid byte sequence in conversion input
error.
/*
* File-Roller
*
* Copyright (C) 2012 Free Software Foundation, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <gtk/gtk.h>
#include <string.h>
#include <sys/types.h>
#include <signal.h>
#include <stdlib.h>
#include <gtk/gtk.h>
#include <glib.h>
#define GETTEXT_PACKAGE "file-roller"
#define PACKAGE_NAME "file-roller"
#define PACKAGE_VERSION "44.0"
G_DECLARE_FINAL_TYPE (FrApplication, fr_application, FR, APPLICATION, GtkApplication)
static char **remaining_args;
static const GOptionEntry options[] = {
{ G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &remaining_args,
NULL,
NULL },
{ NULL }
};
struct _FrApplication {
GtkApplication parent_instance;
};
G_DEFINE_TYPE (FrApplication, fr_application, GTK_TYPE_APPLICATION)
static GOptionContext *
fr_application_create_option_context (void) {
GOptionContext *context;
context = g_option_context_new (("— Create and modify an archive"));
g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);
g_option_context_add_main_entries (context, options, GETTEXT_PACKAGE);
g_option_context_set_ignore_unknown_options (context, TRUE);
return context;
}
static int
fr_application_command_line (GApplication *application, GApplicationCommandLine *command_line) {
return EXIT_SUCCESS;
}
static gboolean
fr_application_local_command_line (GApplication *application,
char ***arguments,
int *exit_status)
{
char **local_argv;
int local_argc;
GOptionContext *context;
GError *error = NULL;
gboolean handled_locally = FALSE;
local_argv = g_strdupv (*arguments);
local_argc = g_strv_length (local_argv);
*exit_status = 0;
context = fr_application_create_option_context ();
g_option_context_set_ignore_unknown_options (context, TRUE);
if (! g_option_context_parse (context, &local_argc, &local_argv, &error)) {
*exit_status = EXIT_FAILURE;
g_critical ("Failed to parse arguments: %s", error->message);
g_clear_error (&error);
handled_locally = TRUE;
}
g_option_context_free (context);
g_strfreev (local_argv);
return handled_locally;
}
static void
fr_application_class_init (FrApplicationClass *klass)
{
GApplicationClass *application_class;
application_class = G_APPLICATION_CLASS (klass);
application_class->command_line = fr_application_command_line;
application_class->local_command_line = fr_application_local_command_line;
}
static void
fr_application_init (FrApplication *self)
{
}
GtkApplication *
fr_application_new (void)
{
return g_object_new (fr_application_get_type (),
"application-id", "org.gnome.FileRoller",
"flags", G_APPLICATION_HANDLES_COMMAND_LINE,
NULL);
}
int
main (int argc, char **argv)
{
// We need to run gtk_init() before GtkApplication startup,
// otherwise non-ASCII CLI arguments will trip up the parser.
// gtk_init ();
GtkApplication *app = fr_application_new ();
int status = g_application_run (G_APPLICATION (app), argc, argv);
g_object_unref (app);
return status;
}
This appears to be at odds with the gtk_init
documentation:
If you are using
GtkApplication
, you don’t have to call this function; theGApplication::startup
handler does it for you.
Either the documentation should be changed, or gtk_init
call should be moved before GApplication::startup
is called.