From 6c06c9fd4851d2ac67d489ead4f536933a01601d Mon Sep 17 00:00:00 2001 From: Packit Service Date: Dec 09 2020 15:00:24 +0000 Subject: Apply patch backport-per-desktop-overrides.patch patch_name: backport-per-desktop-overrides.patch present_in_specfile: true location_in_specfile: 8 --- diff --git a/gio/glib-compile-schemas.c b/gio/glib-compile-schemas.c index 2dc8c71..00dd641 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); } @@ -2072,6 +2139,7 @@ main (int argc, char **argv) /* These options are only for use in the gschema-compile tests */ { "schema-file", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_FILENAME_ARRAY, &schema_files, NULL, NULL }, + { "override-file", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_FILENAME_ARRAY, &override_files, NULL, NULL }, { NULL } }; diff --git a/gio/gsettings.c b/gio/gsettings.c index 10d394d..f1130c0 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 f54de3b..5f996b4 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 f1274a3..17b7e3b 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 = g_getenv ("XDG_CURRENT_DESKTOP"); + gchar **tmp; + + if (xdg_current_desktop != NULL && xdg_current_desktop[0] != '\0') + tmp = g_strsplit (xdg_current_desktop, G_SEARCHPATH_SEPARATOR_S, -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; diff --git a/gio/tests/Makefile.am b/gio/tests/Makefile.am index 49a19bf..b41317a 100644 --- a/gio/tests/Makefile.am +++ b/gio/tests/Makefile.am @@ -367,12 +367,14 @@ test.mo: de.po EXTRA_DIST += de.po dist_uninstalled_test_data += \ org.gtk.test.gschema.xml.orig \ + org.gtk.test.gschema.override.orig \ org.gtk.schemasourcecheck.gschema.xml \ testenum.h \ enums.xml.template # Generated while running the testcase itself... CLEANFILES += \ org.gtk.test.gschema.xml \ + org.gtk.test.gschema.override \ org.gtk.test.enums.xml \ gsettings.store \ gschemas.compiled \ diff --git a/gio/tests/gsettings.c b/gio/tests/gsettings.c index 2be4122..acdeead 100644 --- a/gio/tests/gsettings.c +++ b/gio/tests/gsettings.c @@ -2192,6 +2192,7 @@ G_GNUC_END_IGNORE_DEPRECATIONS "org.gtk.test.range.direct", "org.gtk.test.mapped", "org.gtk.test.descriptions", + "org.gtk.test.per-desktop", NULL)); } @@ -2583,6 +2584,100 @@ test_default_value (void) g_object_unref (settings); } +static gboolean +string_map_func (GVariant *value, + gpointer *result, + gpointer user_data) +{ + const gchar *str; + + str = g_variant_get_string (value, NULL); + *result = g_variant_new_string (str); + + return TRUE; +} + +/* Test that per-desktop values from org.gtk.test.gschema.override + * does not change default value if current desktop is not listed in + * $XDG_CURRENT_DESKTOP. + */ +static void +test_per_desktop (void) +{ + GSettings *settings; + TestObject *obj; + gpointer p; + gchar *str; + + settings = g_settings_new ("org.gtk.test.per-desktop"); + obj = test_object_new (); + + if (!g_test_subprocess ()) + { + g_test_trap_subprocess ("/gsettings/per-desktop/subprocess", 0, 0); + g_test_trap_assert_passed (); + } + + str = g_settings_get_string (settings, "desktop"); + g_assert_cmpstr (str, ==, "GNOME"); + g_free (str); + + p = g_settings_get_mapped (settings, "desktop", string_map_func, NULL); + + str = g_variant_dup_string (p, NULL); + g_assert_cmpstr (str, ==, "GNOME"); + g_free (str); + + g_variant_unref (p); + + g_settings_bind (settings, "desktop", obj, "string", G_SETTINGS_BIND_DEFAULT); + + g_object_get (obj, "string", &str, NULL); + g_assert_cmpstr (str, ==, "GNOME"); + g_free (str); + + g_object_unref (settings); + g_object_unref (obj); +} + +/* Test that per-desktop values from org.gtk.test.gschema.override + * are successfully loaded based on the value of $XDG_CURRENT_DESKTOP. + */ +static void +test_per_desktop_subprocess (void) +{ + GSettings *settings; + TestObject *obj; + gpointer p; + gchar *str; + + g_setenv ("XDG_CURRENT_DESKTOP", "GNOME-Classic:GNOME", TRUE); + + settings = g_settings_new ("org.gtk.test.per-desktop"); + obj = test_object_new (); + + str = g_settings_get_string (settings, "desktop"); + g_assert_cmpstr (str, ==, "GNOME Classic"); + g_free (str); + + p = g_settings_get_mapped (settings, "desktop", string_map_func, NULL); + + str = g_variant_dup_string (p, NULL); + g_assert_cmpstr (str, ==, "GNOME Classic"); + g_free (str); + + g_variant_unref (p); + + g_settings_bind (settings, "desktop", obj, "string", G_SETTINGS_BIND_DEFAULT); + + g_object_get (obj, "string", &str, NULL); + g_assert_cmpstr (str, ==, "GNOME Classic"); + g_free (str); + + g_object_unref (settings); + g_object_unref (obj); +} + static void test_extended_schema (void) { @@ -2603,6 +2698,7 @@ int main (int argc, char *argv[]) { gchar *schema_text; + gchar *override_text; gchar *enums; gint result; @@ -2625,6 +2721,7 @@ main (int argc, char *argv[]) g_setenv ("XDG_DATA_DIRS", ".", TRUE); g_setenv ("XDG_DATA_HOME", ".", TRUE); g_setenv ("GSETTINGS_SCHEMA_DIR", ".", TRUE); + g_setenv ("XDG_CURRENT_DESKTOP", "", TRUE); if (!backend_set) g_setenv ("GSETTINGS_BACKEND", "memory", TRUE); @@ -2647,6 +2744,10 @@ main (int argc, char *argv[]) g_assert (g_file_set_contents ("org.gtk.test.gschema.xml", schema_text, -1, NULL)); g_free (schema_text); + g_assert (g_file_get_contents (SRCDIR "/org.gtk.test.gschema.override.orig", &override_text, NULL, NULL)); + g_assert (g_file_set_contents ("org.gtk.test.gschema.override", override_text, -1, NULL)); + g_free (override_text); + /* Meson build defines this, autotools build does not */ #ifndef GLIB_COMPILE_SCHEMAS #define GLIB_COMPILE_SCHEMAS "../glib-compile-schemas" @@ -2655,7 +2756,8 @@ main (int argc, char *argv[]) g_remove ("gschemas.compiled"); g_assert (g_spawn_command_line_sync (GLIB_COMPILE_SCHEMAS " --targetdir=. " "--schema-file=org.gtk.test.enums.xml " - "--schema-file=org.gtk.test.gschema.xml", + "--schema-file=org.gtk.test.gschema.xml " + "--override-file=org.gtk.test.gschema.override", NULL, NULL, &result, NULL)); g_assert (result == 0); @@ -2736,6 +2838,8 @@ main (int argc, char *argv[]) g_test_add_func ("/gsettings/read-descriptions", test_read_descriptions); g_test_add_func ("/gsettings/test-extended-schema", test_extended_schema); g_test_add_func ("/gsettings/default-value", test_default_value); + g_test_add_func ("/gsettings/per-desktop", test_per_desktop); + g_test_add_func ("/gsettings/per-desktop/subprocess", test_per_desktop_subprocess); result = g_test_run (); diff --git a/gio/tests/org.gtk.test.gschema.override.orig b/gio/tests/org.gtk.test.gschema.override.orig new file mode 100644 index 0000000..6694baa --- /dev/null +++ b/gio/tests/org.gtk.test.gschema.override.orig @@ -0,0 +1,2 @@ +[org.gtk.test.per-desktop:GNOME-Classic] +desktop = "GNOME Classic" diff --git a/gio/tests/org.gtk.test.gschema.xml.orig b/gio/tests/org.gtk.test.gschema.xml.orig index c075583..fbcdce6 100644 --- a/gio/tests/org.gtk.test.gschema.xml.orig +++ b/gio/tests/org.gtk.test.gschema.xml.orig @@ -209,4 +209,10 @@ + + + "GNOME" + + +