diff --git a/app/xdg-app-builtins-run.c b/app/xdg-app-builtins-run.c index fd2ff9ed..91a4a71c 100644 --- a/app/xdg-app-builtins-run.c +++ b/app/xdg-app-builtins-run.c @@ -156,14 +156,12 @@ xdg_app_builtin_run (int argc, char **argv, GCancellable *cancellable, GError ** g_autoptr(GFile) home = NULL; g_autoptr(GFile) user_font1 = NULL; g_autoptr(GFile) user_font2 = NULL; - g_autoptr(GFile) override_file = NULL; g_autoptr(XdgAppSessionHelper) session_helper = NULL; g_autofree char *runtime = NULL; g_autofree char *default_command = NULL; g_autofree char *runtime_ref = NULL; g_autofree char *app_ref = NULL; g_autofree char *doc_mount_path = NULL; - g_autoptr(GKeyFile) override_metakey = NULL; g_autoptr(GKeyFile) metakey = NULL; g_autoptr(GKeyFile) runtime_metakey = NULL; g_autoptr(GPtrArray) argv_array = NULL; @@ -178,10 +176,8 @@ xdg_app_builtin_run (int argc, char **argv, GCancellable *cancellable, GError ** int sync_proxy_pipes[2]; g_autoptr(XdgAppContext) arg_context = NULL; g_autoptr(XdgAppContext) app_context = NULL; + g_autoptr(XdgAppContext) overrides = NULL; g_autoptr(GDBusConnection) session_bus = NULL; - g_autoptr(GFile) override_metadata = NULL; - g_autofree char *override_metadata_contents = NULL; - gsize override_metadata_size; context = g_option_context_new ("APP [args...] - Run an app"); @@ -266,23 +262,8 @@ xdg_app_builtin_run (int argc, char **argv, GCancellable *cancellable, GError ** if (!xdg_app_context_load_metadata (app_context, metakey, error)) goto out; - override_metadata = xdg_app_get_override_file (app); - if (g_file_load_contents (override_metadata, cancellable, - &override_metadata_contents, &override_metadata_size, NULL, NULL)) - { - g_autoptr(GError) local_error = NULL; - g_autoptr(GKeyFile) override_metakey = NULL; - override_metakey = g_key_file_new (); - if (!g_key_file_load_from_data (override_metakey, - override_metadata_contents, override_metadata_size, - 0, &local_error)) - g_warning ("Invalid override file: %s\n", local_error->message); - else - { - if (!xdg_app_context_load_metadata (app_context, override_metakey, &local_error)) - g_warning ("Invalid override file: %s\n", local_error->message); - } - } + overrides = xdg_app_deploy_get_overrides (app_deploy); + xdg_app_context_merge (app_context, overrides); xdg_app_context_merge (app_context, arg_context); diff --git a/lib/xdg-app-dir.c b/lib/xdg-app-dir.c index ebd4d6d3..14a2349f 100644 --- a/lib/xdg-app-dir.c +++ b/lib/xdg-app-dir.c @@ -50,6 +50,8 @@ struct XdgAppDeploy { GFile *dir; GKeyFile *metadata; + GKeyFile *system_overrides; + GKeyFile *user_overrides; }; typedef struct { @@ -79,6 +81,8 @@ xdg_app_deploy_finalize (GObject *object) g_clear_object (&self->dir); g_clear_pointer (&self->metadata, g_key_file_unref); + g_clear_pointer (&self->system_overrides, g_key_file_unref); + g_clear_pointer (&self->user_overrides, g_key_file_unref); G_OBJECT_CLASS (xdg_app_deploy_parent_class)->finalize (object); } @@ -109,6 +113,29 @@ xdg_app_deploy_get_files (XdgAppDeploy *deploy) return g_file_get_child (deploy->dir, "files"); } +XdgAppContext * +xdg_app_deploy_get_overrides (XdgAppDeploy *deploy) +{ + GError *local_error = NULL; + XdgAppContext *overrides = xdg_app_context_new (); + + if (deploy->system_overrides && + !xdg_app_context_load_metadata (overrides, deploy->system_overrides, &local_error)) + { + g_warning ("Invalid system override file: %s\n", local_error->message); + g_clear_error (&local_error); + } + + if (deploy->user_overrides && + !xdg_app_context_load_metadata (overrides, deploy->user_overrides, &local_error)) + { + g_warning ("Invalid user override file: %s\n", local_error->message); + g_clear_error (&local_error); + } + + return overrides; +} + GKeyFile * xdg_app_deploy_get_metadata (XdgAppDeploy *deploy) { @@ -140,18 +167,6 @@ xdg_app_get_user_base_dir_location (void) return g_file_new_for_path (base); } -GFile * -xdg_app_get_override_file (const char *app_id) -{ - g_autoptr(GFile) user_dir = NULL; - g_autoptr(GFile) override_dir = NULL; - - user_dir = xdg_app_get_user_base_dir_location (); - override_dir = g_file_get_child (user_dir, "overrides"); - - return g_file_get_child (override_dir, app_id); -} - static void xdg_app_dir_finalize (GObject *object) { @@ -250,6 +265,39 @@ xdg_app_dir_get_path (XdgAppDir *self) return self->basedir; } +static GKeyFile * +xdg_app_load_override_file (const char *app_id, gboolean user) +{ + g_autoptr(GFile) base_dir = NULL; + g_autoptr(GFile) override_dir = NULL; + g_autoptr(GFile) file = NULL; + g_autofree char *metadata_contents = NULL; + gsize metadata_size; + + if (user) + base_dir = xdg_app_get_user_base_dir_location (); + else + base_dir = xdg_app_get_system_base_dir_location (); + + override_dir = g_file_get_child (base_dir, "overrides"); + file = g_file_get_child (override_dir, app_id); + + if (g_file_load_contents (file, NULL, + &metadata_contents, &metadata_size, NULL, NULL)) + { + g_autoptr(GError) local_error = NULL; + g_autoptr(GKeyFile) metakey = g_key_file_new (); + + if (!g_key_file_load_from_data (metakey, + metadata_contents, metadata_size, + 0, &local_error)) + g_warning ("Invalid override file: %s\n", local_error->message); + else + return g_steal_pointer (&metakey); + } + return NULL; +} + XdgAppDeploy * xdg_app_dir_load_deployed (XdgAppDir *self, const char *ref, @@ -260,7 +308,9 @@ xdg_app_dir_load_deployed (XdgAppDir *self, g_autoptr(GFile) deploy_dir = NULL; g_autoptr(GKeyFile) metakey = NULL; g_autoptr(GFile) metadata = NULL; + g_auto(GStrv) ref_parts = NULL; g_autofree char *metadata_contents = NULL; + XdgAppDeploy *deploy; gsize metadata_size; deploy_dir = xdg_app_dir_get_if_deployed (self, ref, checksum, cancellable); @@ -278,7 +328,23 @@ xdg_app_dir_load_deployed (XdgAppDir *self, if (!g_key_file_load_from_data (metakey, metadata_contents, metadata_size, 0, error)) return NULL; - return xdg_app_deploy_new (deploy_dir, metakey); + deploy = xdg_app_deploy_new (deploy_dir, metakey); + + ref_parts = g_strsplit (ref, "/", -1); + g_assert (g_strv_length (ref_parts) == 4); + + /* Only apps have overrides */ + if (strcmp (ref_parts[0], "app") == 0) + { + /* Only load system overrides for system installed apps */ + if (!self->user) + deploy->system_overrides = xdg_app_load_override_file (ref_parts[1], FALSE); + + /* Always load user overrides */ + deploy->user_overrides = xdg_app_load_override_file (ref_parts[1], TRUE); + } + + return deploy; } GFile * diff --git a/lib/xdg-app-dir.h b/lib/xdg-app-dir.h index 64ddbf83..e6d086c2 100644 --- a/lib/xdg-app-dir.h +++ b/lib/xdg-app-dir.h @@ -23,6 +23,8 @@ #include +#include + typedef struct XdgAppDir XdgAppDir; typedef struct XdgAppDeploy XdgAppDeploy; @@ -53,11 +55,10 @@ GQuark xdg_app_dir_error_quark (void); GFile * xdg_app_get_system_base_dir_location (void); GFile * xdg_app_get_user_base_dir_location (void); -GFile *xdg_app_get_override_file (const char *app_id); - -GFile * xdg_app_deploy_get_dir (XdgAppDeploy *deploy); -GFile * xdg_app_deploy_get_files (XdgAppDeploy *deploy); -GKeyFile * xdg_app_deploy_get_metadata (XdgAppDeploy *deploy); +GFile * xdg_app_deploy_get_dir (XdgAppDeploy *deploy); +GFile * xdg_app_deploy_get_files (XdgAppDeploy *deploy); +XdgAppContext *xdg_app_deploy_get_overrides (XdgAppDeploy *deploy); +GKeyFile * xdg_app_deploy_get_metadata (XdgAppDeploy *deploy); XdgAppDir* xdg_app_dir_new (GFile *basedir, gboolean user);