[Nautilus-list] eel and changing widget styles



Eel has various functions that:

 - Get the style of a widget
 - Modify it
 - Set it back

This is dangerous in several ways:

 - If called before the widget has its final style, the widget
   may not get its proper style
 - The widget will not subsequently react properly to theme
   changes.

In particular, there was a bug in the theme list in Nautilus's
preferences where it was not getting the correct Japanese
font because gtk_widget_get_style() was being called before
the style was looked up from the RC file.

The following patch fixes this problem by making

 void eel_gtk_widget_set_foreground_color ();
 void eel_gtk_widget_set_backgound_color ();
 void eel_gtk_widget_set_font ();

Use gtk_widget_modify_style() instead of gtk_widget_set_style().

An alternate simpler fix to the bug would be to add calls
to gtk_widget_ensure_style() into these three functions 
before calling gtk_widget_get_style(), but I would consider
the following to be more correct and more robust.

It's fairly similar in operation to gtk_widget_modify_fg(),
and friends in GTK+-2.0.

Regards,
                                        Owen

--- eel-1.0.1/eel/eel-gdk-font-extensions.c.bak	Thu Aug  2 19:41:19 2001
+++ eel-1.0.1/eel/eel-gdk-font-extensions.c	Thu Aug  2 20:00:12 2001
@@ -67,7 +67,6 @@
 static EelStringList *      font_list_fonts                          (const char          *pattern);
 static const EelStringList *font_list_fonts_cached                   (const char          *pattern,
 								      GCompareFunc         compare_function);
-static char *               font_get_name                            (const GdkFont       *font);
 static guint                font_get_size_in_pixels                  (const GdkFont       *font);
 static GdkFont *            font_get_bold                            (GdkFont             *font);
 
@@ -128,7 +127,7 @@
 		return font;
 	}
 
-	name = font_get_name (font);
+	name = eel_gdk_font_get_name (font);
 
 	/* Replace the slant with a wildard */
 	slant_pattern = xlfd_string_replace_nth (name, XLFD_SLANT_INDEX, "*");
@@ -247,7 +246,7 @@
 
 	g_assert (bold_font_table != NULL);
 
-	name = font_get_name (font);
+	name = eel_gdk_font_get_name (font);
 	entry = g_hash_table_lookup (bold_font_table, name);
 
 	if (entry != NULL) {
@@ -419,7 +418,7 @@
 		return font;
 	}
 
-	name = font_get_name (font);
+	name = eel_gdk_font_get_name (font);
 
 	size_in_points = xlfd_string_get_nth_as_int (name, XLFD_SIZE_IN_POINTS_INDEX);
 	size_in_pixels = xlfd_string_get_nth_as_int (name, XLFD_SIZE_IN_PIXELS_INDEX);
@@ -604,7 +603,7 @@
 		char *font_name;
 		gboolean done;
 		
-		font_name = font_get_name (font);
+		font_name = eel_gdk_font_get_name (font);
 		
 		/* Iterate through the fonts until we find one that works */
 		candidate_size = maximum_acceptable_font_size;
@@ -835,7 +834,7 @@
 
 	g_return_val_if_fail (font != NULL, NULL);
 
-	name = font_get_name (font);
+	name = eel_gdk_font_get_name (font);
 
 	/* Replace the weight with a wildard */
 	weight_pattern = xlfd_string_replace_nth (name, XLFD_WEIGHT_INDEX, "*");
@@ -1003,9 +1002,17 @@
 	return entry->font_list;
 }
 
-/* Return the font name - an xlfd string used by Gdk to allocate the font */
-static char *
-font_get_name (const GdkFont *font)
+/**
+ * eel_gdk_font_get_name:
+ * @font: a #GdkFont
+ * 
+ * Get the XLFD string used by GDK to allocate the font.
+ * 
+ * Return value: a newly allocated string holding the XLFD
+ *   used to allocate the font.
+ **/
+char *
+eel_gdk_font_get_name (GdkFont *font)
 {
 	GdkFontPrivate *font_private;
 	const char *font_name;
@@ -1040,7 +1047,7 @@
 
 	g_return_val_if_fail (font != NULL, 0);
 
-	name = font_get_name (font);
+	name = eel_gdk_font_get_name (font);
 	size_in_pixels = xlfd_string_get_nth_as_int (name, XLFD_SIZE_IN_PIXELS_INDEX);
 	g_free (name);
 
--- eel-1.0.1/eel/eel-gdk-font-extensions.h.bak	Thu Aug  2 19:41:48 2001
+++ eel-1.0.1/eel/eel-gdk-font-extensions.h	Thu Aug  2 20:00:32 2001
@@ -62,5 +62,6 @@
 					   const char *set_width,
 					   const char *add_style,
 					   guint       size_in_pixels);
+char *   eel_gdk_font_get_name            (GdkFont    *font);
 
 #endif /* EEL_GDK_FONT_EXTENSIONS_H */
--- eel-1.0.1/eel/eel-gtk-extensions.c.bak	Thu Aug  2 19:46:17 2001
+++ eel-1.0.1/eel/eel-gtk-extensions.c	Thu Aug  2 19:56:25 2001
@@ -1203,6 +1203,42 @@
 	return g_list_copy (eel_gtk_object_list_ref (list));
 }
 
