summaryrefslogtreecommitdiff
path: root/service
diff options
context:
space:
mode:
authorRyan Lortie <desrt@desrt.ca>2013-01-11 18:16:52 -0500
committerRyan Lortie <desrt@desrt.ca>2013-01-11 18:16:52 -0500
commit1f97cd016106267c722be637310b3a9c774996ba (patch)
tree10717cc76d3f87edc81b06f4ea65943f5e62028d /service
parente4f5ebcf2eaacb70e3b4508b24ae259f9f0098bd (diff)
downloaddconf-1f97cd016106267c722be637310b3a9c774996ba.tar.gz
keyfile: many improvements
Store the keyfile in ~/.config/dconf/$(name).txt instead of ~/.config/dconf-keyfile/name. Adjust the base writer not to pick up filenames with dots in them (so we will skip the .txt files the keyfile writer puts into the same directory). Add file change monitoring and reload the file if anyone changes it. Fix a crasher on the first write of a file if it does not yet exist. Add proper finalize handling.
Diffstat (limited to 'service')
-rw-r--r--service/dconf-keyfile-writer.c94
-rw-r--r--service/dconf-writer.c5
2 files changed, 86 insertions, 13 deletions
diff --git a/service/dconf-keyfile-writer.c b/service/dconf-keyfile-writer.c
index d65d25d..2845c65 100644
--- a/service/dconf-keyfile-writer.c
+++ b/service/dconf-keyfile-writer.c
@@ -28,10 +28,12 @@ typedef DConfWriterClass DConfKeyfileWriterClass;
typedef struct
{
- DConfWriter parent_instance;
- gchar *filename;
- gchar *contents;
- GKeyFile *keyfile;
+ DConfWriter parent_instance;
+ gchar *filename;
+ GFileMonitor *monitor;
+ guint scheduled_update;
+ gchar *contents;
+ GKeyFile *keyfile;
} DConfKeyfileWriter;
G_DEFINE_TYPE (DConfKeyfileWriter, dconf_keyfile_writer, DCONF_TYPE_WRITER)
@@ -122,6 +124,25 @@ dconf_keyfile_writer_list (GHashTable *set)
{
}
+static gboolean dconf_keyfile_update (gpointer user_data);
+
+static void
+dconf_keyfile_changed (GFileMonitor *monitor,
+ GFile *file,
+ GFile *other_file,
+ GFileMonitorEvent event_type,
+ gpointer user_data)
+{
+ DConfKeyfileWriter *kfw = user_data;
+
+ if (event_type == G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT ||
+ event_type == G_FILE_MONITOR_EVENT_CREATED)
+ {
+ if (!kfw->scheduled_update)
+ kfw->scheduled_update = g_idle_add (dconf_keyfile_update, kfw);
+ }
+}
+
static gboolean
dconf_keyfile_writer_begin (DConfWriter *writer,
GError **error)
@@ -132,8 +153,20 @@ dconf_keyfile_writer_begin (DConfWriter *writer,
DConfChangeset *changes;
if (kfw->filename == NULL)
- kfw->filename = g_build_filename (g_get_user_config_dir (), "dconf-keyfile",
- dconf_writer_get_name (writer), NULL);
+ {
+ gchar *filename_base;
+ GFile *file;
+
+ filename_base = g_build_filename (g_get_user_config_dir (), "dconf", dconf_writer_get_name (writer), NULL);
+ kfw->filename = g_strconcat (filename_base, ".txt", NULL);
+ g_free (filename_base);
+
+ file = g_file_new_for_path (kfw->filename);
+ kfw->monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, NULL);
+ g_object_unref (file);
+
+ g_signal_connect (kfw->monitor, "changed", G_CALLBACK (dconf_keyfile_changed), kfw);
+ }
g_clear_pointer (&kfw->contents, g_free);
@@ -150,12 +183,15 @@ dconf_keyfile_writer_begin (DConfWriter *writer,
kfw->keyfile = g_key_file_new ();
- if (!g_key_file_load_from_data (kfw->keyfile, kfw->contents, -1, G_KEY_FILE_KEEP_COMMENTS, &local_error))
+ if (kfw->contents)
{
- g_clear_pointer (&kfw->keyfile, g_key_file_free);
- g_clear_pointer (&kfw->contents, g_free);
- g_propagate_error (error, local_error);
- return FALSE;
+ if (!g_key_file_load_from_data (kfw->keyfile, kfw->contents, -1, G_KEY_FILE_KEEP_COMMENTS, &local_error))
+ {
+ g_clear_pointer (&kfw->keyfile, g_key_file_free);
+ g_clear_pointer (&kfw->contents, g_free);
+ g_propagate_error (error, local_error);
+ return FALSE;
+ }
}
if (!DCONF_WRITER_CLASS (dconf_keyfile_writer_parent_class)->begin (writer, error))
@@ -307,7 +343,7 @@ dconf_keyfile_writer_commit (DConfWriter *writer,
data = g_key_file_to_data (kfw->keyfile, &size, NULL);
/* don't write it again if nothing changed */
- if (!g_str_equal (kfw->contents, data))
+ if (!kfw->contents || !g_str_equal (kfw->contents, data))
{
if (!g_file_set_contents (kfw->filename, data, size, error))
{
@@ -360,6 +396,36 @@ dconf_keyfile_writer_end (DConfWriter *writer)
g_clear_pointer (&kfw->contents, g_free);
}
+static gboolean
+dconf_keyfile_update (gpointer user_data)
+{
+ DConfKeyfileWriter *kfw = user_data;
+
+ if (dconf_keyfile_writer_begin (DCONF_WRITER (kfw), NULL))
+ {
+ dconf_keyfile_writer_commit (DCONF_WRITER (kfw), NULL);
+ dconf_keyfile_writer_end (DCONF_WRITER (kfw));
+ }
+
+ kfw->scheduled_update = 0;
+
+ return G_SOURCE_REMOVE;
+}
+
+static void
+dconf_keyfile_writer_finalize (GObject *object)
+{
+ DConfKeyfileWriter *kfw = (DConfKeyfileWriter *) object;
+
+ if (kfw->scheduled_update)
+ g_source_remove (kfw->scheduled_update);
+
+ g_clear_object (&kfw->monitor);
+ g_free (kfw->filename);
+
+ G_OBJECT_CLASS (dconf_keyfile_writer_parent_class)->finalize (object);
+}
+
static void
dconf_keyfile_writer_init (DConfKeyfileWriter *writer)
{
@@ -369,6 +435,10 @@ dconf_keyfile_writer_init (DConfKeyfileWriter *writer)
static void
dconf_keyfile_writer_class_init (DConfWriterClass *class)
{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+ object_class->finalize = dconf_keyfile_writer_finalize;
+
class->list = dconf_keyfile_writer_list;
class->begin = dconf_keyfile_writer_begin;
class->change = dconf_keyfile_writer_change;
diff --git a/service/dconf-writer.c b/service/dconf-writer.c
index 7f9f2a5..15801b5 100644
--- a/service/dconf-writer.c
+++ b/service/dconf-writer.c
@@ -75,7 +75,10 @@ dconf_writer_real_list (GHashTable *set)
return;
while ((name = g_dir_read_name (dir)))
- g_hash_table_add (set, g_strdup (name));
+ {
+ if (!strchr (name, '.'))
+ g_hash_table_add (set, g_strdup (name));
+ }
g_dir_close (dir);
}