Fix issues with symbolic colors in rc file parsing

Don't recreate the settings color hash every time, repopulate it
instead. This avoids invalidating the references held by RcContexts.
This commit is contained in:
Matthias Clasen 2009-10-25 23:47:59 -04:00
parent 16482f20db
commit d3e6cffff7
2 changed files with 44 additions and 21 deletions

View File

@ -659,11 +659,15 @@ gtk_rc_color_hash_changed (GtkSettings *settings,
GParamSpec *pspec,
GtkRcContext *context)
{
if (context->color_hash)
g_hash_table_unref (context->color_hash);
GHashTable *old_hash;
old_hash = context->color_hash;
g_object_get (settings, "color-hash", &context->color_hash, NULL);
if (old_hash)
g_hash_table_unref (old_hash);
gtk_rc_reparse_all_for_settings (settings, TRUE);
}
@ -3148,8 +3152,10 @@ gtk_rc_parse_style (GtkRcContext *context,
break;
case GTK_RC_TOKEN_COLOR:
if (our_hash == NULL)
gtk_rc_style_prepend_empty_color_hash (rc_style);
our_hash = rc_priv->color_hashes->data;
{
gtk_rc_style_prepend_empty_color_hash (rc_style);
our_hash = rc_priv->color_hashes->data;
}
token = gtk_rc_parse_logical_color (scanner, rc_style, our_hash);
break;
case G_TOKEN_IDENTIFIER:

View File

@ -2196,8 +2196,8 @@ settings_update_color_scheme (GtkSettings *settings)
}
static gboolean
add_color_to_hash (gchar *name,
GdkColor *color,
add_color_to_hash (gchar *name,
GdkColor *color,
GHashTable *target)
{
GdkColor *old;
@ -2206,7 +2206,7 @@ add_color_to_hash (gchar *name,
if (!old || !gdk_color_equal (old, color))
{
g_hash_table_insert (target, g_strdup (name), gdk_color_copy (color));
return TRUE;
}
@ -2214,7 +2214,7 @@ add_color_to_hash (gchar *name,
}
static gboolean
add_colors_to_hash_from_string (GHashTable *hash,
add_colors_to_hash_from_string (GHashTable *hash,
const gchar *colors)
{
gchar *s, *p, *name;
@ -2262,24 +2262,27 @@ add_colors_to_hash_from_string (GHashTable *hash,
static gboolean
update_color_hash (ColorSchemeData *data,
const gchar *str,
const gchar *str,
GtkSettingsSource source)
{
gboolean changed = FALSE;
gint i;
GHashTable *old_hash;
GHashTableIter iter;
gchar *name;
GdkColor *color;
if ((str == NULL || *str == '\0') &&
if ((str == NULL || *str == '\0') &&
(data->lastentry[source] == NULL || data->lastentry[source][0] == '\0'))
return FALSE;
if (str && data->lastentry[source] && strcmp (str, data->lastentry[source]) == 0)
return FALSE;
/* For the RC_FILE source we merge the values rather than over-writing
/* For the RC_FILE source we merge the values rather than over-writing
* them, since multiple rc files might define independent sets of colors
*/
if ((source != GTK_SETTINGS_SOURCE_RC_FILE) &&
if ((source != GTK_SETTINGS_SOURCE_RC_FILE) &&
data->tables[source] && g_hash_table_size (data->tables[source]) > 0)
{
g_hash_table_unref (data->tables[source]);
@ -2288,22 +2291,36 @@ update_color_hash (ColorSchemeData *data,
}
if (data->tables[source] == NULL)
data->tables[source] = g_hash_table_new_full (g_str_hash, g_str_equal,
data->tables[source] = g_hash_table_new_full (g_str_hash, g_str_equal,
g_free,
(GDestroyNotify) gdk_color_free);
g_free (data->lastentry[source]);
data->lastentry[source] = g_strdup (str);
changed |= add_colors_to_hash_from_string (data->tables[source], str);
if (!changed)
return FALSE;
/* Rebuild the merged hash table. */
old_hash = data->color_hash;
data->color_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
(GDestroyNotify) gdk_color_free);
if (data->color_hash)
{
old_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
(GDestroyNotify) gdk_color_free);
g_hash_table_iter_init (&iter, data->color_hash);
while (g_hash_table_iter_next (&iter, &name, &color))
{
g_hash_table_insert (old_hash, name, color);
g_hash_table_iter_steal (&iter);
}
}
else
{
old_hash = NULL;
}
for (i = 0; i <= GTK_SETTINGS_SOURCE_APPLICATION; i++)
{
if (data->tables[i])
@ -2330,13 +2347,13 @@ update_color_hash (ColorSchemeData *data,
{
changed = TRUE;
break;
}
}
}
}
g_hash_table_unref (old_hash);
}
else
else
changed = TRUE;
return changed;