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>
This commit is contained in:
Frederic Martinsons 2020-12-03 10:42:47 +01:00
parent 48efbc7d6f
commit c3a073e96f
7 changed files with 157 additions and 1 deletions

View File

@ -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>

View File

@ -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

131
gio/gio-tool-launch.c Normal file
View File

@ -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;
}

View File

@ -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"))

View File

@ -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);

View File

@ -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',

View File

@ -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