mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-02-24 11:12:11 +01:00
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).
This commit is contained in:
parent
05479beac9
commit
ddc12323d1
@ -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));
|
||||
|
||||
|
@ -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__ */
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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()
|
||||
@ -807,6 +817,14 @@ g_settings_backend_subscribe (GSettingsBackend *backend,
|
||||
->subscribe (backend, name);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
@ -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]);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user