diff --git a/gio/glib-compile-schemas.c b/gio/glib-compile-schemas.c index 2dc8c7171..59fb68ee7 100644 --- a/gio/glib-compile-schemas.c +++ b/gio/glib-compile-schemas.c @@ -179,6 +179,8 @@ typedef struct GString *unparsed_default_value; GVariant *default_value; + GVariantDict *desktop_overrides; + GString *strinfo; gboolean is_enum; gboolean is_flags; @@ -731,6 +733,11 @@ key_state_serialise (KeyState *state) g_variant_builder_add (&builder, "(y(**))", 'r', state->minimum, state->maximum); + /* per-desktop overrides */ + if (state->desktop_overrides) + g_variant_builder_add (&builder, "(y@a{sv})", 'd', + g_variant_dict_end (state->desktop_overrides)); + state->serialised = g_variant_builder_end (&builder); } @@ -768,6 +775,9 @@ key_state_free (gpointer data) if (state->serialised) g_variant_unref (state->serialised); + if (state->desktop_overrides) + g_variant_dict_unref (state->desktop_overrides); + g_slice_free (KeyState, state); } @@ -1878,6 +1888,8 @@ set_overrides (GHashTable *schema_table, gchar **groups; gint i; + g_debug ("Processing override file '%s'", filename); + key_file = g_key_file_new (); if (!g_key_file_load_from_file (key_file, filename, 0, &error)) { @@ -1900,18 +1912,31 @@ set_overrides (GHashTable *schema_table, for (i = 0; groups[i]; i++) { const gchar *group = groups[i]; + const gchar *schema_name; + const gchar *desktop_id; SchemaState *schema; + gchar **pieces; gchar **keys; gint j; - schema = g_hash_table_lookup (schema_table, group); + pieces = g_strsplit (group, ":", 2); + schema_name = pieces[0]; + desktop_id = pieces[1]; + + g_debug ("Processing group '%s' (schema '%s', %s)", + group, schema_name, desktop_id ? desktop_id : "all desktops"); + + schema = g_hash_table_lookup (schema_table, schema_name); if (schema == NULL) - /* Having the schema not be installed is expected to be a - * common case. Don't even emit an error message about - * that. - */ - continue; + { + /* Having the schema not be installed is expected to be a + * common case. Don't even emit an error message about + * that. + */ + g_strfreev (pieces); + continue; + } keys = g_key_file_get_keys (key_file, group, NULL, NULL); g_assert (keys != NULL); @@ -1939,6 +1964,32 @@ set_overrides (GHashTable *schema_table, fprintf (stderr, _(" and --strict was specified; exiting.\n")); g_key_file_free (key_file); + g_strfreev (pieces); + g_strfreev (groups); + g_strfreev (keys); + + return FALSE; + } + + if (desktop_id != NULL && state->l10n) + { + /* Let's avoid the n*m case of per-desktop localised + * default values, and just forbid it. + */ + fprintf (stderr, + _("cannot provide per-desktop overrides for localised " + "key '%s' in schema '%s' (override file '%s')"), + key, group, filename); + + if (!strict) + { + fprintf (stderr, _("; ignoring override for this key.\n")); + continue; + } + + fprintf (stderr, _(" and --strict was specified; exiting.\n")); + g_key_file_free (key_file); + g_strfreev (pieces); g_strfreev (groups); g_strfreev (keys); @@ -1969,6 +2020,7 @@ set_overrides (GHashTable *schema_table, fprintf (stderr, _("--strict was specified; exiting.\n")); g_key_file_free (key_file); + g_strfreev (pieces); g_strfreev (groups); g_strfreev (keys); @@ -1997,6 +2049,7 @@ set_overrides (GHashTable *schema_table, fprintf (stderr, _(" and --strict was specified; exiting.\n")); g_key_file_free (key_file); + g_strfreev (pieces); g_strfreev (groups); g_strfreev (keys); @@ -2025,6 +2078,7 @@ set_overrides (GHashTable *schema_table, fprintf (stderr, _(" and --strict was specified; exiting.\n")); g_key_file_free (key_file); + g_strfreev (pieces); g_strfreev (groups); g_strfreev (keys); @@ -2032,11 +2086,24 @@ set_overrides (GHashTable *schema_table, } } - g_variant_unref (state->default_value); - state->default_value = value; + if (desktop_id != NULL) + { + if (state->desktop_overrides == NULL) + state->desktop_overrides = g_variant_dict_new (NULL); + + g_variant_dict_insert_value (state->desktop_overrides, desktop_id, value); + g_variant_unref (value); + } + else + { + g_variant_unref (state->default_value); + state->default_value = value; + } + g_free (string); } + g_strfreev (pieces); g_strfreev (keys); } diff --git a/gio/gsettings.c b/gio/gsettings.c index 7b0b6a162..5a91ec0d6 100644 --- a/gio/gsettings.c +++ b/gio/gsettings.c @@ -1204,10 +1204,7 @@ g_settings_get_value (GSettings *settings, value = g_settings_read_from_backend (settings, &skey, FALSE, FALSE); if (value == NULL) - value = g_settings_schema_key_get_translated_default (&skey); - - if (value == NULL) - value = g_variant_ref (skey.default_value); + value = g_settings_schema_key_get_default_value (&skey); g_settings_schema_key_clear (&skey); @@ -1304,10 +1301,7 @@ g_settings_get_default_value (GSettings *settings, value = g_settings_read_from_backend (settings, &skey, FALSE, TRUE); if (value == NULL) - value = g_settings_schema_key_get_translated_default (&skey); - - if (value == NULL) - value = g_variant_ref (skey.default_value); + value = g_settings_schema_key_get_default_value (&skey); g_settings_schema_key_clear (&skey); @@ -1360,10 +1354,7 @@ g_settings_get_enum (GSettings *settings, value = g_settings_read_from_backend (settings, &skey, FALSE, FALSE); if (value == NULL) - value = g_settings_schema_key_get_translated_default (&skey); - - if (value == NULL) - value = g_variant_ref (skey.default_value); + value = g_settings_schema_key_get_default_value (&skey); result = g_settings_schema_key_to_enum (&skey, value); g_settings_schema_key_clear (&skey); @@ -1473,10 +1464,7 @@ g_settings_get_flags (GSettings *settings, value = g_settings_read_from_backend (settings, &skey, FALSE, FALSE); if (value == NULL) - value = g_settings_schema_key_get_translated_default (&skey); - - if (value == NULL) - value = g_variant_ref (skey.default_value); + value = g_settings_schema_key_get_default_value (&skey); result = g_settings_schema_key_to_flags (&skey, value); g_settings_schema_key_clear (&skey); @@ -1751,6 +1739,13 @@ g_settings_get_mapped (GSettings *settings, if (okay) goto okay; } + if ((value = g_settings_schema_key_get_per_desktop_default (&skey))) + { + okay = mapping (value, &result, user_data); + g_variant_unref (value); + if (okay) goto okay; + } + if (mapping (skey.default_value, &result, user_data)) goto okay; @@ -2661,6 +2656,20 @@ g_settings_binding_key_changed (GSettings *settings, if (variant == NULL) { + variant = g_settings_schema_key_get_per_desktop_default (&binding->key); + if (variant && + !binding->get_mapping (&value, variant, binding->user_data)) + { + g_error ("Per-desktop default value for key '%s' in schema '%s' " + "was rejected by the binding mapping function.", + binding->key.name, g_settings_schema_get_id (binding->key.schema)); + g_variant_unref (variant); + variant = NULL; + } + } + + if (variant == NULL) + { variant = g_variant_ref (binding->key.default_value); if (!binding->get_mapping (&value, variant, binding->user_data)) g_error ("The schema default value for key '%s' in schema '%s' " diff --git a/gio/gsettingsschema-internal.h b/gio/gsettingsschema-internal.h index f54de3b34..5f996b4bc 100644 --- a/gio/gsettingsschema-internal.h +++ b/gio/gsettingsschema-internal.h @@ -37,6 +37,7 @@ struct _GSettingsSchemaKey const GVariantType *type; GVariant *minimum, *maximum; GVariant *default_value; + GVariant *desktop_overrides; gint ref_count; }; @@ -58,6 +59,7 @@ gboolean g_settings_schema_key_type_check (GSettin GVariant * g_settings_schema_key_range_fixup (GSettingsSchemaKey *key, GVariant *value); GVariant * g_settings_schema_key_get_translated_default (GSettingsSchemaKey *key); +GVariant * g_settings_schema_key_get_per_desktop_default (GSettingsSchemaKey *key); gint g_settings_schema_key_to_enum (GSettingsSchemaKey *key, GVariant *value); diff --git a/gio/gsettingsschema.c b/gio/gsettingsschema.c index 4e12243d8..42722892b 100644 --- a/gio/gsettingsschema.c +++ b/gio/gsettingsschema.c @@ -27,6 +27,7 @@ #include #include #include +#include /** * SECTION:gsettingsschema @@ -1283,6 +1284,11 @@ g_settings_schema_key_init (GSettingsSchemaKey *key, endian_fixup (&key->maximum); break; + case 'd': + g_variant_get (data, "@a{sv}", &key->desktop_overrides); + endian_fixup (&key->desktop_overrides); + break; + default: g_warning ("unknown schema extension '%c'", code); break; @@ -1303,6 +1309,9 @@ g_settings_schema_key_clear (GSettingsSchemaKey *key) if (key->maximum) g_variant_unref (key->maximum); + if (key->desktop_overrides) + g_variant_unref (key->desktop_overrides); + g_variant_unref (key->default_value); g_settings_schema_unref (key->schema); @@ -1410,6 +1419,35 @@ g_settings_schema_key_get_translated_default (GSettingsSchemaKey *key) return value; } +GVariant * +g_settings_schema_key_get_per_desktop_default (GSettingsSchemaKey *key) +{ + static const gchar * const *current_desktops; + GVariant *value = NULL; + gint i; + + if (!key->desktop_overrides) + return NULL; + + if (g_once_init_enter (¤t_desktops)) + { + const gchar *xdg_current_desktop = getenv ("XDG_CURRENT_DESKTOP"); + gchar **tmp; + + if (xdg_current_desktop != NULL && xdg_current_desktop[0] != '\0') + tmp = g_strsplit (xdg_current_desktop, ":", -1); + else + tmp = g_new0 (gchar *, 0 + 1); + + g_once_init_leave (¤t_desktops, (const gchar **) tmp); + } + + for (i = 0; value == NULL && current_desktops[i] != NULL; i++) + value = g_variant_lookup_value (key->desktop_overrides, current_desktops[i], NULL); + + return value; +} + gint g_settings_schema_key_to_enum (GSettingsSchemaKey *key, GVariant *value) @@ -1699,6 +1737,9 @@ g_settings_schema_key_get_default_value (GSettingsSchemaKey *key) value = g_settings_schema_key_get_translated_default (key); if (!value) + value = g_settings_schema_key_get_per_desktop_default (key); + + if (!value) value = g_variant_ref (key->default_value); return value;