+static GtkRcStyle *
+get_modifier_style (GtkWidget *widget)
+{
+	static GQuark rc_style_id = 0;
+	GtkRcStyle *old_style;
+	GtkRcStyle *new_style;
+	int i;
+
+	if (!rc_style_id)
+		rc_style_id = g_quark_from_static_string ("gtk-rc-style");
+
+	old_style = gtk_object_get_data_by_id (GTK_OBJECT (widget), rc_style_id);
+
+	new_style = gtk_rc_style_new ();
+
+	if (old_style) {
+		if (old_style->font_name)
+			new_style->font_name = g_strdup (old_style->font_name);
+		if (old_style->fontset_name)
+			new_style->fontset_name = g_strdup (old_style->fontset_name);
+
+		for (i=0; i < 5; i++) {
+			if (old_style->bg_pixmap_name[i])
+				new_style->fontset_name = g_strdup (old_style->bg_pixmap_name[i]);
+			
+			new_style->color_flags[i] = old_style->color_flags[i];
+			new_style->fg[i] = old_style->fg[i];
+			new_style->bg[i] = old_style->bg[i];
+			new_style->text[i] = old_style->text[i];
+			new_style->base[i] = old_style->base[i];
+		}
+	}
+
+	return new_style;
+}
+
 /**
  * eel_gtk_style_set_font
  *
@@ -1231,17 +1267,22 @@
 void
 eel_gtk_widget_set_font (GtkWidget *widget, GdkFont *font)
 {
-	GtkStyle *new_style;
+	GtkRcStyle *new_style;
+	char *font_name;
 	
 	g_return_if_fail (GTK_IS_WIDGET (widget));
 	g_return_if_fail (font != NULL);
 	
-	new_style = gtk_style_copy (gtk_widget_get_style (widget));
+	new_style = get_modifier_style (widget);
+	font_name = eel_gdk_font_get_name (font);
 
-	eel_gtk_style_set_font (new_style, font);
-	
-	gtk_widget_set_style (widget, new_style);
-	gtk_style_unref (new_style);
+	if (new_style->fontset_name)
+		g_free (new_style->fontset_name);
+
+	new_style->fontset_name = font_name;
+
+	gtk_widget_modify_style (widget, new_style);
+	gtk_rc_style_unref (new_style);
 }
 
 /**
@@ -1699,51 +1740,53 @@
 }
 
 void
-eel_gtk_widget_set_background_color (GtkWidget              *widget,
-					  const char		*color_spec)
+eel_gtk_widget_set_background_color (GtkWidget          *widget,
+				     const char		*color_spec)
 {
-	GtkStyle	*style;
+	GtkRcStyle     *new_style;
 	GdkColor	color;
 
 	g_return_if_fail (GTK_IS_WIDGET (widget));
 
-	style = gtk_widget_get_style (widget);
+	eel_gdk_color_parse_with_white_default (color_spec, &color);
+	
+	new_style = get_modifier_style (widget);
 
-	/* Make a copy of the style. */
-	style = gtk_style_copy (style);
+	new_style->color_flags[GTK_STATE_NORMAL] |= (GTK_RC_BG | GTK_RC_BASE);
+	new_style->bg[GTK_STATE_NORMAL] = color;
+	new_style->base[GTK_STATE_NORMAL] = color;
+
+	new_style->color_flags[GTK_STATE_ACTIVE] |= (GTK_RC_BG | GTK_RC_BASE);
+	new_style->bg[GTK_STATE_ACTIVE] = color;
+	new_style->base[GTK_STATE_ACTIVE] = color;
 
-	eel_gdk_color_parse_with_white_default (color_spec, &color);
-	style->bg[GTK_STATE_NORMAL] = color;
-	style->base[GTK_STATE_NORMAL] = color;
-	style->bg[GTK_STATE_ACTIVE] = color;
-	style->base[GTK_STATE_ACTIVE] = color;
-
-	/* Put the style in the widget. */
-	gtk_widget_set_style (widget, style);
-	gtk_style_unref (style);
+	gtk_widget_modify_style (widget, new_style);
+	gtk_rc_style_unref (new_style);
 }
 
 void
 eel_gtk_widget_set_foreground_color (GtkWidget              *widget,
 					  const char		*color_spec)
 {
-	GtkStyle	*style;
+	GtkRcStyle     *new_style;
 	GdkColor	color;
 
 	g_return_if_fail (GTK_IS_WIDGET (widget));
 
-	style = gtk_widget_get_style (widget);
-
-	/* Make a copy of the style. */
-	style = gtk_style_copy (style);
-
 	eel_gdk_color_parse_with_white_default (color_spec, &color);
-	style->fg[GTK_STATE_NORMAL] = color;
-	style->fg[GTK_STATE_ACTIVE] = color;
+	
+	new_style = get_modifier_style (widget);
+
+	new_style->color_flags[GTK_STATE_NORMAL] |= (GTK_RC_FG | GTK_RC_TEXT);
+	new_style->fg[GTK_STATE_NORMAL] = color;
+	new_style->text[GTK_STATE_NORMAL] = color;
+
+	new_style->color_flags[GTK_STATE_ACTIVE] |= (GTK_RC_FG | GTK_RC_TEXT);
+	new_style->fg[GTK_STATE_ACTIVE] = color;
+	new_style->text[GTK_STATE_ACTIVE] = color;
 
-	/* Put the style in the widget. */
-	gtk_widget_set_style (widget, style);
-	gtk_style_unref (style);
+	gtk_widget_modify_style (widget, new_style);
+	gtk_rc_style_unref (new_style);
 }
 
 GtkWidget *




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]