summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyan Lortie <desrt@desrt.ca>2011-12-29 04:58:20 -0500
committerRyan Lortie <desrt@desrt.ca>2012-07-29 10:40:16 +0200
commitddc12323d1e65a97b8dfdf27f9798e69f85491a1 (patch)
tree0fdbf2fe033999bdcb51f71193c02c5cb8f06d5f
parent05479beac97d9e9d8780763b789ad8a2091a883d (diff)
downloadglib-ddc12323d1e65a97b8dfdf27f9798e69f85491a1.tar.gz
GSettingsBackend: move 'has-unapplied' logic here
Add GSettingsBackend API to allow any backend to have a 'has-unapplied' property. Remove the 'owner' hackery that was used for notifying of changes to 'has-unapplied' and just use normal GObject notify (and wire into that from the frontend).
-rw-r--r--gio/gdelayedsettingsbackend.c93
-rw-r--r--gio/gdelayedsettingsbackend.h6
-rw-r--r--gio/gio.symbols1
-rw-r--r--gio/gsettings.c31
-rw-r--r--gio/gsettingsbackend.c42
-rw-r--r--gio/gsettingsbackend.h2
-rw-r--r--gio/gsettingsbackendinternal.h2
7 files changed, 80 insertions, 97 deletions
diff --git a/gio/gdelayedsettingsbackend.c b/gio/gdelayedsettingsbackend.c
index a891fe1b3..e45da36af 100644
--- a/gio/gdelayedsettingsbackend.c
+++ b/gio/gdelayedsettingsbackend.c
@@ -32,48 +32,12 @@ struct _GDelayedSettingsBackendPrivate
GSettingsBackend *backend;
GMutex lock;
GTree *delayed;
-
- GMainContext *owner_context;
- gpointer owner;
};
G_DEFINE_TYPE (GDelayedSettingsBackend,
g_delayed_settings_backend,
G_TYPE_SETTINGS_BACKEND)
-static gboolean
-invoke_notify_unapplied (gpointer data)
-{
- g_object_notify (data, "has-unapplied");
- g_object_unref (data);
-
- return FALSE;
-}
-
-static void
-g_delayed_settings_backend_notify_unapplied (GDelayedSettingsBackend *delayed)
-{
- GMainContext *target_context;
- GObject *target;
-
- g_mutex_lock (&delayed->priv->lock);
- if (delayed->priv->owner)
- {
- target_context = delayed->priv->owner_context;
- target = g_object_ref (delayed->priv->owner);
- }
- else
- {
- target_context = NULL;
- target = NULL;
- }
- g_mutex_unlock (&delayed->priv->lock);
-
- if (target != NULL)
- g_main_context_invoke (target_context, invoke_notify_unapplied, target);
-}
-
-
static GVariant *
g_delayed_settings_backend_read (GSettingsBackend *backend,
const gchar *key,
@@ -111,18 +75,13 @@ g_delayed_settings_backend_write (GSettingsBackend *backend,
gpointer origin_tag)
{
GDelayedSettingsBackend *delayed = G_DELAYED_SETTINGS_BACKEND (backend);
- gboolean was_empty;
g_mutex_lock (&delayed->priv->lock);
- was_empty = g_tree_nnodes (delayed->priv->delayed) == 0;
- g_tree_insert (delayed->priv->delayed, g_strdup (key),
- g_variant_ref_sink (value));
+ g_tree_insert (delayed->priv->delayed, g_strdup (key), g_variant_ref_sink (value));
g_mutex_unlock (&delayed->priv->lock);
g_settings_backend_changed (backend, key, origin_tag);
-
- if (was_empty)
- g_delayed_settings_backend_notify_unapplied (delayed);
+ g_settings_backend_set_has_unapplied (backend, TRUE);
return TRUE;
}
@@ -142,18 +101,13 @@ g_delayed_settings_backend_write_tree (GSettingsBackend *backend,
gpointer origin_tag)
{
GDelayedSettingsBackend *delayed = G_DELAYED_SETTINGS_BACKEND (backend);
- gboolean was_empty;
g_mutex_lock (&delayed->priv->lock);
- was_empty = g_tree_nnodes (delayed->priv->delayed) == 0;
-
g_tree_foreach (tree, add_to_tree, delayed->priv->delayed);
g_mutex_unlock (&delayed->priv->lock);
g_settings_backend_changed_tree (backend, tree, origin_tag);
-
- if (was_empty)
- g_delayed_settings_backend_notify_unapplied (delayed);
+ g_settings_backend_set_has_unapplied (backend, TRUE);
return TRUE;
}
@@ -173,15 +127,13 @@ g_delayed_settings_backend_reset (GSettingsBackend *backend,
gpointer origin_tag)
{
GDelayedSettingsBackend *delayed = G_DELAYED_SETTINGS_BACKEND (backend);
- gboolean was_empty;
g_mutex_lock (&delayed->priv->lock);
- was_empty = g_tree_nnodes (delayed->priv->delayed) == 0;
g_tree_insert (delayed->priv->delayed, g_strdup (key), NULL);
g_mutex_unlock (&delayed->priv->lock);
- if (was_empty)
- g_delayed_settings_backend_notify_unapplied (delayed);
+ g_settings_backend_changed (backend, key, origin_tag);
+ g_settings_backend_set_has_unapplied (backend, TRUE);
}
static void
@@ -213,14 +165,6 @@ g_delayed_settings_backend_get_permission (GSettingsBackend *backend,
/* method calls */
-gboolean
-g_delayed_settings_backend_get_has_unapplied (GDelayedSettingsBackend *delayed)
-{
- /* we don't need to lock for this... */
-
- return g_tree_nnodes (delayed->priv->delayed) > 0;
-}
-
void
g_delayed_settings_backend_apply (GDelayedSettingsBackend *delayed)
{
@@ -242,7 +186,7 @@ g_delayed_settings_backend_apply (GDelayedSettingsBackend *delayed)
g_tree_unref (tmp);
- g_delayed_settings_backend_notify_unapplied (delayed);
+ g_settings_backend_set_has_unapplied (G_SETTINGS_BACKEND (delayed), FALSE);
}
}
@@ -260,7 +204,7 @@ g_delayed_settings_backend_revert (GDelayedSettingsBackend *delayed)
g_settings_backend_changed_tree (G_SETTINGS_BACKEND (delayed), tmp, NULL);
g_tree_unref (tmp);
- g_delayed_settings_backend_notify_unapplied (delayed);
+ g_settings_backend_set_has_unapplied (G_SETTINGS_BACKEND (delayed), FALSE);
}
}
@@ -283,9 +227,6 @@ g_delayed_settings_backend_finalize (GObject *object)
g_object_unref (delayed->priv->backend);
g_tree_unref (delayed->priv->delayed);
- /* if our owner is still alive, why are we finalizing? */
- g_assert (delayed->priv->owner == NULL);
-
G_OBJECT_CLASS (g_delayed_settings_backend_parent_class)
->finalize (object);
}
@@ -321,31 +262,13 @@ g_delayed_settings_backend_init (GDelayedSettingsBackend *delayed)
g_mutex_init (&delayed->priv->lock);
}
-static void
-g_delayed_settings_backend_disown (gpointer data,
- GObject *where_the_object_was)
-{
- GDelayedSettingsBackend *delayed = data;
-
- g_mutex_lock (&delayed->priv->lock);
- delayed->priv->owner_context = NULL;
- delayed->priv->owner = NULL;
- g_mutex_unlock (&delayed->priv->lock);
-}
-
GDelayedSettingsBackend *
-g_delayed_settings_backend_new (GSettingsBackend *backend,
- gpointer owner,
- GMainContext *owner_context)
+g_delayed_settings_backend_new (GSettingsBackend *backend)
{
GDelayedSettingsBackend *delayed;
delayed = g_object_new (G_TYPE_DELAYED_SETTINGS_BACKEND, NULL);
delayed->priv->backend = g_object_ref (backend);
- delayed->priv->owner_context = owner_context;
- delayed->priv->owner = owner;
-
- g_object_weak_ref (owner, g_delayed_settings_backend_disown, delayed);
g_settings_backend_watch (delayed->priv->backend, g_delayed_settings_got_event, G_OBJECT (delayed));
diff --git a/gio/gdelayedsettingsbackend.h b/gio/gdelayedsettingsbackend.h
index 34ec3efb7..b11cae641 100644
--- a/gio/gdelayedsettingsbackend.h
+++ b/gio/gdelayedsettingsbackend.h
@@ -59,14 +59,10 @@ struct _GDelayedSettingsBackend
G_GNUC_INTERNAL
GType g_delayed_settings_backend_get_type (void);
G_GNUC_INTERNAL
-GDelayedSettingsBackend * g_delayed_settings_backend_new (GSettingsBackend *backend,
- gpointer owner,
- GMainContext *owner_context);
+GDelayedSettingsBackend * g_delayed_settings_backend_new (GSettingsBackend *backend);
G_GNUC_INTERNAL
void g_delayed_settings_backend_revert (GDelayedSettingsBackend *delayed);
G_GNUC_INTERNAL
void g_delayed_settings_backend_apply (GDelayedSettingsBackend *delayed);
-G_GNUC_INTERNAL
-gboolean g_delayed_settings_backend_get_has_unapplied (GDelayedSettingsBackend *delayed);
#endif /* __G_DELAYED_SETTINGS_BACKEND_H__ */
diff --git a/gio/gio.symbols b/gio/gio.symbols
index 3c7cc0ca2..9907f04e6 100644
--- a/gio/gio.symbols
+++ b/gio/gio.symbols
@@ -1133,6 +1133,7 @@ g_file_descriptor_based_get_fd
#endif
g_settings_backend_get_type
g_settings_backend_report_event
+g_settings_backend_set_has_unapplied
g_settings_backend_changed
g_settings_backend_flatten_tree
g_settings_backend_keys_changed
diff --git a/gio/gsettings.c b/gio/gsettings.c
index 4c828b3b4..9f1f1f330 100644
--- a/gio/gsettings.c
+++ b/gio/gsettings.c
@@ -514,6 +514,25 @@ g_settings_got_event (GObject *target,
}
}
+static gboolean
+g_settings_emit_has_unapplied_notify (gpointer data)
+{
+ g_object_notify (data, "has-unapplied");
+ g_object_unref (data);
+
+ return G_SOURCE_REMOVE;
+}
+
+static void
+g_settings_got_has_unapplied_notify (GSettingsBackend *backend,
+ GParamSpec *pspec,
+ gpointer user_data)
+{
+ GSettings *settings = G_SETTINGS (user_data);
+
+ g_main_context_invoke (settings->priv->main_context, g_settings_emit_has_unapplied_notify, g_object_ref (settings));
+}
+
/* Properties, Construction, Destruction {{{1 */
static void
g_settings_set_property (GObject *object,
@@ -658,6 +677,7 @@ g_settings_finalize (GObject *object)
{
GSettings *settings = G_SETTINGS (object);
+ g_signal_handlers_disconnect_by_func (settings->priv->backend, g_settings_got_has_unapplied_notify, settings);
g_settings_backend_unsubscribe (settings->priv->backend,
settings->priv->path);
g_main_context_unref (settings->priv->main_context);
@@ -1966,16 +1986,15 @@ g_settings_delay (GSettings *settings)
if (settings->priv->delayed)
return;
- settings->priv->delayed =
- g_delayed_settings_backend_new (settings->priv->backend,
- settings,
- settings->priv->main_context);
+ settings->priv->delayed = g_delayed_settings_backend_new (settings->priv->backend);
g_settings_backend_unwatch (settings->priv->backend, G_OBJECT (settings));
g_object_unref (settings->priv->backend);
settings->priv->backend = G_SETTINGS_BACKEND (settings->priv->delayed);
g_settings_backend_watch (settings->priv->backend, g_settings_got_event, G_OBJECT (settings));
+ g_signal_connect (settings->priv->delayed, "notify::has-unapplied",
+ G_CALLBACK (g_settings_got_has_unapplied_notify), settings);
g_object_notify (G_OBJECT (settings), "delay-apply");
}
@@ -2039,9 +2058,7 @@ g_settings_get_has_unapplied (GSettings *settings)
{
g_return_val_if_fail (G_IS_SETTINGS (settings), FALSE);
- return settings->priv->delayed &&
- g_delayed_settings_backend_get_has_unapplied (
- G_DELAYED_SETTINGS_BACKEND (settings->priv->backend));
+ return g_settings_backend_get_has_unapplied (settings->priv->backend);
}
/* Extra API (reset, sync, get_child, is_writable, list_*, ranges) {{{1 */
diff --git a/gio/gsettingsbackend.c b/gio/gsettingsbackend.c
index 7d4eb055c..f8d1eb752 100644
--- a/gio/gsettingsbackend.c
+++ b/gio/gsettingsbackend.c
@@ -40,9 +40,19 @@ typedef struct _GSettingsBackendWatch GSettingsBackendWatch;
struct _GSettingsBackendPrivate
{
GSettingsBackendWatch *watches;
+ gboolean has_unapplied;
GMutex lock;
};
+enum
+{
+ PROP_0,
+ PROP_HAS_UNAPPLIED,
+ N_PROPS
+};
+
+static GParamSpec *g_settings_backend_pspecs[N_PROPS];
+
/* For g_settings_backend_sync_default(), we only want to actually do
* the sync if the backend already exists. This avoids us creating an
* entire GSettingsBackend in order to call a do-nothing sync()
@@ -808,6 +818,14 @@ g_settings_backend_subscribe (GSettingsBackend *backend,
}
static void
+g_settings_backend_get_property (GObject *object, guint prop_id,
+ GValue *value, GParamSpec *pspec)
+{
+ g_assert (prop_id == PROP_HAS_UNAPPLIED);
+ g_value_set_boolean (value, g_settings_backend_get_has_unapplied (G_SETTINGS_BACKEND (object)));
+}
+
+static void
g_settings_backend_finalize (GObject *object)
{
GSettingsBackend *backend = G_SETTINGS_BACKEND (object);
@@ -841,8 +859,14 @@ g_settings_backend_class_init (GSettingsBackendClass *class)
class->subscribe = ignore_subscription;
class->unsubscribe = ignore_subscription;
+ gobject_class->get_property = g_settings_backend_get_property;
gobject_class->finalize = g_settings_backend_finalize;
+ g_settings_backend_pspecs[PROP_HAS_UNAPPLIED] =
+ g_param_spec_boolean ("has-unapplied", "has unapplied", "TRUE if apply() is meaningful",
+ FALSE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_properties (gobject_class, N_PROPS, g_settings_backend_pspecs);
+
g_type_class_add_private (class, sizeof (GSettingsBackendPrivate));
}
@@ -954,3 +978,21 @@ g_settings_backend_sync_default (void)
class->sync (backend);
}
}
+
+gboolean
+g_settings_backend_get_has_unapplied (GSettingsBackend *backend)
+{
+ return backend->priv->has_unapplied;
+}
+
+void
+g_settings_backend_set_has_unapplied (GSettingsBackend *backend,
+ gboolean has_unapplied)
+{
+ if (has_unapplied != backend->priv->has_unapplied)
+ {
+ backend->priv->has_unapplied = has_unapplied;
+
+ g_object_notify_by_pspec (G_OBJECT (backend), g_settings_backend_pspecs[PROP_HAS_UNAPPLIED]);
+ }
+}
diff --git a/gio/gsettingsbackend.h b/gio/gsettingsbackend.h
index f75136fa3..b7f89e7ec 100644
--- a/gio/gsettingsbackend.h
+++ b/gio/gsettingsbackend.h
@@ -122,6 +122,8 @@ GType g_settings_backend_get_type (void);
void g_settings_backend_report_event (GSettingsBackend *backend,
const GSettingsEvent *event);
+void g_settings_backend_set_has_unapplied (GSettingsBackend *backend,
+ gboolean has_unapplied);
void g_settings_backend_changed (GSettingsBackend *backend,
const gchar *key,
gpointer origin_tag);
diff --git a/gio/gsettingsbackendinternal.h b/gio/gsettingsbackendinternal.h
index 3da1232f2..85494fff8 100644
--- a/gio/gsettingsbackendinternal.h
+++ b/gio/gsettingsbackendinternal.h
@@ -71,6 +71,8 @@ G_GNUC_INTERNAL
GPermission * g_settings_backend_get_permission (GSettingsBackend *backend,
const gchar *path);
G_GNUC_INTERNAL
+gboolean g_settings_backend_get_has_unapplied (GSettingsBackend *backend);
+G_GNUC_INTERNAL
void g_settings_backend_sync_default (void);
G_GNUC_INTERNAL