Rework the way the color scheme setting is inherited. Now the overriding

2005-12-16  Matthias Clasen  <mclasen@redhat.com>

	* gtk/gtksettings.[hc]: Rework the way the color scheme setting
	is inherited. Now the overriding is done on a per-color basis,
	rather than for the setting as a whole. This has the effect
	that themes can declare defaults for all the symbolic colors they
	use by specifying a value for the gtk-color-scheme setting in
	their rc file, while still allowing the XSetting to override
	"standard" symbolic colors. The hash table is now available
	through the color-hash property.

	* gtk/gtkrc.c: Use the new color-hash property.
This commit is contained in:
Matthias Clasen 2005-12-16 18:45:31 +00:00 committed by Matthias Clasen
parent 9abfb245c5
commit bc190f2a70
5 changed files with 221 additions and 83 deletions

View File

@ -1,3 +1,16 @@
2005-12-16 Matthias Clasen <mclasen@redhat.com>
* gtk/gtksettings.[hc]: Rework the way the color scheme setting
is inherited. Now the overriding is done on a per-color basis,
rather than for the setting as a whole. This has the effect
that themes can declare defaults for all the symbolic colors they
use by specifying a value for the gtk-color-scheme setting in
their rc file, while still allowing the XSetting to override
"standard" symbolic colors. The hash table is now available
through the color-hash property.
* gtk/gtkrc.c: Use the new color-hash property.
2005-12-14 Matthias Clasen <mclasen@redhat.com> 2005-12-14 Matthias Clasen <mclasen@redhat.com>
* gtk/gtkcontainer.c (_gtk_container_focus_sort): Skip unrealized * gtk/gtkcontainer.c (_gtk_container_focus_sort): Skip unrealized

View File

@ -1,3 +1,16 @@
2005-12-16 Matthias Clasen <mclasen@redhat.com>
* gtk/gtksettings.[hc]: Rework the way the color scheme setting
is inherited. Now the overriding is done on a per-color basis,
rather than for the setting as a whole. This has the effect
that themes can declare defaults for all the symbolic colors they
use by specifying a value for the gtk-color-scheme setting in
their rc file, while still allowing the XSetting to override
"standard" symbolic colors. The hash table is now available
through the color-hash property.
* gtk/gtkrc.c: Use the new color-hash property.
2005-12-14 Matthias Clasen <mclasen@redhat.com> 2005-12-14 Matthias Clasen <mclasen@redhat.com>
* gtk/gtkcontainer.c (_gtk_container_focus_sort): Skip unrealized * gtk/gtkcontainer.c (_gtk_container_focus_sort): Skip unrealized

View File

@ -105,7 +105,6 @@ struct _GtkRcContext
gint default_priority; gint default_priority;
GtkStyle *default_style; GtkStyle *default_style;
gchar *colors;
GHashTable *color_hash; GHashTable *color_hash;
}; };
@ -574,36 +573,19 @@ gtk_rc_font_name_changed (GtkSettings *settings,
} }
static void static void
gtk_rc_color_scheme_changed (GtkSettings *settings, gtk_rc_color_hash_changed (GtkSettings *settings,
GParamSpec *pspec, GParamSpec *pspec,
GtkRcContext *context) GtkRcContext *context)
{ {
gchar *colors; if (context->color_hash)
g_hash_table_unref (context->color_hash);
g_object_get (settings, "color-hash", &context->color_hash, NULL);
g_object_get (settings, if (context->color_hash)
"gtk-color-scheme", &colors, g_hash_table_ref (context->color_hash);
NULL);
gtk_rc_reparse_all_for_settings (settings, TRUE);
if (!colors && !context->colors)
return;
if (!colors || !context->colors ||
strcmp (colors, context->colors) != 0)
{
g_free (context->colors);
context->colors = g_strdup (colors);
if (context->color_hash)
g_hash_table_unref (context->color_hash);
context->color_hash = _gtk_settings_get_color_hash (settings);
if (context->color_hash)
g_hash_table_ref (context->color_hash);
gtk_rc_reparse_all_for_settings (settings, TRUE);
}
g_free (colors);
} }
static GtkRcContext * static GtkRcContext *
@ -625,10 +607,9 @@ gtk_rc_context_get (GtkSettings *settings)
"gtk-theme-name", &context->theme_name, "gtk-theme-name", &context->theme_name,
"gtk-key-theme-name", &context->key_theme_name, "gtk-key-theme-name", &context->key_theme_name,
"gtk-font-name", &context->font_name, "gtk-font-name", &context->font_name,
"gtk-color-scheme", &context->colors, "color-hash", &context->color_hash,
NULL); NULL);
context->color_hash = _gtk_settings_get_color_hash (settings);
if (context->color_hash) if (context->color_hash)
g_hash_table_ref (context->color_hash); g_hash_table_ref (context->color_hash);
@ -645,8 +626,8 @@ gtk_rc_context_get (GtkSettings *settings)
G_CALLBACK (gtk_rc_font_name_changed), G_CALLBACK (gtk_rc_font_name_changed),
context); context);
g_signal_connect (settings, g_signal_connect (settings,
"notify::gtk-color-scheme", "notify::color-hash",
G_CALLBACK (gtk_rc_color_scheme_changed), G_CALLBACK (gtk_rc_color_hash_changed),
context); context);
context->pixmap_path[0] = NULL; context->pixmap_path[0] = NULL;

