diff --git a/docs/reference/gio/gio.xml b/docs/reference/gio/gio.xml
index 641b2228c..eecaac9a1 100644
--- a/docs/reference/gio/gio.xml
+++ b/docs/reference/gio/gio.xml
@@ -53,6 +53,12 @@
OPTION
LOCATION
+
+ gio
+ launch
+ DESKTOP-FILE
+ FILE-ARG
+
gio
list
@@ -273,6 +279,19 @@
+
+
+ launch
+ DESKTOP-FILE
+ FILE-ARG
+
+
+ Launch a desktop file from any location given.
+ The launch command extends the behavior of the open command by allowing
+ any desktop file to be launched, not only those registered as file handlers.
+
+
+
list
diff --git a/gio/completion/gio b/gio/completion/gio
index 75473d255..989befedd 100644
--- a/gio/completion/gio
+++ b/gio/completion/gio
@@ -105,7 +105,7 @@ __gio_location() {
__gio() {
# Complete subcommands
if (( ${COMP_CWORD} == 1 )); then
- COMPREPLY=($(compgen -W "help version cat copy info list mime mkdir monitor mount move open rename remove save set trash tree" -- "${COMP_WORDS[1]}"))
+ COMPREPLY=($(compgen -W "help version cat copy info launch list mime mkdir monitor mount move open rename remove save set trash tree" -- "${COMP_WORDS[1]}"))
compopt +o nospace
return 0
fi
diff --git a/gio/gio-tool-launch.c b/gio/gio-tool-launch.c
new file mode 100644
index 000000000..08c91c68a
--- /dev/null
+++ b/gio/gio-tool-launch.c
@@ -0,0 +1,131 @@
+/*
+ * Copyright 2020 Frederic Martinsons
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see .
+ *
+ * Author: Frederic Martinsons
+ */
+
+#include "config.h"
+
+#include
+
+#if defined(G_OS_UNIX) && !defined(HAVE_COCOA)
+#include
+#endif
+
+#include
+
+#include "gio-tool.h"
+
+static const GOptionEntry entries[] = {
+ { NULL }
+};
+
+int
+handle_launch (int argc, char *argv[], gboolean do_help)
+{
+ GOptionContext *context;
+ GError *error = NULL;
+#if defined(G_OS_UNIX) && !defined(HAVE_COCOA)
+ int i;
+ GAppInfo *app = NULL;
+ GAppLaunchContext *app_context = NULL;
+ GKeyFile *keyfile = NULL;
+ GList *args = NULL;
+ char *desktop_file = NULL;
+#endif
+ int retval;
+
+ g_set_prgname ("gio launch");
+
+ /* Translators: commandline placeholder */
+ context = g_option_context_new (_("DESKTOP-FILE [FILE-ARG …]"));
+ g_option_context_set_help_enabled (context, FALSE);
+ g_option_context_set_summary (context,
+ _("Launch an application from a desktop file, passing optional filename arguments to it."));
+ g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
+
+ if (do_help)
+ {
+ show_help (context, NULL);
+ g_option_context_free (context);
+ return 0;
+ }
+
+ if (!g_option_context_parse (context, &argc, &argv, &error))
+ {
+ show_help (context, error->message);
+ g_error_free (error);
+ g_option_context_free (context);
+ return 1;
+ }
+
+ if (argc < 2)
+ {
+ show_help (context, _("No desktop file given"));
+ g_option_context_free (context);
+ return 1;
+ }
+
+ g_option_context_free (context);
+
+#if !defined(G_OS_UNIX) || defined(HAVE_COCOA)
+ print_error (_("The launch command is not currently supported on this platform"));
+ retval = 1;
+#else
+ retval = 0;
+ desktop_file = argv[1];
+
+ /* Use keyfile api for loading desktop app in order to check for
+ * - not existing file.
+ * - invalid keyfile format.
+ */
+ keyfile = g_key_file_new ();
+ if (!g_key_file_load_from_file (keyfile, desktop_file, G_KEY_FILE_NONE, &error))
+ {
+ print_error (_("Unable to load ‘%s‘: %s"), desktop_file, error->message);
+ g_clear_error (&error);
+ retval = 1;
+ }
+ else
+ {
+ app = (GAppInfo*)g_desktop_app_info_new_from_keyfile (keyfile);
+ if (!app)
+ {
+ print_error (_("Unable to load application information for ‘%s‘"), desktop_file);
+ retval = 1;
+ }
+ else
+ {
+ for (i = 2; i < argc; i++)
+ {
+ args = g_list_append (args, g_file_new_for_commandline_arg (argv[i]));
+ }
+ app_context = g_app_launch_context_new ();
+ if (!g_app_info_launch (app, args, app_context, &error))
+ {
+ print_error (_("Unable to launch application ‘%s’: %s"), desktop_file, error->message);
+ g_clear_error (&error);
+ retval = 1;
+ }
+ g_list_free_full (args, g_object_unref);
+ g_clear_object (&app_context);
+ }
+ g_clear_object (&app);
+ }
+ g_key_file_free (keyfile);
+#endif
+ return retval;
+}
diff --git a/gio/gio-tool.c b/gio/gio-tool.c
index c0aec7492..ff82c638e 100644
--- a/gio/gio-tool.c
+++ b/gio/gio-tool.c
@@ -229,6 +229,7 @@ usage (void)
g_printerr (" cat %s\n", _("Concatenate files to standard output"));
g_printerr (" copy %s\n", _("Copy one or more files"));
g_printerr (" info %s\n", _("Show information about locations"));
+ g_printerr (" launch %s\n", _("Launch an application from a desktop file"));
g_printerr (" list %s\n", _("List the contents of locations"));
g_printerr (" mime %s\n", _("Get or set the handler for a mimetype"));
g_printerr (" mkdir %s\n", _("Create directories"));
@@ -312,6 +313,8 @@ main (int argc, char **argv)
return handle_copy (argc, argv, do_help);
else if (g_str_equal (command, "info"))
return handle_info (argc, argv, do_help);
+ else if (g_str_equal (command, "launch"))
+ return handle_launch (argc, argv, do_help);
else if (g_str_equal (command, "list"))
return handle_list (argc, argv, do_help);
else if (g_str_equal (command, "mime"))
diff --git a/gio/gio-tool.h b/gio/gio-tool.h
index 5064165a6..6cd1d946a 100644
--- a/gio/gio-tool.h
+++ b/gio/gio-tool.h
@@ -37,6 +37,7 @@ gboolean file_is_dir (GFile *file);
int handle_cat (int argc, char *argv[], gboolean do_help);
int handle_copy (int argc, char *argv[], gboolean do_help);
int handle_info (int argc, char *argv[], gboolean do_help);
+int handle_launch (int argc, char *argv[], gboolean do_help);
int handle_list (int argc, char *argv[], gboolean do_help);
int handle_mime (int argc, char *argv[], gboolean do_help);
int handle_mkdir (int argc, char *argv[], gboolean do_help);
diff --git a/gio/meson.build b/gio/meson.build
index f79d22053..465a7d2d6 100644
--- a/gio/meson.build
+++ b/gio/meson.build
@@ -908,6 +908,7 @@ gio_tool_sources = [
'gio-tool-cat.c',
'gio-tool-copy.c',
'gio-tool-info.c',
+ 'gio-tool-launch.c',
'gio-tool-list.c',
'gio-tool-mime.c',
'gio-tool-mkdir.c',
diff --git a/po/POTFILES.in b/po/POTFILES.in
index bb9d8e370..c31517dcf 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -75,6 +75,7 @@ gio/gio-tool.c
gio/gio-tool-cat.c
gio/gio-tool-copy.c
gio/gio-tool-info.c
+gio/gio-tool-launch.c
gio/gio-tool-list.c
gio/gio-tool-mime.c
gio/gio-tool-mkdir.c