gdesktopappinfo: Take in account the desktop Path to find executables

Desktop files can provide the executable working path and that can be
used to pick the file to launch.

So take it in account.
This commit is contained in:
Marco Trevisan (Treviño) 2022-10-31 16:56:23 +01:00
parent 7bac92a2bb
commit e41e3dc601
4 changed files with 95 additions and 3 deletions

View File

@ -56,6 +56,7 @@
#include "gappinfo.h" #include "gappinfo.h"
#include "gappinfoprivate.h" #include "gappinfoprivate.h"
#include "glocalfilemonitor.h" #include "glocalfilemonitor.h"
#include "gutilsprivate.h"
#ifdef G_OS_UNIX #ifdef G_OS_UNIX
#include "gdocumentportal.h" #include "gdocumentportal.h"
@ -1830,6 +1831,7 @@ g_desktop_app_info_load_from_keyfile (GDesktopAppInfo *info,
char *type; char *type;
char *try_exec; char *try_exec;
char *exec; char *exec;
char *path;
gboolean bus_activatable; gboolean bus_activatable;
start_group = g_key_file_get_start_group (key_file); start_group = g_key_file_get_start_group (key_file);
@ -1851,6 +1853,10 @@ g_desktop_app_info_load_from_keyfile (GDesktopAppInfo *info,
} }
g_free (type); g_free (type);
path = g_key_file_get_string (key_file,
G_KEY_FILE_DESKTOP_GROUP,
G_KEY_FILE_DESKTOP_KEY_PATH, NULL);
try_exec = g_key_file_get_string (key_file, try_exec = g_key_file_get_string (key_file,
G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_GROUP,
G_KEY_FILE_DESKTOP_KEY_TRY_EXEC, G_KEY_FILE_DESKTOP_KEY_TRY_EXEC,
@ -1858,9 +1864,10 @@ g_desktop_app_info_load_from_keyfile (GDesktopAppInfo *info,
if (try_exec && try_exec[0] != '\0') if (try_exec && try_exec[0] != '\0')
{ {
char *t; char *t;
t = g_find_program_in_path (try_exec); t = g_find_program_for_path (try_exec, NULL, path);
if (t == NULL) if (t == NULL)
{ {
g_free (path);
g_free (try_exec); g_free (try_exec);
return FALSE; return FALSE;
} }
@ -1877,6 +1884,7 @@ g_desktop_app_info_load_from_keyfile (GDesktopAppInfo *info,
char **argv; char **argv;
if (!g_shell_parse_argv (exec, &argc, &argv, NULL)) if (!g_shell_parse_argv (exec, &argc, &argv, NULL))
{ {
g_free (path);
g_free (exec); g_free (exec);
g_free (try_exec); g_free (try_exec);
return FALSE; return FALSE;
@ -1888,11 +1896,12 @@ g_desktop_app_info_load_from_keyfile (GDesktopAppInfo *info,
/* Since @exec is not an empty string, there must be at least one /* Since @exec is not an empty string, there must be at least one
* argument, so dereferencing argv[0] should return non-NULL. */ * argument, so dereferencing argv[0] should return non-NULL. */
g_assert (argc > 0); g_assert (argc > 0);
t = g_find_program_in_path (argv[0]); t = g_find_program_for_path (argv[0], NULL, path);
g_strfreev (argv); g_strfreev (argv);
if (t == NULL) if (t == NULL)
{ {
g_free (path);
g_free (exec); g_free (exec);
g_free (try_exec); g_free (try_exec);
return FALSE; return FALSE;
@ -1912,7 +1921,7 @@ g_desktop_app_info_load_from_keyfile (GDesktopAppInfo *info,
info->not_show_in = g_key_file_get_string_list (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_NOT_SHOW_IN, NULL, NULL); info->not_show_in = g_key_file_get_string_list (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_NOT_SHOW_IN, NULL, NULL);
info->try_exec = try_exec; info->try_exec = try_exec;
info->exec = exec; info->exec = exec;
info->path = g_key_file_get_string (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_PATH, NULL); info->path = g_steal_pointer (&path);
info->terminal = g_key_file_get_boolean (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_TERMINAL, NULL) != FALSE; info->terminal = g_key_file_get_boolean (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_TERMINAL, NULL) != FALSE;
info->startup_notify = g_key_file_get_boolean (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_STARTUP_NOTIFY, NULL) != FALSE; info->startup_notify = g_key_file_get_boolean (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_STARTUP_NOTIFY, NULL) != FALSE;
info->no_fuse = g_key_file_get_boolean (key_file, G_KEY_FILE_DESKTOP_GROUP, "X-GIO-NoFuse", NULL) != FALSE; info->no_fuse = g_key_file_get_boolean (key_file, G_KEY_FILE_DESKTOP_GROUP, "X-GIO-NoFuse", NULL) != FALSE;

View File

@ -0,0 +1,22 @@
[Desktop Entry]
Type=Application
GenericName=generic-appinfo-test-path
Name=appinfo-test-path
Name[de]=appinfo-test-de
X-GNOME-FullName=example
X-GNOME-FullName[de]=Beispiel
Comment=GAppInfo example
Comment[de]=GAppInfo Beispiel
Path=@installed_tests_dir@
TryExec=apps
Exec=appinfo-test --option %U %i --name %c --filename %k %m %%
Icon=testicon.svg
Terminal=false
StartupNotify=true
StartupWMClass=appinfo-path-class
MimeType=image/png;image/jpeg;
Keywords=keyword1;test keyword;
Categories=GNOME;GTK;
X-JunkFood=Burger
X-JunkFood[de]=Bratwurst
X-JunkFood[it]=

View File

@ -1578,6 +1578,64 @@ test_launch_uris_with_invalid_terminal (void)
g_free (old_path); g_free (old_path);
} }
static void
test_app_path (void)
{
GDesktopAppInfo *appinfo;
const char *desktop_path;
desktop_path = g_test_get_filename (G_TEST_BUILT, "appinfo-test-path.desktop", NULL);
appinfo = g_desktop_app_info_new_from_filename (desktop_path);
g_assert_true (G_IS_DESKTOP_APP_INFO (appinfo));
g_clear_object (&appinfo);
}
static void
test_app_path_wrong (void)
{
GKeyFile *key_file;
GDesktopAppInfo *appinfo;
const gchar bad_try_exec_file_contents[] =
"[Desktop Entry]\n"
"Type=Application\n"
"Name=appinfo-test\n"
"TryExec=appinfo-test\n"
"Path=this-must-not-exist‼\n"
"Exec=true\n";
const gchar bad_exec_file_contents[] =
"[Desktop Entry]\n"
"Type=Application\n"
"Name=appinfo-test\n"
"TryExec=true\n"
"Path=this-must-not-exist‼\n"
"Exec=appinfo-test\n";
g_assert_true (
g_file_test (g_test_get_filename (G_TEST_BUILT, "appinfo-test", NULL),
G_FILE_TEST_IS_REGULAR | G_FILE_TEST_IS_EXECUTABLE));
key_file = g_key_file_new ();
g_assert_true (
g_key_file_load_from_data (key_file, bad_try_exec_file_contents, -1,
G_KEY_FILE_NONE, NULL));
appinfo = g_desktop_app_info_new_from_keyfile (key_file);
g_assert_false (G_IS_DESKTOP_APP_INFO (appinfo));
g_assert_true (
g_key_file_load_from_data (key_file, bad_exec_file_contents, -1,
G_KEY_FILE_NONE, NULL));
appinfo = g_desktop_app_info_new_from_keyfile (key_file);
g_assert_false (G_IS_DESKTOP_APP_INFO (appinfo));
g_clear_pointer (&key_file, g_key_file_unref);
g_clear_object (&appinfo);
}
int int
main (int argc, main (int argc,
char *argv[]) char *argv[])
@ -1615,6 +1673,8 @@ main (int argc,
g_test_add_func ("/desktop-app-info/search", test_search); g_test_add_func ("/desktop-app-info/search", test_search);
g_test_add_func ("/desktop-app-info/implements", test_implements); g_test_add_func ("/desktop-app-info/implements", test_implements);
g_test_add_func ("/desktop-app-info/show-in", test_show_in); g_test_add_func ("/desktop-app-info/show-in", test_show_in);
g_test_add_func ("/desktop-app-info/app-path", test_app_path);
g_test_add_func ("/desktop-app-info/app-path/wrong", test_app_path_wrong);
g_test_add_func ("/desktop-app-info/launch-as-manager", test_launch_as_manager); g_test_add_func ("/desktop-app-info/launch-as-manager", test_launch_as_manager);
g_test_add_func ("/desktop-app-info/launch-as-manager/fail", test_launch_as_manager_fail); g_test_add_func ("/desktop-app-info/launch-as-manager/fail", test_launch_as_manager_fail);
g_test_add_func ("/desktop-app-info/launch-default-uri-handler", test_default_uri_handler); g_test_add_func ("/desktop-app-info/launch-default-uri-handler", test_default_uri_handler);

View File

@ -628,6 +628,7 @@ endif
appinfo_test_desktop_files = [ appinfo_test_desktop_files = [
'appinfo-test-gnome', 'appinfo-test-gnome',
'appinfo-test-notgnome', 'appinfo-test-notgnome',
'appinfo-test-path',
'appinfo-test', 'appinfo-test',
'appinfo-test2', 'appinfo-test2',
] ]