View File

@ -41,6 +41,7 @@ typedef enum
{ {
GTK_SETTINGS_SOURCE_DEFAULT, GTK_SETTINGS_SOURCE_DEFAULT,
GTK_SETTINGS_SOURCE_RC_FILE, GTK_SETTINGS_SOURCE_RC_FILE,
GTK_SETTINGS_SOURCE_XSETTING,
GTK_SETTINGS_SOURCE_APPLICATION GTK_SETTINGS_SOURCE_APPLICATION
} GtkSettingsSource; } GtkSettingsSource;
@ -86,7 +87,8 @@ enum {
PROP_TIMEOUT_INITIAL, PROP_TIMEOUT_INITIAL,
PROP_TIMEOUT_REPEAT, PROP_TIMEOUT_REPEAT,
PROP_COLOR_SCHEME, PROP_COLOR_SCHEME,
PROP_ENABLE_ANIMATIONS PROP_ENABLE_ANIMATIONS,
PROP_COLOR_HASH
}; };
@ -109,14 +111,19 @@ static guint settings_install_property_parser (GtkSettingsClass *class,
GtkRcPropertyParser parser); GtkRcPropertyParser parser);
static void settings_update_double_click (GtkSettings *settings); static void settings_update_double_click (GtkSettings *settings);
static void settings_update_modules (GtkSettings *settings); static void settings_update_modules (GtkSettings *settings);
static void settings_update_color_scheme (GtkSettings *settings);
#ifdef GDK_WINDOWING_X11 #ifdef GDK_WINDOWING_X11
static void settings_update_cursor_theme (GtkSettings *settings); static void settings_update_cursor_theme (GtkSettings *settings);
static void settings_update_resolution (GtkSettings *settings); static void settings_update_resolution (GtkSettings *settings);
static void settings_update_font_options (GtkSettings *settings); static void settings_update_font_options (GtkSettings *settings);
#endif #endif
static void settings_update_color_scheme (GtkSettings *settings);
static void merge_color_scheme (GtkSettings *settings,
GValue *value,
GtkSettingsSource source);
static gchar *get_color_scheme (GtkSettings *settings);
static GHashTable *get_color_hash (GtkSettings *settings);
/* --- variables --- */ /* --- variables --- */
@ -448,6 +455,10 @@ gtk_settings_class_init (GtkSettingsClass *class)
* color specifications must be in the format accepted by * color specifications must be in the format accepted by
* gdk_color_parse(). * gdk_color_parse().
* *
* Note that due to the way the color tables from different sources are
* merged, color specifications will be converted to hexadecimal form
* when getting this property.
*
* Since: 2.10 * Since: 2.10
*/ */
result = settings_install_property_parser (class, result = settings_install_property_parser (class,
@ -469,6 +480,22 @@ gtk_settings_class_init (GtkSettingsClass *class)
NULL); NULL);
g_assert (result == PROP_ENABLE_ANIMATIONS); g_assert (result == PROP_ENABLE_ANIMATIONS);
/**
* GtkSettings:color-hash:
*
* Holds a hash table representation of the gtk-color-scheme setting,
* mapping color names to #GdkColor<!-- -->s.
*
* Since: 2.10
*/
g_object_class_install_property (gobject_class,
PROP_COLOR_HASH,
g_param_spec_boxed ("color-hash",
P_("Color Hash"),
P_("A hash table resentation of the color scheme."),
G_TYPE_HASH_TABLE,
GTK_PARAM_READABLE));
} }
static void static void
@ -519,6 +546,7 @@ gtk_settings_get_for_screen (GdkScreen *screen)
settings_update_resolution (settings); settings_update_resolution (settings);
settings_update_font_options (settings); settings_update_font_options (settings);
#endif #endif
settings_update_color_scheme (settings);
} }
return settings; return settings;
@ -566,6 +594,12 @@ gtk_settings_get_property (GObject *object,
GType value_type = G_VALUE_TYPE (value); GType value_type = G_VALUE_TYPE (value);
GType fundamental_type = G_TYPE_FUNDAMENTAL (value_type); GType fundamental_type = G_TYPE_FUNDAMENTAL (value_type);
if (property_id == PROP_COLOR_HASH)
{
g_value_set_boxed (value, get_color_hash (settings));
return;
}
/* For enums and strings, we need to get the value as a string, /* For enums and strings, we need to get the value as a string,
* not as an int, since we support using names/nicks as the setting * not as an int, since we support using names/nicks as the setting
* value. * value.
@ -578,8 +612,16 @@ gtk_settings_get_property (GObject *object,
if (settings->property_values[property_id - 1].source == GTK_SETTINGS_SOURCE_APPLICATION || if (settings->property_values[property_id - 1].source == GTK_SETTINGS_SOURCE_APPLICATION ||
!gdk_screen_get_setting (settings->screen, pspec->name, value)) !gdk_screen_get_setting (settings->screen, pspec->name, value))
g_value_copy (&settings->property_values[property_id - 1].value, value); g_value_copy (&settings->property_values[property_id - 1].value, value);
else else
g_param_value_validate (pspec, value); {
if (pspec->param_id == PROP_COLOR_SCHEME)
{
merge_color_scheme (settings, value, GTK_SETTINGS_SOURCE_XSETTING);
g_value_set_string (value, get_color_scheme (settings));
}
g_param_value_validate (pspec, value);
}
} }
else else
{ {
@ -601,7 +643,6 @@ gtk_settings_get_property (GObject *object,
GtkRcPropertyParser parser = (GtkRcPropertyParser) g_param_spec_get_qdata (pspec, quark_property_parser); GtkRcPropertyParser parser = (GtkRcPropertyParser) g_param_spec_get_qdata (pspec, quark_property_parser);
g_value_init (&gstring_value, G_TYPE_GSTRING); g_value_init (&gstring_value, G_TYPE_GSTRING);
g_value_take_boxed (&gstring_value, g_value_take_boxed (&gstring_value,
g_string_new (g_value_get_string (&val))); g_string_new (g_value_get_string (&val)));
@ -641,13 +682,13 @@ gtk_settings_notify (GObject *object,
case PROP_MODULES: case PROP_MODULES:
settings_update_modules (settings); settings_update_modules (settings);
break; break;
case PROP_COLOR_SCHEME:
settings_update_color_scheme (settings);
break;
case PROP_DOUBLE_CLICK_TIME: case PROP_DOUBLE_CLICK_TIME:
case PROP_DOUBLE_CLICK_DISTANCE: case PROP_DOUBLE_CLICK_DISTANCE:
settings_update_double_click (settings); settings_update_double_click (settings);
break; break;
case PROP_COLOR_SCHEME:
settings_update_color_scheme (settings);
break;
#ifdef GDK_WINDOWING_X11 #ifdef GDK_WINDOWING_X11
case PROP_XFT_DPI: case PROP_XFT_DPI:
settings_update_resolution (settings); settings_update_resolution (settings);
@ -751,7 +792,14 @@ apply_queued_setting (GtkSettings *data,
if (_gtk_settings_parse_convert (parser, &qvalue->public.value, if (_gtk_settings_parse_convert (parser, &qvalue->public.value,
pspec, &tmp_value)) pspec, &tmp_value))
{ {
if (data->property_values[pspec->param_id - 1].source <= qvalue->source) if (pspec->param_id == PROP_COLOR_SCHEME)
{
merge_color_scheme (data, &tmp_value, qvalue->source);
g_object_set_property (G_OBJECT (data), pspec->name, &tmp_value);
data->property_values[pspec->param_id - 1].source = GTK_SETTINGS_SOURCE_DEFAULT;
}
else if (data->property_values[pspec->param_id - 1].source <= qvalue->source)
{ {
g_object_set_property (G_OBJECT (data), pspec->name, &tmp_value); g_object_set_property (G_OBJECT (data), pspec->name, &tmp_value);
data->property_values[pspec->param_id - 1].source = qvalue->source; data->property_values[pspec->param_id - 1].source = qvalue->source;
@ -1557,15 +1605,45 @@ settings_update_resolution (GtkSettings *settings)
} }
#endif #endif
static GHashTable * static void
gtk_color_table_from_string (const gchar *str) settings_update_color_scheme (GtkSettings *settings)
{
gchar *dummy;
g_object_get (settings, "gtk-color-scheme", &dummy, NULL);
/* nothing to do here, the color hash is updated as a
* side effect of getting the color scheme
*/
g_free (dummy);
}
typedef struct {
GHashTable *color_hash;
gchar *tables[GTK_SETTINGS_SOURCE_APPLICATION + 1];
} ColorSchemeData;
static gboolean
update_color_hash (ColorSchemeData *data,
const gchar *str,
GtkSettingsSource source)
{ {
gchar *copy, *s, *p, *name; gchar *copy, *s, *p, *name;
GdkColor color; GdkColor color;
GHashTable *colors; gboolean changed = FALSE;
colors = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, if (data->tables[source] == NULL && str == NULL)
(GDestroyNotify) gdk_color_free); return FALSE;
if (data->tables[source] != NULL && str != NULL &&
strcmp (data->tables[source], str) == 0)
return FALSE;
g_free (data->tables[source]);
data->tables[source] = g_strdup (str);
copy = g_strdup (str); copy = g_strdup (str);
@ -1580,12 +1658,7 @@ gtk_color_table_from_string (const gchar *str)
p++; p++;
} }
else else
{ break;
g_hash_table_destroy (colors);
colors = NULL;
break;
}
while (*p == ' ') while (*p == ' ')
p++; p++;
@ -1602,51 +1675,110 @@ gtk_color_table_from_string (const gchar *str)
s++; s++;
} }
if (!gdk_color_parse (p, &color)) if (gdk_color_parse (p, &color))
{ {
g_hash_table_destroy (colors); GdkColor *old;
colors = NULL;
break; old = g_hash_table_lookup (data->color_hash, name);
} if (!old ||
(old->pixel <= source && !gdk_color_equal (old, &color)))
g_hash_table_insert (colors, {
g_strdup (name), GdkColor *new;
gdk_color_copy (&color));
new = gdk_color_copy (&color);
new->pixel = source;
g_hash_table_insert (data->color_hash, g_strdup (name), new);
changed = TRUE;
}
}
} }
g_free (copy); g_free (copy);
return colors; return changed;
} }
static void static void
settings_update_color_scheme (GtkSettings *settings) color_scheme_data_free (ColorSchemeData *data)
{ {
gchar *colors; gint i;
GHashTable *color_hash;
g_object_get (settings, g_hash_table_unref (data->color_hash);
"gtk-color-scheme", &colors,
NULL);
color_hash = gtk_color_table_from_string (colors); for (i = 0; i <= GTK_SETTINGS_SOURCE_APPLICATION; i++)
g_free (data->tables[i]);
g_object_set_data_full (G_OBJECT (settings), "gtk-color-scheme", g_free (data);
color_hash, (GDestroyNotify) g_hash_table_unref);
g_free (colors);
} }
GHashTable * static void
_gtk_settings_get_color_hash (GtkSettings *settings) merge_color_scheme (GtkSettings *settings,
GValue *value,
GtkSettingsSource source)
{ {
if (g_object_get_data (G_OBJECT (settings), ColorSchemeData *data;
"gtk-color-scheme") == NULL) const gchar *colors;
settings_update_color_scheme (settings);
return (GHashTable *) g_object_get_data (G_OBJECT (settings), colors = g_value_get_string (value);
"gtk-color-scheme");
data = (ColorSchemeData *) g_object_get_data (G_OBJECT (settings),
"gtk-color-scheme");
if (!data)
{
data = g_new0 (ColorSchemeData, 1);
data->color_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
(GDestroyNotify) gdk_color_free);
g_object_set_data_full (G_OBJECT (settings), "gtk-color-scheme",
data, (GDestroyNotify) color_scheme_data_free);
}
if (update_color_hash (data, colors, source))
g_object_notify (G_OBJECT (settings), "color-hash");
}
static GHashTable *
get_color_hash (GtkSettings *settings)
{
ColorSchemeData *data;
if (!g_object_get_data (G_OBJECT (settings), "gtk-color-scheme"))
settings_update_color_scheme (settings);
data = (ColorSchemeData *)g_object_get_data (G_OBJECT (settings),
"gtk-color-scheme");
return data->color_hash;
}
static void
append_color_scheme (gpointer key,
gpointer value,
gpointer data)
{
gchar *name = (gchar *)key;
GdkColor *color = (GdkColor *)value;
GString *string = (GString *)data;
g_string_append_printf (string, "%s: #%04x%04x%04x\n",
name, color->red, color->green, color->blue);
}
static gchar *
get_color_scheme (GtkSettings *settings)
{
ColorSchemeData *data;
GString *string;
data = (ColorSchemeData *) g_object_get_data (G_OBJECT (settings),
"gtk-color-scheme");
string = g_string_new ("");
g_hash_table_foreach (data->color_hash, append_color_scheme, string);
return g_string_free (string, FALSE);
} }

View File

@ -126,7 +126,6 @@ gboolean _gtk_settings_parse_convert (GtkRcPropertyParser parser,
const GValue *src_value, const GValue *src_value,
GParamSpec *pspec, GParamSpec *pspec,
GValue *dest_value); GValue *dest_value);
GHashTable* _gtk_settings_get_color_hash (GtkSettings *settings);
G_END_DECLS G_END_DECLS