[glib: 1/2] Add gio launch command to execute desktop file




commit c3a073e96fe036dc069f455e904b456ae3f3906b
Author: Frederic Martinsons <frederic martinsons sigfox com>
Date:   Thu Dec 3 10:42:47 2020 +0100

    Add gio launch command to execute desktop file
    
    This command will try to execute a desktop file, before that
    it will load the input as a keyfile for checking its existence
    and its validity (as a keyfile).
    File arguments are allowed after the desktop file.
    
    Closes #54
    
    Signed-off-by: Frederic Martinsons <frederic martinsons sigfox com>

 docs/reference/gio/gio.xml |  19 +++++++
 gio/completion/gio         |   2 +-
 gio/gio-tool-launch.c      | 131 +++++++++++++++++++++++++++++++++++++++++++++
 gio/gio-tool.c             |   3 ++
 gio/gio-tool.h             |   1 +
 gio/meson.build            |   1 +
 po/POTFILES.in             |   1 +
 7 files changed, 157 insertions(+), 1 deletion(-)
---
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 @@
       <arg choice="opt" rep="repeat"><replaceable>OPTION</replaceable></arg>
       <arg choice="plain" rep="repeat"><replaceable>LOCATION</replaceable></arg>
     </cmdsynopsis>
+    <cmdsynopsis>
+      <command>gio</command>
+      <arg choice="plain">launch</arg>
+      <arg choice="plain"><replaceable>DESKTOP-FILE</replaceable></arg>
+      <arg choice="opt" rep="repeat"><replaceable>FILE-ARG</replaceable></arg>
+    </cmdsynopsis>
     <cmdsynopsis>
       <command>gio</command>
       <arg choice="plain">list</arg>
@@ -273,6 +279,19 @@
         </listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term>
+          <command>launch</command>
+          <arg choice="plain"><replaceable>DESKTOP-FILE</replaceable></arg>
+          <arg choice="opt" rep="repeat"><replaceable>FILE-ARG</replaceable></arg>
+        </term>
+        <listitem>
+          <para>Launch a desktop file from any location given.</para>
+          <para>The <command>launch</command> command extends the behavior of the <command>open</command> 
command by allowing
+            any desktop file to be launched, not only those registered as file handlers.</para>
+        </listitem>
+      </varlistentry>
+
       <varlistentry>
         <term>
           <command>list</command>
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 <http://www.gnu.org/licenses/>.
+ *
+ * Author: Frederic Martinsons <frederic martinsons sigfox com>
+ */
+
+#include "config.h"
+
+#include <gio/gio.h>
+
+#if defined(G_OS_UNIX) && !defined(HAVE_COCOA)
+#include <gio/gdesktopappinfo.h>
+#endif
+
+#include <gi18n.h>
+
+#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


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]