From owner-svn-ports-all@freebsd.org Thu Jun 18 00:56:02 2020 Return-Path: Delivered-To: svn-ports-all@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 1623833C5EB; Thu, 18 Jun 2020 00:56:02 +0000 (UTC) (envelope-from jbeich@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 49nNm15hVLz3XVZ; Thu, 18 Jun 2020 00:56:01 +0000 (UTC) (envelope-from jbeich@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 66A9128D7D; Thu, 18 Jun 2020 00:55:58 +0000 (UTC) (envelope-from jbeich@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 05I0tw9s016599; Thu, 18 Jun 2020 00:55:58 GMT (envelope-from jbeich@FreeBSD.org) Received: (from jbeich@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 05I0twEV016597; Thu, 18 Jun 2020 00:55:58 GMT (envelope-from jbeich@FreeBSD.org) Message-Id: <202006180055.05I0twEV016597@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: jbeich set sender to jbeich@FreeBSD.org using -f From: Jan Beich Date: Thu, 18 Jun 2020 00:55:58 +0000 (UTC) To: ports-committers@freebsd.org, svn-ports-all@freebsd.org, svn-ports-head@freebsd.org Subject: svn commit: r539508 - in head/devel/glib20: . files X-SVN-Group: ports-head X-SVN-Commit-Author: jbeich X-SVN-Commit-Paths: in head/devel/glib20: . files X-SVN-Commit-Revision: 539508 X-SVN-Commit-Repository: ports MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-ports-all@freebsd.org X-Mailman-Version: 2.1.33 Precedence: list List-Id: SVN commit messages for the ports tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 18 Jun 2020 00:56:02 -0000 Author: jbeich Date: Thu Jun 18 00:55:57 2020 New Revision: 539508 URL: https://svnweb.freebsd.org/changeset/ports/539508 Log: devel/glib20: backport GSETTINGS_BACKEND=keyfile support If devel/dconf or devel/gconf2 are installed then nothing changes. If neither are installed then settings are now stored in ~/.config/glib-2.0/settings/keyfile. PR: 247039 Obtained from: upstream Added: head/devel/glib20/files/patch-keyfile (contents, props changed) Modified: head/devel/glib20/Makefile (contents, props changed) Modified: head/devel/glib20/Makefile ============================================================================== --- head/devel/glib20/Makefile Thu Jun 18 00:55:52 2020 (r539507) +++ head/devel/glib20/Makefile Thu Jun 18 00:55:57 2020 (r539508) @@ -3,7 +3,7 @@ PORTNAME= glib PORTVERSION= 2.56.3 -PORTREVISION= 7 +PORTREVISION= 8 PORTEPOCH= 1 CATEGORIES= devel MASTER_SITES= GNOME Added: head/devel/glib20/files/patch-keyfile ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/devel/glib20/files/patch-keyfile Thu Jun 18 00:55:57 2020 (r539508) @@ -0,0 +1,668 @@ +https://gitlab.gnome.org/GNOME/glib/-/merge_requests/450 +https://gitlab.gnome.org/GNOME/glib/-/merge_requests/603 +https://gitlab.gnome.org/GNOME/glib/-/merge_requests/604 +https://gitlab.gnome.org/GNOME/glib/-/merge_requests/629 +https://gitlab.gnome.org/GNOME/glib/-/merge_requests/974 +https://gitlab.gnome.org/GNOME/glib/-/merge_requests/984 +https://gitlab.gnome.org/GNOME/glib/-/merge_requests/985 + +--- gio/giomodule.c.orig 2018-09-21 09:29:23 UTC ++++ gio/giomodule.c +@@ -1136,6 +1136,7 @@ _g_io_modules_ensure_loaded (void) + /* Initialize types from built-in "modules" */ + g_type_ensure (g_null_settings_backend_get_type ()); + g_type_ensure (g_memory_settings_backend_get_type ()); ++ g_type_ensure (g_keyfile_settings_backend_get_type ()); + #if defined(HAVE_INOTIFY_INIT1) + g_type_ensure (g_inotify_file_monitor_get_type ()); + #endif +--- gio/gkeyfilesettingsbackend.c.orig 2018-08-15 16:22:08 UTC ++++ gio/gkeyfilesettingsbackend.c +@@ -21,14 +21,20 @@ + + #include "config.h" + ++#include ++#include ++ + #include + #include + + #include "gfile.h" + #include "gfileinfo.h" ++#include "gfileenumerator.h" + #include "gfilemonitor.h" + #include "gsimplepermission.h" +-#include "gsettingsbackend.h" ++#include "gsettingsbackendinternal.h" ++#include "giomodule-priv.h" ++#include "gportalsupport.h" + + + #define G_TYPE_KEYFILE_SETTINGS_BACKEND (g_keyfile_settings_backend_get_type ()) +@@ -41,6 +47,13 @@ + + typedef GSettingsBackendClass GKeyfileSettingsBackendClass; + ++typedef enum { ++ PROP_FILENAME = 1, ++ PROP_ROOT_PATH, ++ PROP_ROOT_GROUP, ++ PROP_DEFAULTS_DIR ++} GKeyfileSettingsBackendProperty; ++ + typedef struct + { + GSettingsBackend parent_instance; +@@ -48,6 +61,9 @@ typedef struct + GKeyFile *keyfile; + GPermission *permission; + gboolean writable; ++ char *defaults_dir; ++ GKeyFile *system_keyfile; ++ GHashTable *system_locks; /* Used as a set, owning the strings it contains */ + + gchar *prefix; + gint prefix_len; +@@ -61,11 +77,19 @@ typedef struct + GFileMonitor *dir_monitor; + } GKeyfileSettingsBackend; + +-static GType g_keyfile_settings_backend_get_type (void); +-G_DEFINE_TYPE (GKeyfileSettingsBackend, +- g_keyfile_settings_backend, +- G_TYPE_SETTINGS_BACKEND) ++#ifdef G_OS_WIN32 ++#define EXTENSION_PRIORITY 10 ++#else ++#define EXTENSION_PRIORITY (glib_should_use_portal () && !glib_has_dconf_access_in_sandbox () ? 110 : 10) ++#endif + ++G_DEFINE_TYPE_WITH_CODE (GKeyfileSettingsBackend, ++ g_keyfile_settings_backend, ++ G_TYPE_SETTINGS_BACKEND, ++ _g_io_modules_ensure_extension_points_registered (); ++ g_io_extension_point_implement (G_SETTINGS_BACKEND_EXTENSION_POINT_NAME, ++ g_define_type_id, "keyfile", EXTENSION_PRIORITY)) ++ + static void + compute_checksum (guint8 *digest, + gconstpointer contents, +@@ -89,7 +113,8 @@ g_keyfile_settings_backend_keyfile_write (GKeyfileSett + + contents = g_key_file_to_data (kfsb->keyfile, &length, NULL); + g_file_replace_contents (kfsb->file, contents, length, NULL, FALSE, +- G_FILE_CREATE_REPLACE_DESTINATION, ++ G_FILE_CREATE_REPLACE_DESTINATION | ++ G_FILE_CREATE_PRIVATE, + NULL, NULL, NULL); + + compute_checksum (kfsb->digest, contents, length); +@@ -184,17 +209,51 @@ get_from_keyfile (GKeyfileSettingsBackend *kfsb, + if (convert_path (kfsb, key, &group, &name)) + { + gchar *str; ++ gchar *sysstr; + + g_assert (*name); + ++ sysstr = g_key_file_get_value (kfsb->system_keyfile, group, name, NULL); + str = g_key_file_get_value (kfsb->keyfile, group, name, NULL); ++ if (sysstr && ++ (g_hash_table_contains (kfsb->system_locks, key) || ++ str == NULL)) ++ { ++ g_free (str); ++ str = g_steal_pointer (&sysstr); ++ } + + if (str) + { + return_value = g_variant_parse (type, str, NULL, NULL, NULL); ++ ++ /* As a special case, support values of type %G_VARIANT_TYPE_STRING ++ * not being quoted, since users keep forgetting to do it and then ++ * getting confused. */ ++ if (return_value == NULL && ++ g_variant_type_equal (type, G_VARIANT_TYPE_STRING) && ++ str[0] != '\"') ++ { ++ GString *s = g_string_sized_new (strlen (str) + 2); ++ char *p = str; ++ ++ g_string_append_c (s, '\"'); ++ while (*p) ++ { ++ if (*p == '\"') ++ g_string_append_c (s, '\\'); ++ g_string_append_c (s, *p); ++ p++; ++ } ++ g_string_append_c (s, '\"'); ++ return_value = g_variant_parse (type, s->str, NULL, NULL, NULL); ++ g_string_free (s, TRUE); ++ } + g_free (str); + } + ++ g_free (sysstr); ++ + g_free (group); + g_free (name); + } +@@ -209,6 +268,9 @@ set_to_keyfile (GKeyfileSettingsBackend *kfsb, + { + gchar *group, *name; + ++ if (g_hash_table_contains (kfsb->system_locks, key)) ++ return FALSE; ++ + if (convert_path (kfsb, key, &group, &name)) + { + if (value) +@@ -287,7 +349,8 @@ g_keyfile_settings_backend_check_one (gpointer key, + { + WriteManyData *data = user_data; + +- return data->failed = !path_is_valid (data->kfsb, key); ++ return data->failed = g_hash_table_contains (data->kfsb->system_locks, key) || ++ !path_is_valid (data->kfsb, key); + } + + static gboolean +@@ -355,7 +418,9 @@ g_keyfile_settings_backend_get_writable (GSettingsBack + { + GKeyfileSettingsBackend *kfsb = G_KEYFILE_SETTINGS_BACKEND (backend); + +- return kfsb->writable && path_is_valid (kfsb, name); ++ return kfsb->writable && ++ !g_hash_table_contains (kfsb->system_locks, name) && ++ path_is_valid (kfsb, name); + } + + static GPermission * +@@ -501,6 +566,9 @@ g_keyfile_settings_backend_finalize (GObject *object) + + g_key_file_free (kfsb->keyfile); + g_object_unref (kfsb->permission); ++ g_key_file_unref (kfsb->system_keyfile); ++ g_hash_table_unref (kfsb->system_locks); ++ g_free (kfsb->defaults_dir); + + g_file_monitor_cancel (kfsb->file_monitor); + g_object_unref (kfsb->file_monitor); +@@ -523,25 +591,6 @@ g_keyfile_settings_backend_init (GKeyfileSettingsBacke + } + + static void +-g_keyfile_settings_backend_class_init (GKeyfileSettingsBackendClass *class) +-{ +- GObjectClass *object_class = G_OBJECT_CLASS (class); +- +- object_class->finalize = g_keyfile_settings_backend_finalize; +- +- class->read = g_keyfile_settings_backend_read; +- class->write = g_keyfile_settings_backend_write; +- class->write_tree = g_keyfile_settings_backend_write_tree; +- class->reset = g_keyfile_settings_backend_reset; +- class->get_writable = g_keyfile_settings_backend_get_writable; +- class->get_permission = g_keyfile_settings_backend_get_permission; +- /* No need to implement subscribed/unsubscribe: the only point would be to +- * stop monitoring the file when there's no GSettings anymore, which is no +- * big win. +- */ +-} +- +-static void + file_changed (GFileMonitor *monitor, + GFile *file, + GFile *other_file, +@@ -567,6 +616,283 @@ dir_changed (GFileMonitor *monitor, + g_keyfile_settings_backend_keyfile_writable (kfsb); + } + ++static void ++load_system_settings (GKeyfileSettingsBackend *kfsb) ++{ ++ GError *error = NULL; ++ const char *dir = "/etc/glib-2.0/settings"; ++ char *path; ++ char *contents; ++ ++ kfsb->system_keyfile = g_key_file_new (); ++ kfsb->system_locks = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); ++ ++ if (kfsb->defaults_dir) ++ dir = kfsb->defaults_dir; ++ ++ path = g_build_filename (dir, "defaults", NULL); ++ ++ /* The defaults are in the same keyfile format that we use for the settings. ++ * It can be produced from a dconf database using: dconf dump ++ */ ++ if (!g_key_file_load_from_file (kfsb->system_keyfile, path, G_KEY_FILE_NONE, &error)) ++ { ++ if (!g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT)) ++ g_warning ("Failed to read %s: %s", path, error->message); ++ g_clear_error (&error); ++ } ++ else ++ g_debug ("Loading default settings from %s", path); ++ ++ g_free (path); ++ ++ path = g_build_filename (dir, "locks", NULL); ++ ++ /* The locks file is a text file containing a list paths to lock, one per line. ++ * It can be produced from a dconf database using: dconf list-locks ++ */ ++ if (!g_file_get_contents (path, &contents, NULL, &error)) ++ { ++ if (!g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT)) ++ g_warning ("Failed to read %s: %s", path, error->message); ++ g_clear_error (&error); ++ } ++ else ++ { ++ char **lines; ++ gsize i; ++ ++ g_debug ("Loading locks from %s", path); ++ ++ lines = g_strsplit (contents, "\n", 0); ++ for (i = 0; lines[i]; i++) ++ { ++ char *line = lines[i]; ++ if (line[0] == '#' || line[0] == '\0') ++ { ++ g_free (line); ++ continue; ++ } ++ ++ g_debug ("Locking key %s", line); ++ g_hash_table_add (kfsb->system_locks, g_steal_pointer (&line)); ++ } ++ ++ g_free (lines); ++ } ++ g_free (contents); ++ ++ g_free (path); ++} ++ ++static void ++g_keyfile_settings_backend_constructed (GObject *object) ++{ ++ GKeyfileSettingsBackend *kfsb = G_KEYFILE_SETTINGS_BACKEND (object); ++ ++ if (kfsb->file == NULL) ++ { ++ char *filename = g_build_filename (g_get_user_config_dir (), ++ "glib-2.0", "settings", "keyfile", ++ NULL); ++ kfsb->file = g_file_new_for_path (filename); ++ g_free (filename); ++ } ++ ++ if (kfsb->prefix == NULL) ++ { ++ kfsb->prefix = g_strdup ("/"); ++ kfsb->prefix_len = 1; ++ } ++ ++ kfsb->keyfile = g_key_file_new (); ++ kfsb->permission = g_simple_permission_new (TRUE); ++ ++ kfsb->dir = g_file_get_parent (kfsb->file); ++ g_mkdir_with_parents (g_file_peek_path (kfsb->dir), 0700); ++ ++ kfsb->file_monitor = g_file_monitor (kfsb->file, G_FILE_MONITOR_NONE, NULL, NULL); ++ kfsb->dir_monitor = g_file_monitor (kfsb->dir, G_FILE_MONITOR_NONE, NULL, NULL); ++ ++ compute_checksum (kfsb->digest, NULL, 0); ++ ++ g_signal_connect (kfsb->file_monitor, "changed", ++ G_CALLBACK (file_changed), kfsb); ++ g_signal_connect (kfsb->dir_monitor, "changed", ++ G_CALLBACK (dir_changed), kfsb); ++ ++ g_keyfile_settings_backend_keyfile_writable (kfsb); ++ g_keyfile_settings_backend_keyfile_reload (kfsb); ++ ++ load_system_settings (kfsb); ++} ++ ++static void ++g_keyfile_settings_backend_set_property (GObject *object, ++ guint prop_id, ++ const GValue *value, ++ GParamSpec *pspec) ++{ ++ GKeyfileSettingsBackend *kfsb = G_KEYFILE_SETTINGS_BACKEND (object); ++ ++ switch ((GKeyfileSettingsBackendProperty)prop_id) ++ { ++ case PROP_FILENAME: ++ /* Construct only. */ ++ g_assert (kfsb->file == NULL); ++ if (g_value_get_string (value)) ++ kfsb->file = g_file_new_for_path (g_value_get_string (value)); ++ break; ++ ++ case PROP_ROOT_PATH: ++ /* Construct only. */ ++ g_assert (kfsb->prefix == NULL); ++ kfsb->prefix = g_value_dup_string (value); ++ if (kfsb->prefix) ++ kfsb->prefix_len = strlen (kfsb->prefix); ++ break; ++ ++ case PROP_ROOT_GROUP: ++ /* Construct only. */ ++ g_assert (kfsb->root_group == NULL); ++ kfsb->root_group = g_value_dup_string (value); ++ if (kfsb->root_group) ++ kfsb->root_group_len = strlen (kfsb->root_group); ++ break; ++ ++ case PROP_DEFAULTS_DIR: ++ /* Construct only. */ ++ g_assert (kfsb->defaults_dir == NULL); ++ kfsb->defaults_dir = g_value_dup_string (value); ++ break; ++ ++ default: ++ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); ++ break; ++ } ++} ++ ++static void ++g_keyfile_settings_backend_get_property (GObject *object, ++ guint prop_id, ++ GValue *value, ++ GParamSpec *pspec) ++{ ++ GKeyfileSettingsBackend *kfsb = G_KEYFILE_SETTINGS_BACKEND (object); ++ ++ switch ((GKeyfileSettingsBackendProperty)prop_id) ++ { ++ case PROP_FILENAME: ++ g_value_set_string (value, g_file_peek_path (kfsb->file)); ++ break; ++ ++ case PROP_ROOT_PATH: ++ g_value_set_string (value, kfsb->prefix); ++ break; ++ ++ case PROP_ROOT_GROUP: ++ g_value_set_string (value, kfsb->root_group); ++ break; ++ ++ case PROP_DEFAULTS_DIR: ++ g_value_set_string (value, kfsb->defaults_dir); ++ break; ++ ++ default: ++ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); ++ break; ++ } ++} ++ ++static void ++g_keyfile_settings_backend_class_init (GKeyfileSettingsBackendClass *class) ++{ ++ GObjectClass *object_class = G_OBJECT_CLASS (class); ++ ++ object_class->finalize = g_keyfile_settings_backend_finalize; ++ object_class->constructed = g_keyfile_settings_backend_constructed; ++ object_class->get_property = g_keyfile_settings_backend_get_property; ++ object_class->set_property = g_keyfile_settings_backend_set_property; ++ ++ class->read = g_keyfile_settings_backend_read; ++ class->write = g_keyfile_settings_backend_write; ++ class->write_tree = g_keyfile_settings_backend_write_tree; ++ class->reset = g_keyfile_settings_backend_reset; ++ class->get_writable = g_keyfile_settings_backend_get_writable; ++ class->get_permission = g_keyfile_settings_backend_get_permission; ++ /* No need to implement subscribed/unsubscribe: the only point would be to ++ * stop monitoring the file when there's no GSettings anymore, which is no ++ * big win. ++ */ ++ ++ /** ++ * GKeyfileSettingsBackend:filename: ++ * ++ * The location where the settings are stored on disk. ++ * ++ * Defaults to `$XDG_CONFIG_HOME/glib-2.0/settings/keyfile`. ++ */ ++ g_object_class_install_property (object_class, ++ PROP_FILENAME, ++ g_param_spec_string ("filename", ++ P_("Filename"), ++ P_("The filename"), ++ NULL, ++ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | ++ G_PARAM_STATIC_STRINGS)); ++ ++ /** ++ * GKeyfileSettingsBackend:root-path: ++ * ++ * All settings read to or written from the backend must fall under the ++ * path given in @root_path (which must start and end with a slash and ++ * not contain two consecutive slashes). @root_path may be "/". ++ * ++ * Defaults to "/". ++ */ ++ g_object_class_install_property (object_class, ++ PROP_ROOT_PATH, ++ g_param_spec_string ("root-path", ++ P_("Root path"), ++ P_("The root path"), ++ NULL, ++ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | ++ G_PARAM_STATIC_STRINGS)); ++ ++ /** ++ * GKeyfileSettingsBackend:root-group: ++ * ++ * If @root_group is non-%NULL then it specifies the name of the keyfile ++ * group used for keys that are written directly below the root path. ++ * ++ * Defaults to NULL. ++ */ ++ g_object_class_install_property (object_class, ++ PROP_ROOT_GROUP, ++ g_param_spec_string ("root-group", ++ P_("Root group"), ++ P_("The root group"), ++ NULL, ++ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | ++ G_PARAM_STATIC_STRINGS)); ++ ++ /** ++ * GKeyfileSettingsBackend:default-dir: ++ * ++ * The directory where the system defaults and locks are located. ++ * ++ * Defaults to `/etc/glib-2.0/settings`. ++ */ ++ g_object_class_install_property (object_class, ++ PROP_DEFAULTS_DIR, ++ g_param_spec_string ("defaults-dir", ++ P_("Default dir"), ++ P_("Defaults dir"), ++ NULL, ++ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | ++ G_PARAM_STATIC_STRINGS)); ++} ++ + /** + * g_keyfile_settings_backend_new: + * @filename: the filename of the keyfile +@@ -619,6 +945,11 @@ dir_changed (GFileMonitor *monitor, + * characters in your path names or '=' in your key names you may be in + * trouble. + * ++ * The backend reads default values from a keyfile called `defaults` in ++ * the directory specified by the #GKeyfileSettingsBackend:defaults-dir property, ++ * and a list of locked keys from a text file with the name `locks` in ++ * the same location. ++ * + * Returns: (transfer full): a keyfile-backed #GSettingsBackend + **/ + GSettingsBackend * +@@ -626,43 +957,15 @@ g_keyfile_settings_backend_new (const gchar *filename, + const gchar *root_path, + const gchar *root_group) + { +- GKeyfileSettingsBackend *kfsb; +- + g_return_val_if_fail (filename != NULL, NULL); + g_return_val_if_fail (root_path != NULL, NULL); + g_return_val_if_fail (g_str_has_prefix (root_path, "/"), NULL); + g_return_val_if_fail (g_str_has_suffix (root_path, "/"), NULL); + g_return_val_if_fail (strstr (root_path, "//") == NULL, NULL); + +- kfsb = g_object_new (G_TYPE_KEYFILE_SETTINGS_BACKEND, NULL); +- kfsb->keyfile = g_key_file_new (); +- kfsb->permission = g_simple_permission_new (TRUE); +- +- kfsb->file = g_file_new_for_path (filename); +- kfsb->dir = g_file_get_parent (kfsb->file); +- g_file_make_directory_with_parents (kfsb->dir, NULL, NULL); +- +- kfsb->file_monitor = g_file_monitor (kfsb->file, 0, NULL, NULL); +- kfsb->dir_monitor = g_file_monitor (kfsb->dir, 0, NULL, NULL); +- +- kfsb->prefix_len = strlen (root_path); +- kfsb->prefix = g_strdup (root_path); +- +- if (root_group) +- { +- kfsb->root_group_len = strlen (root_group); +- kfsb->root_group = g_strdup (root_group); +- } +- +- compute_checksum (kfsb->digest, NULL, 0); +- +- g_signal_connect (kfsb->file_monitor, "changed", +- G_CALLBACK (file_changed), kfsb); +- g_signal_connect (kfsb->dir_monitor, "changed", +- G_CALLBACK (dir_changed), kfsb); +- +- g_keyfile_settings_backend_keyfile_writable (kfsb); +- g_keyfile_settings_backend_keyfile_reload (kfsb); +- +- return G_SETTINGS_BACKEND (kfsb); ++ return G_SETTINGS_BACKEND (g_object_new (G_TYPE_KEYFILE_SETTINGS_BACKEND, ++ "filename", filename, ++ "root-path", root_path, ++ "root-group", root_group, ++ NULL)); + } +--- gio/gportalsupport.c.orig 2018-08-15 16:22:08 UTC ++++ gio/gportalsupport.c +@@ -23,6 +23,7 @@ + static gboolean flatpak_info_read; + static gboolean use_portal; + static gboolean network_available; ++static gboolean dconf_access; + + static void + read_flatpak_info (void) +@@ -40,11 +41,13 @@ read_flatpak_info (void) + + use_portal = TRUE; + network_available = FALSE; ++ dconf_access = FALSE; + + keyfile = g_key_file_new (); + if (g_key_file_load_from_file (keyfile, path, G_KEY_FILE_NONE, NULL)) + { + char **shared = NULL; ++ char *dconf_policy = NULL; + + shared = g_key_file_get_string_list (keyfile, "Context", "shared", NULL, NULL); + if (shared) +@@ -52,6 +55,14 @@ read_flatpak_info (void) + network_available = g_strv_contains ((const char * const *)shared, "network"); + g_strfreev (shared); + } ++ ++ dconf_policy = g_key_file_get_string (keyfile, "Session Bus Policy", "ca.desrt.dconf", NULL); ++ if (dconf_policy) ++ { ++ if (strcmp (dconf_policy, "talk") == 0) ++ dconf_access = TRUE; ++ g_free (dconf_policy); ++ } + } + + g_key_file_unref (keyfile); +@@ -64,6 +75,7 @@ read_flatpak_info (void) + if (var && var[0] == '1') + use_portal = TRUE; + network_available = TRUE; ++ dconf_access = TRUE; + } + } + +@@ -81,3 +93,9 @@ glib_network_available_in_sandbox (void) + return network_available; + } + ++gboolean ++glib_has_dconf_access_in_sandbox (void) ++{ ++ read_flatpak_info (); ++ return dconf_access; ++} +--- gio/gportalsupport.h.orig 2018-08-15 16:22:08 UTC ++++ gio/gportalsupport.h +@@ -24,6 +24,7 @@ G_BEGIN_DECLS + + gboolean glib_should_use_portal (void); + gboolean glib_network_available_in_sandbox (void); ++gboolean glib_has_dconf_access_in_sandbox (void); + + G_END_DECLS + +--- gio/gsettingsbackendinternal.h.orig 2018-08-15 16:22:08 UTC ++++ gio/gsettingsbackendinternal.h +@@ -87,6 +87,8 @@ GType g_null_settings_backend_get_ty + + GType g_memory_settings_backend_get_type (void); + ++GType g_keyfile_settings_backend_get_type (void); ++ + #ifdef HAVE_COCOA + GType g_nextstep_settings_backend_get_type (void); + #endif +--- gio/tests/gsettings.c.orig 2018-09-21 09:29:23 UTC ++++ gio/tests/gsettings.c +@@ -1716,6 +1716,23 @@ test_keyfile (void) + g_assert_cmpstr (str, ==, "howdy"); + g_free (str); + ++ /* Now check setting a string without quotes */ ++ called = FALSE; ++ g_signal_connect (settings, "changed::greeting", G_CALLBACK (key_changed_cb), &called); ++ ++ g_key_file_set_string (keyfile, "tests", "greeting", "he\"l🤗uń"); ++ g_free (data); ++ data = g_key_file_to_data (keyfile, &len, NULL); ++ g_file_set_contents ("keyfile/gsettings.store", data, len, &error); ++ g_assert_no_error (error); ++ while (!called) ++ g_main_context_iteration (NULL, FALSE); ++ g_signal_handlers_disconnect_by_func (settings, key_changed_cb, &called); ++ ++ str = g_settings_get_string (settings, "greeting"); ++ g_assert_cmpstr (str, ==, "he\"l🤗uń"); ++ g_free (str); ++ + g_settings_set (settings, "farewell", "s", "cheerio"); + + called = FALSE;