From e5f91951a132b4a7daa848887a87ba22f96568bc Mon Sep 17 00:00:00 2001 From: Ryan Lortie Date: Sun, 12 Jan 2014 12:31:38 -0500 Subject: [PATCH] GApplication: change commandline encoding policy Clarify in the documentation that the commandline arguments passed around by GApplication (to local_command_line and returned via g_application_command_line_get_arguments()) are in the GLib filename encoding (ie: UTF-8) on Windows, not the system code page. Fix the mismatch that would result from having argv passed to g_application_run() in main() on Windows (where it is in the system code page) by ignoring argc/argv on Windows and calling g_win32_get_command_line() for ourselves. Document this. This might be a slight API break on Windows: we documented that it was possible to call g_application_run() with arguments other than argc/argv and now doing that will result in those arguments being ignored. It has always been recommended practice to only call g_application_run() from main() directly, however, and all of our code examples have shown only this. We will see if this causes any issues and consider reevaluating the situation if so. https://bugzilla.gnome.org/show_bug.cgi?id=722025 --- gio/gapplication.c | 32 +++++++++++++++++++++----------- gio/gapplicationcommandline.c | 7 ++++++- 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/gio/gapplication.c b/gio/gapplication.c index 2024048..ffc1c27 100644 --- a/gio/gapplication.c +++ b/gio/gapplication.c @@ -1505,15 +1505,18 @@ g_application_open (GApplication *application, * is intended to be returned by main(). Although you are expected to pass * the @argc, @argv parameters from main() to this function, it is possible * to pass %NULL if @argv is not available or commandline handling is not - * required. + * required. Note that on Windows, @argc and @argv are ignored, and + * g_win32_get_command_line() is called internally (for proper support + * of Unicode commandline arguments). * * First, the local_command_line() virtual function is invoked. * This function always runs on the local instance. It gets passed a pointer - * to a %NULL-terminated copy of @argv and is expected to remove the arguments - * that it handled (shifting up remaining arguments). See - * for an example of - * parsing @argv manually. Alternatively, you may use the #GOptionContext API, - * after setting argc = g_strv_length (argv);. + * to a %NULL-terminated copy of the command line and is expected to + * remove the arguments that it handled (shifting up remaining + * arguments). See for + * an example of parsing @argv manually. Alternatively, you may use the + * #GOptionContext API, but you must use g_option_context_parse_strv() + * in order to avoid memory leaks and encoding mismatches. * * The last argument to local_command_line() is a pointer to the @status * variable which can used to set the exit status that is returned from @@ -1604,16 +1607,23 @@ g_application_run (GApplication *application, { gchar **arguments; int status; - gint i; g_return_val_if_fail (G_IS_APPLICATION (application), 1); g_return_val_if_fail (argc == 0 || argv != NULL, 1); g_return_val_if_fail (!application->priv->must_quit_now, 1); - arguments = g_new (gchar *, argc + 1); - for (i = 0; i < argc; i++) - arguments[i] = g_strdup (argv[i]); - arguments[i] = NULL; +#ifdef G_OS_WIN32 + arguments = g_win32_get_command_line (); +#else + { + gint i; + + arguments = g_new (gchar *, argc + 1); + for (i = 0; i < argc; i++) + arguments[i] = g_strdup (argv[i]); + arguments[i] = NULL; + } +#endif if (g_get_prgname () == NULL) { diff --git a/gio/gapplicationcommandline.c b/gio/gapplicationcommandline.c index 693cfff..905b35e 100644 --- a/gio/gapplicationcommandline.c +++ b/gio/gapplicationcommandline.c @@ -348,7 +348,12 @@ g_application_command_line_class_init (GApplicationCommandLineClass *class) * * Gets the list of arguments that was passed on the command line. * - * The strings in the array may contain non-utf8 data. + * The strings in the array may contain non-UTF-8 data on UNIX (such as + * filenames or arguments given in the system locale) but are always in + * UTF-8 on Windows. + * + * If you wish to use the return value with #GOptionContext, you must + * use g_option_context_parse_strv(). * * The return value is %NULL-terminated and should be freed using * g_strfreev(). -- 2.7.4