Added
Link Here
|
1 |
https://gitlab.gnome.org/GNOME/glib/-/merge_requests/450 |
2 |
https://gitlab.gnome.org/GNOME/glib/-/merge_requests/603 |
3 |
https://gitlab.gnome.org/GNOME/glib/-/merge_requests/974 |
4 |
|
5 |
--- gio/giomodule.c.orig 2018-09-21 09:29:23 UTC |
6 |
+++ gio/giomodule.c |
7 |
@@ -1136,6 +1136,7 @@ _g_io_modules_ensure_loaded (void) |
8 |
/* Initialize types from built-in "modules" */ |
9 |
g_type_ensure (g_null_settings_backend_get_type ()); |
10 |
g_type_ensure (g_memory_settings_backend_get_type ()); |
11 |
+ g_type_ensure (g_keyfile_settings_backend_get_type ()); |
12 |
#if defined(HAVE_INOTIFY_INIT1) |
13 |
g_type_ensure (g_inotify_file_monitor_get_type ()); |
14 |
#endif |
15 |
--- gio/gkeyfilesettingsbackend.c.orig 2018-08-15 16:22:08 UTC |
16 |
+++ gio/gkeyfilesettingsbackend.c |
17 |
@@ -21,14 +21,20 @@ |
18 |
|
19 |
#include "config.h" |
20 |
|
21 |
+#include <glib.h> |
22 |
+#include <glibintl.h> |
23 |
+ |
24 |
#include <stdio.h> |
25 |
#include <string.h> |
26 |
|
27 |
#include "gfile.h" |
28 |
#include "gfileinfo.h" |
29 |
+#include "gfileenumerator.h" |
30 |
#include "gfilemonitor.h" |
31 |
#include "gsimplepermission.h" |
32 |
-#include "gsettingsbackend.h" |
33 |
+#include "gsettingsbackendinternal.h" |
34 |
+#include "giomodule-priv.h" |
35 |
+#include "gportalsupport.h" |
36 |
|
37 |
|
38 |
#define G_TYPE_KEYFILE_SETTINGS_BACKEND (g_keyfile_settings_backend_get_type ()) |
39 |
@@ -41,6 +47,13 @@ |
40 |
|
41 |
typedef GSettingsBackendClass GKeyfileSettingsBackendClass; |
42 |
|
43 |
+typedef enum { |
44 |
+ PROP_FILENAME = 1, |
45 |
+ PROP_ROOT_PATH, |
46 |
+ PROP_ROOT_GROUP, |
47 |
+ PROP_DEFAULTS_DIR |
48 |
+} GKeyfileSettingsBackendProperty; |
49 |
+ |
50 |
typedef struct |
51 |
{ |
52 |
GSettingsBackend parent_instance; |
53 |
@@ -48,6 +61,9 @@ typedef struct |
54 |
GKeyFile *keyfile; |
55 |
GPermission *permission; |
56 |
gboolean writable; |
57 |
+ char *defaults_dir; |
58 |
+ GKeyFile *system_keyfile; |
59 |
+ GHashTable *system_locks; /* Used as a set, owning the strings it contains */ |
60 |
|
61 |
gchar *prefix; |
62 |
gint prefix_len; |
63 |
@@ -61,11 +77,19 @@ typedef struct |
64 |
GFileMonitor *dir_monitor; |
65 |
} GKeyfileSettingsBackend; |
66 |
|
67 |
-static GType g_keyfile_settings_backend_get_type (void); |
68 |
-G_DEFINE_TYPE (GKeyfileSettingsBackend, |
69 |
- g_keyfile_settings_backend, |
70 |
- G_TYPE_SETTINGS_BACKEND) |
71 |
+#ifdef G_OS_WIN32 |
72 |
+#define EXTENSION_PRIORITY 10 |
73 |
+#else |
74 |
+#define EXTENSION_PRIORITY (glib_should_use_portal () ? 110 : 10) |
75 |
+#endif |
76 |
|
77 |
+G_DEFINE_TYPE_WITH_CODE (GKeyfileSettingsBackend, |
78 |
+ g_keyfile_settings_backend, |
79 |
+ G_TYPE_SETTINGS_BACKEND, |
80 |
+ _g_io_modules_ensure_extension_points_registered (); |
81 |
+ g_io_extension_point_implement (G_SETTINGS_BACKEND_EXTENSION_POINT_NAME, |
82 |
+ g_define_type_id, "keyfile", EXTENSION_PRIORITY)) |
83 |
+ |
84 |
static void |
85 |
compute_checksum (guint8 *digest, |
86 |
gconstpointer contents, |
87 |
@@ -184,17 +208,47 @@ get_from_keyfile (GKeyfileSettingsBackend *kfsb, |
88 |
if (convert_path (kfsb, key, &group, &name)) |
89 |
{ |
90 |
gchar *str; |
91 |
+ gchar *sysstr; |
92 |
|
93 |
g_assert (*name); |
94 |
|
95 |
+ sysstr = g_key_file_get_value (kfsb->system_keyfile, group, name, NULL); |
96 |
str = g_key_file_get_value (kfsb->keyfile, group, name, NULL); |
97 |
+ if (sysstr && |
98 |
+ (g_hash_table_contains (kfsb->system_locks, key) || |
99 |
+ str == NULL)) |
100 |
+ { |
101 |
+ g_free (str); |
102 |
+ str = g_steal_pointer (&sysstr); |
103 |
+ } |
104 |
|
105 |
if (str) |
106 |
{ |
107 |
return_value = g_variant_parse (type, str, NULL, NULL, NULL); |
108 |
+ if (return_value == NULL && |
109 |
+ g_variant_type_equal (type, G_VARIANT_TYPE_STRING) && |
110 |
+ str[0] != '\"') |
111 |
+ { |
112 |
+ GString *s = g_string_sized_new (strlen (str) + 2); |
113 |
+ char *p = str; |
114 |
+ |
115 |
+ g_string_append_c (s, '\"'); |
116 |
+ while (*p) |
117 |
+ { |
118 |
+ if (*p == '\"') |
119 |
+ g_string_append_c (s, '\\'); |
120 |
+ g_string_append_c (s, *p); |
121 |
+ p++; |
122 |
+ } |
123 |
+ g_string_append_c (s, '\"'); |
124 |
+ return_value = g_variant_parse (type, s->str, NULL, NULL, NULL); |
125 |
+ g_string_free (s, TRUE); |
126 |
+ } |
127 |
g_free (str); |
128 |
} |
129 |
|
130 |
+ g_free (sysstr); |
131 |
+ |
132 |
g_free (group); |
133 |
g_free (name); |
134 |
} |
135 |
@@ -209,6 +263,9 @@ set_to_keyfile (GKeyfileSettingsBackend *kfsb, |
136 |
{ |
137 |
gchar *group, *name; |
138 |
|
139 |
+ if (g_hash_table_contains (kfsb->system_locks, key)) |
140 |
+ return FALSE; |
141 |
+ |
142 |
if (convert_path (kfsb, key, &group, &name)) |
143 |
{ |
144 |
if (value) |
145 |
@@ -287,7 +344,8 @@ g_keyfile_settings_backend_check_one (gpointer key, |
146 |
{ |
147 |
WriteManyData *data = user_data; |
148 |
|
149 |
- return data->failed = !path_is_valid (data->kfsb, key); |
150 |
+ return data->failed = g_hash_table_contains (data->kfsb->system_locks, key) || |
151 |
+ !path_is_valid (data->kfsb, key); |
152 |
} |
153 |
|
154 |
static gboolean |
155 |
@@ -355,7 +413,9 @@ g_keyfile_settings_backend_get_writable (GSettingsBack |
156 |
{ |
157 |
GKeyfileSettingsBackend *kfsb = G_KEYFILE_SETTINGS_BACKEND (backend); |
158 |
|
159 |
- return kfsb->writable && path_is_valid (kfsb, name); |
160 |
+ return kfsb->writable && |
161 |
+ !g_hash_table_contains (kfsb->system_locks, name) && |
162 |
+ path_is_valid (kfsb, name); |
163 |
} |
164 |
|
165 |
static GPermission * |
166 |
@@ -501,6 +561,9 @@ g_keyfile_settings_backend_finalize (GObject *object) |
167 |
|
168 |
g_key_file_free (kfsb->keyfile); |
169 |
g_object_unref (kfsb->permission); |
170 |
+ g_key_file_unref (kfsb->system_keyfile); |
171 |
+ g_hash_table_unref (kfsb->system_locks); |
172 |
+ g_free (kfsb->defaults_dir); |
173 |
|
174 |
g_file_monitor_cancel (kfsb->file_monitor); |
175 |
g_object_unref (kfsb->file_monitor); |
176 |
@@ -523,25 +586,6 @@ g_keyfile_settings_backend_init (GKeyfileSettingsBacke |
177 |
} |
178 |
|
179 |
static void |
180 |
-g_keyfile_settings_backend_class_init (GKeyfileSettingsBackendClass *class) |
181 |
-{ |
182 |
- GObjectClass *object_class = G_OBJECT_CLASS (class); |
183 |
- |
184 |
- object_class->finalize = g_keyfile_settings_backend_finalize; |
185 |
- |
186 |
- class->read = g_keyfile_settings_backend_read; |
187 |
- class->write = g_keyfile_settings_backend_write; |
188 |
- class->write_tree = g_keyfile_settings_backend_write_tree; |
189 |
- class->reset = g_keyfile_settings_backend_reset; |
190 |
- class->get_writable = g_keyfile_settings_backend_get_writable; |
191 |
- class->get_permission = g_keyfile_settings_backend_get_permission; |
192 |
- /* No need to implement subscribed/unsubscribe: the only point would be to |
193 |
- * stop monitoring the file when there's no GSettings anymore, which is no |
194 |
- * big win. |
195 |
- */ |
196 |
-} |
197 |
- |
198 |
-static void |
199 |
file_changed (GFileMonitor *monitor, |
200 |
GFile *file, |
201 |
GFile *other_file, |
202 |
@@ -567,6 +611,282 @@ dir_changed (GFileMonitor *monitor, |
203 |
g_keyfile_settings_backend_keyfile_writable (kfsb); |
204 |
} |
205 |
|
206 |
+static void |
207 |
+load_system_settings (GKeyfileSettingsBackend *kfsb) |
208 |
+{ |
209 |
+ GError *error = NULL; |
210 |
+ const char *dir = "/etc/glib-2.0/settings"; |
211 |
+ char *path; |
212 |
+ char *contents; |
213 |
+ |
214 |
+ kfsb->system_keyfile = g_key_file_new (); |
215 |
+ kfsb->system_locks = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); |
216 |
+ |
217 |
+ if (kfsb->defaults_dir) |
218 |
+ dir = kfsb->defaults_dir; |
219 |
+ |
220 |
+ path = g_build_filename (dir, "defaults", NULL); |
221 |
+ |
222 |
+ /* The defaults are in the same keyfile format that we use for the settings. |
223 |
+ * It can be produced from a dconf database using: dconf dump |
224 |
+ */ |
225 |
+ if (!g_key_file_load_from_file (kfsb->system_keyfile, path, G_KEY_FILE_NONE, &error)) |
226 |
+ { |
227 |
+ if (!g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT)) |
228 |
+ g_warning ("Failed to read %s: %s", path, error->message); |
229 |
+ g_clear_error (&error); |
230 |
+ } |
231 |
+ else |
232 |
+ g_debug ("Loading default settings from %s", path); |
233 |
+ |
234 |
+ g_free (path); |
235 |
+ |
236 |
+ path = g_build_filename (dir, "locks", NULL); |
237 |
+ |
238 |
+ /* The locks file is a text file containing a list paths to lock, one per line. |
239 |
+ * It can be produced from a dconf database using: dconf list-locks |
240 |
+ */ |
241 |
+ if (!g_file_get_contents (path, &contents, NULL, &error)) |
242 |
+ { |
243 |
+ if (!g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT)) |
244 |
+ g_warning ("Failed to read %s: %s", path, error->message); |
245 |
+ g_clear_error (&error); |
246 |
+ } |
247 |
+ else |
248 |
+ { |
249 |
+ char **lines; |
250 |
+ gsize i; |
251 |
+ |
252 |
+ g_debug ("Loading locks from %s", path); |
253 |
+ |
254 |
+ lines = g_strsplit (contents, "\n", 0); |
255 |
+ for (i = 0; lines[i]; i++) |
256 |
+ { |
257 |
+ char *line = lines[i]; |
258 |
+ if (line[0] == '#' || line[0] == '\0') |
259 |
+ { |
260 |
+ g_free (line); |
261 |
+ continue; |
262 |
+ } |
263 |
+ |
264 |
+ g_debug ("Locking key %s", line); |
265 |
+ g_hash_table_add (kfsb->system_locks, g_steal_pointer (&line)); |
266 |
+ } |
267 |
+ |
268 |
+ g_free (lines); |
269 |
+ } |
270 |
+ g_free (contents); |
271 |
+ |
272 |
+ g_free (path); |
273 |
+} |
274 |
+ |
275 |
+static void |
276 |
+g_keyfile_settings_backend_constructed (GObject *object) |
277 |
+{ |
278 |
+ GKeyfileSettingsBackend *kfsb = G_KEYFILE_SETTINGS_BACKEND (object); |
279 |
+ |
280 |
+ if (kfsb->file == NULL) |
281 |
+ { |
282 |
+ char *filename = g_build_filename (g_get_user_config_dir (), |
283 |
+ "glib-2.0", "settings", "keyfile", |
284 |
+ NULL); |
285 |
+ kfsb->file = g_file_new_for_path (filename); |
286 |
+ g_free (filename); |
287 |
+ } |
288 |
+ |
289 |
+ if (kfsb->prefix == NULL) |
290 |
+ { |
291 |
+ kfsb->prefix = g_strdup ("/"); |
292 |
+ kfsb->prefix_len = 1; |
293 |
+ } |
294 |
+ |
295 |
+ kfsb->keyfile = g_key_file_new (); |
296 |
+ kfsb->permission = g_simple_permission_new (TRUE); |
297 |
+ |
298 |
+ kfsb->dir = g_file_get_parent (kfsb->file); |
299 |
+ g_file_make_directory_with_parents (kfsb->dir, NULL, NULL); |
300 |
+ |
301 |
+ kfsb->file_monitor = g_file_monitor (kfsb->file, G_FILE_MONITOR_NONE, NULL, NULL); |
302 |
+ kfsb->dir_monitor = g_file_monitor (kfsb->dir, G_FILE_MONITOR_NONE, NULL, NULL); |
303 |
+ |
304 |
+ compute_checksum (kfsb->digest, NULL, 0); |
305 |
+ |
306 |
+ g_signal_connect (kfsb->file_monitor, "changed", |
307 |
+ G_CALLBACK (file_changed), kfsb); |
308 |
+ g_signal_connect (kfsb->dir_monitor, "changed", |
309 |
+ G_CALLBACK (dir_changed), kfsb); |
310 |
+ |
311 |
+ g_keyfile_settings_backend_keyfile_writable (kfsb); |
312 |
+ g_keyfile_settings_backend_keyfile_reload (kfsb); |
313 |
+ |
314 |
+ load_system_settings (kfsb); |
315 |
+} |
316 |
+ |
317 |
+static void |
318 |
+g_keyfile_settings_backend_set_property (GObject *object, |
319 |
+ guint prop_id, |
320 |
+ const GValue *value, |
321 |
+ GParamSpec *pspec) |
322 |
+{ |
323 |
+ GKeyfileSettingsBackend *kfsb = G_KEYFILE_SETTINGS_BACKEND (object); |
324 |
+ |
325 |
+ switch ((GKeyfileSettingsBackendProperty)prop_id) |
326 |
+ { |
327 |
+ case PROP_FILENAME: |
328 |
+ /* Construct only. */ |
329 |
+ g_assert (kfsb->file == NULL); |
330 |
+ kfsb->file = g_file_new_for_path (g_value_get_string (value)); |
331 |
+ break; |
332 |
+ |
333 |
+ case PROP_ROOT_PATH: |
334 |
+ /* Construct only. */ |
335 |
+ g_assert (kfsb->prefix == NULL); |
336 |
+ kfsb->prefix = g_value_dup_string (value); |
337 |
+ if (kfsb->prefix) |
338 |
+ kfsb->prefix_len = strlen (kfsb->prefix); |
339 |
+ break; |
340 |
+ |
341 |
+ case PROP_ROOT_GROUP: |
342 |
+ /* Construct only. */ |
343 |
+ g_assert (kfsb->root_group == NULL); |
344 |
+ kfsb->root_group = g_value_dup_string (value); |
345 |
+ if (kfsb->root_group) |
346 |
+ kfsb->root_group_len = strlen (kfsb->root_group); |
347 |
+ break; |
348 |
+ |
349 |
+ case PROP_DEFAULTS_DIR: |
350 |
+ /* Construct only. */ |
351 |
+ g_assert (kfsb->defaults_dir == NULL); |
352 |
+ kfsb->defaults_dir = g_value_dup_string (value); |
353 |
+ break; |
354 |
+ |
355 |
+ default: |
356 |
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); |
357 |
+ break; |
358 |
+ } |
359 |
+} |
360 |
+ |
361 |
+static void |
362 |
+g_keyfile_settings_backend_get_property (GObject *object, |
363 |
+ guint prop_id, |
364 |
+ GValue *value, |
365 |
+ GParamSpec *pspec) |
366 |
+{ |
367 |
+ GKeyfileSettingsBackend *kfsb = G_KEYFILE_SETTINGS_BACKEND (object); |
368 |
+ |
369 |
+ switch ((GKeyfileSettingsBackendProperty)prop_id) |
370 |
+ { |
371 |
+ case PROP_FILENAME: |
372 |
+ g_value_set_string (value, g_file_peek_path (kfsb->file)); |
373 |
+ break; |
374 |
+ |
375 |
+ case PROP_ROOT_PATH: |
376 |
+ g_value_set_string (value, kfsb->prefix); |
377 |
+ break; |
378 |
+ |
379 |
+ case PROP_ROOT_GROUP: |
380 |
+ g_value_set_string (value, kfsb->root_group); |
381 |
+ break; |
382 |
+ |
383 |
+ case PROP_DEFAULTS_DIR: |
384 |
+ g_value_set_string (value, kfsb->defaults_dir); |
385 |
+ break; |
386 |
+ |
387 |
+ default: |
388 |
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); |
389 |
+ break; |
390 |
+ } |
391 |
+} |
392 |
+ |
393 |
+static void |
394 |
+g_keyfile_settings_backend_class_init (GKeyfileSettingsBackendClass *class) |
395 |
+{ |
396 |
+ GObjectClass *object_class = G_OBJECT_CLASS (class); |
397 |
+ |
398 |
+ object_class->finalize = g_keyfile_settings_backend_finalize; |
399 |
+ object_class->constructed = g_keyfile_settings_backend_constructed; |
400 |
+ object_class->get_property = g_keyfile_settings_backend_get_property; |
401 |
+ object_class->set_property = g_keyfile_settings_backend_set_property; |
402 |
+ |
403 |
+ class->read = g_keyfile_settings_backend_read; |
404 |
+ class->write = g_keyfile_settings_backend_write; |
405 |
+ class->write_tree = g_keyfile_settings_backend_write_tree; |
406 |
+ class->reset = g_keyfile_settings_backend_reset; |
407 |
+ class->get_writable = g_keyfile_settings_backend_get_writable; |
408 |
+ class->get_permission = g_keyfile_settings_backend_get_permission; |
409 |
+ /* No need to implement subscribed/unsubscribe: the only point would be to |
410 |
+ * stop monitoring the file when there's no GSettings anymore, which is no |
411 |
+ * big win. |
412 |
+ */ |
413 |
+ |
414 |
+ /** |
415 |
+ * GKeyfileSettingsBackend:filename: |
416 |
+ * |
417 |
+ * The location where the settings are stored on disk. |
418 |
+ * |
419 |
+ * Defaults to `$XDG_CONFIG_HOME/glib-2.0/settings/keyfile`. |
420 |
+ */ |
421 |
+ g_object_class_install_property (object_class, |
422 |
+ PROP_FILENAME, |
423 |
+ g_param_spec_string ("filename", |
424 |
+ P_("Filename"), |
425 |
+ P_("The filename"), |
426 |
+ NULL, |
427 |
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | |
428 |
+ G_PARAM_STATIC_STRINGS)); |
429 |
+ |
430 |
+ /** |
431 |
+ * GKeyfileSettingsBackend:root-path: |
432 |
+ * |
433 |
+ * All settings read to or written from the backend must fall under the |
434 |
+ * path given in @root_path (which must start and end with a slash and |
435 |
+ * not contain two consecutive slashes). @root_path may be "/". |
436 |
+ * |
437 |
+ * Defaults to "/". |
438 |
+ */ |
439 |
+ g_object_class_install_property (object_class, |
440 |
+ PROP_ROOT_PATH, |
441 |
+ g_param_spec_string ("root-path", |
442 |
+ P_("Root path"), |
443 |
+ P_("The root path"), |
444 |
+ NULL, |
445 |
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | |
446 |
+ G_PARAM_STATIC_STRINGS)); |
447 |
+ |
448 |
+ /** |
449 |
+ * GKeyfileSettingsBackend:root-group: |
450 |
+ * |
451 |
+ * If @root_group is non-%NULL then it specifies the name of the keyfile |
452 |
+ * group used for keys that are written directly below the root path. |
453 |
+ * |
454 |
+ * Defaults to NULL. |
455 |
+ */ |
456 |
+ g_object_class_install_property (object_class, |
457 |
+ PROP_ROOT_GROUP, |
458 |
+ g_param_spec_string ("root-group", |
459 |
+ P_("Root group"), |
460 |
+ P_("The root group"), |
461 |
+ NULL, |
462 |
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | |
463 |
+ G_PARAM_STATIC_STRINGS)); |
464 |
+ |
465 |
+ /** |
466 |
+ * GKeyfileSettingsBackend:default-dir: |
467 |
+ * |
468 |
+ * The directory where the system defaults and locks are located. |
469 |
+ * |
470 |
+ * Defaults to `/etc/glib-2.0/settings`. |
471 |
+ */ |
472 |
+ g_object_class_install_property (object_class, |
473 |
+ PROP_DEFAULTS_DIR, |
474 |
+ g_param_spec_string ("defaults-dir", |
475 |
+ P_("Default dir"), |
476 |
+ P_("Defaults dir"), |
477 |
+ NULL, |
478 |
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | |
479 |
+ G_PARAM_STATIC_STRINGS)); |
480 |
+} |
481 |
+ |
482 |
/** |
483 |
* g_keyfile_settings_backend_new: |
484 |
* @filename: the filename of the keyfile |
485 |
@@ -619,6 +939,11 @@ dir_changed (GFileMonitor *monitor, |
486 |
* characters in your path names or '=' in your key names you may be in |
487 |
* trouble. |
488 |
* |
489 |
+ * The backend reads default values from a keyfile called `defaults` in |
490 |
+ * the directory specified by the #GKeyfileSettingsBackend:defaults-dir property, |
491 |
+ * and a list of locked keys from a text file with the name `locks` in |
492 |
+ * the same location. |
493 |
+ * |
494 |
* Returns: (transfer full): a keyfile-backed #GSettingsBackend |
495 |
**/ |
496 |
GSettingsBackend * |
497 |
@@ -626,43 +951,15 @@ g_keyfile_settings_backend_new (const gchar *filename, |
498 |
const gchar *root_path, |
499 |
const gchar *root_group) |
500 |
{ |
501 |
- GKeyfileSettingsBackend *kfsb; |
502 |
- |
503 |
g_return_val_if_fail (filename != NULL, NULL); |
504 |
g_return_val_if_fail (root_path != NULL, NULL); |
505 |
g_return_val_if_fail (g_str_has_prefix (root_path, "/"), NULL); |
506 |
g_return_val_if_fail (g_str_has_suffix (root_path, "/"), NULL); |
507 |
g_return_val_if_fail (strstr (root_path, "//") == NULL, NULL); |
508 |
|
509 |
- kfsb = g_object_new (G_TYPE_KEYFILE_SETTINGS_BACKEND, NULL); |
510 |
- kfsb->keyfile = g_key_file_new (); |
511 |
- kfsb->permission = g_simple_permission_new (TRUE); |
512 |
- |
513 |
- kfsb->file = g_file_new_for_path (filename); |
514 |
- kfsb->dir = g_file_get_parent (kfsb->file); |
515 |
- g_file_make_directory_with_parents (kfsb->dir, NULL, NULL); |
516 |
- |
517 |
- kfsb->file_monitor = g_file_monitor (kfsb->file, 0, NULL, NULL); |
518 |
- kfsb->dir_monitor = g_file_monitor (kfsb->dir, 0, NULL, NULL); |
519 |
- |
520 |
- kfsb->prefix_len = strlen (root_path); |
521 |
- kfsb->prefix = g_strdup (root_path); |
522 |
- |
523 |
- if (root_group) |
524 |
- { |
525 |
- kfsb->root_group_len = strlen (root_group); |
526 |
- kfsb->root_group = g_strdup (root_group); |
527 |
- } |
528 |
- |
529 |
- compute_checksum (kfsb->digest, NULL, 0); |
530 |
- |
531 |
- g_signal_connect (kfsb->file_monitor, "changed", |
532 |
- G_CALLBACK (file_changed), kfsb); |
533 |
- g_signal_connect (kfsb->dir_monitor, "changed", |
534 |
- G_CALLBACK (dir_changed), kfsb); |
535 |
- |
536 |
- g_keyfile_settings_backend_keyfile_writable (kfsb); |
537 |
- g_keyfile_settings_backend_keyfile_reload (kfsb); |
538 |
- |
539 |
- return G_SETTINGS_BACKEND (kfsb); |
540 |
+ return G_SETTINGS_BACKEND (g_object_new (G_TYPE_KEYFILE_SETTINGS_BACKEND, |
541 |
+ "filename", filename, |
542 |
+ "root-path", root_path, |
543 |
+ "root-group", root_group, |
544 |
+ NULL)); |
545 |
} |
546 |
--- gio/gsettingsbackendinternal.h.orig 2018-08-15 16:22:08 UTC |
547 |
+++ gio/gsettingsbackendinternal.h |
548 |
@@ -87,6 +87,8 @@ GType g_null_settings_backend_get_ty |
549 |
|
550 |
GType g_memory_settings_backend_get_type (void); |
551 |
|
552 |
+GType g_keyfile_settings_backend_get_type (void); |
553 |
+ |
554 |
#ifdef HAVE_COCOA |
555 |
GType g_nextstep_settings_backend_get_type (void); |
556 |
#endif |
557 |
--- gio/tests/gsettings.c.orig 2018-09-21 09:29:23 UTC |
558 |
+++ gio/tests/gsettings.c |
559 |
@@ -1716,6 +1716,23 @@ test_keyfile (void) |
560 |
g_assert_cmpstr (str, ==, "howdy"); |
561 |
g_free (str); |
562 |
|
563 |
+ /* Now check setting a string without quotes */ |
564 |
+ called = FALSE; |
565 |
+ g_signal_connect (settings, "changed::greeting", G_CALLBACK (key_changed_cb), &called); |
566 |
+ |
567 |
+ g_key_file_set_string (keyfile, "tests", "greeting", "he\"l🤗uń"); |
568 |
+ g_free (data); |
569 |
+ data = g_key_file_to_data (keyfile, &len, NULL); |
570 |
+ g_file_set_contents ("keyfile/gsettings.store", data, len, &error); |
571 |
+ g_assert_no_error (error); |
572 |
+ while (!called) |
573 |
+ g_main_context_iteration (NULL, FALSE); |
574 |
+ g_signal_handlers_disconnect_by_func (settings, key_changed_cb, &called); |
575 |
+ |
576 |
+ str = g_settings_get_string (settings, "greeting"); |
577 |
+ g_assert_cmpstr (str, ==, "he\"l🤗uń"); |
578 |
+ g_free (str); |
579 |
+ |
580 |
g_settings_set (settings, "farewell", "s", "cheerio"); |
581 |
|
582 |
called = FALSE; |