Blob Blame History Raw
From 0b452d4735c6ef35299e24ffb3faa0cabc5559c3 Mon Sep 17 00:00:00 2001
From: Vincent Untz <vuntz@gnome.org>
Date: Mon, 4 Apr 2011 19:32:56 +0200
Subject: [PATCH] Use the right color for text in GkbdStatus

This is really a big hack: instead of getting the information about how
to draw the font from a GTK+ style, we get it from the GtkStyleContext
from the tray icon widget embedded in the GtkStatusIcon.

To make this happen, we have to fake the GtkStatusIconPrivate structure,
and we rely on the fact that the tray icon widget is the first element
in this structure.

https://bugzilla.gnome.org/show_bug.cgi?id=642703
---
 libgnomekbd/gkbd-indicator-config.c |   98 ++++++++++++++++++-----------------
 libgnomekbd/gkbd-indicator-config.h |   10 ++++
 libgnomekbd/gkbd-status.c           |   65 ++++++++++++++---------
 3 files changed, 100 insertions(+), 73 deletions(-)

diff --git a/libgnomekbd/gkbd-indicator-config.c b/libgnomekbd/gkbd-indicator-config.c
index fdf008b..c678643 100644
--- a/libgnomekbd/gkbd-indicator-config.c
+++ b/libgnomekbd/gkbd-indicator-config.c
@@ -37,7 +37,6 @@
 /**
  * GkbdIndicatorConfig
  */
-#define GTK_STYLE_PATH "*PanelWidget*"
 
 const gchar GKBD_INDICATOR_CONFIG_KEY_SHOW_FLAGS[] = "show-flags";
 const gchar GKBD_INDICATOR_CONFIG_KEY_ENABLED_PLUGINS[] =
@@ -65,26 +64,8 @@ gkbd_indicator_config_load_font (GkbdIndicatorConfig * ind_config)
 	    g_settings_get_int (ind_config->settings,
 				GKBD_INDICATOR_CONFIG_KEY_FONT_SIZE);
 
-	if (ind_config->font_family == NULL ||
-	    ind_config->font_family[0] == '\0') {
-		PangoFontDescription *fd = NULL;
-		GtkStyle *style =
-		    gtk_rc_get_style_by_paths (gtk_settings_get_default (),
-					       GTK_STYLE_PATH,
-					       GTK_STYLE_PATH,
-					       GTK_TYPE_LABEL);
-		if (style != NULL)
-			fd = style->font_desc;
-		if (fd != NULL) {
-			ind_config->font_family =
-			    g_strdup (pango_font_description_get_family
-				      (fd));
-			ind_config->font_size =
-			    pango_font_description_get_size (fd) /
-			    PANGO_SCALE;
-		}
-	}
-	xkl_debug (150, "font: [%s], size %d\n", ind_config->font_family,
+	xkl_debug (150, "font: [%s], size %d\n",
+		   ind_config->font_family ? ind_config->font_family : "(null)",
 		   ind_config->font_size);
 
 }
@@ -96,38 +77,61 @@ gkbd_indicator_config_load_colors (GkbdIndicatorConfig * ind_config)
 	    g_settings_get_string (ind_config->settings,
 				   GKBD_INDICATOR_CONFIG_KEY_FOREGROUND_COLOR);
 
-	if (ind_config->foreground_color == NULL ||
-	    ind_config->foreground_color[0] == '\0') {
-		GtkStyle *style =
-		    gtk_rc_get_style_by_paths (gtk_settings_get_default (),
-					       GTK_STYLE_PATH,
-					       GTK_STYLE_PATH,
-					       GTK_TYPE_LABEL);
-		if (style != NULL) {
-			ind_config->foreground_color =
-			    g_strdup_printf ("%g %g %g", ((double)
-							  style->fg
-							  [GTK_STATE_NORMAL].
-							  red)
-					     / 0x10000, ((double)
-							 style->fg
-							 [GTK_STATE_NORMAL].
-							 green)
-					     / 0x10000, ((double)
-							 style->fg
-							 [GTK_STATE_NORMAL].
-							 blue)
-					     / 0x10000);
-		}
-
-	}
-
 	ind_config->background_color =
 	    g_settings_get_string (ind_config->settings,
 				   GKBD_INDICATOR_CONFIG_KEY_BACKGROUND_COLOR);
 }
 
 void
+gkbd_indicator_config_get_font_for_widget (GkbdIndicatorConfig * ind_config,
+					   GtkWidget           * widget,
+					   gchar               ** font_family,
+					   int                  * font_size)
+{
+	GtkStyleContext *context;
+	const PangoFontDescription *fd = NULL;
+
+	g_return_if_fail (GTK_IS_WIDGET (widget));
+
+	if (ind_config->font_family != NULL &&
+	    ind_config->font_family[0] != '\0') {
+		if (font_family)
+			*font_family = g_strdup (ind_config->font_family);
+		if (font_size)
+			*font_size = ind_config->font_size;
+
+		return;
+	}
+
+	context = gtk_widget_get_style_context (widget);
+	fd = gtk_style_context_get_font (context, GTK_STATE_FLAG_NORMAL);
+
+	if (font_family)
+		*font_family = g_strdup (pango_font_description_get_family (fd));
+	if (font_size)
+		*font_size = pango_font_description_get_size (fd) / PANGO_SCALE;
+}
+
+gchar *
+gkbd_indicator_config_get_fg_color_for_widget (GkbdIndicatorConfig * ind_config,
+					       GtkWidget           * widget)
+{
+	GtkStyleContext *context;
+	GdkRGBA          rgba;
+
+	g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
+
+	if (ind_config->foreground_color != NULL &&
+	    ind_config->foreground_color[0] != '\0')
+		return g_strdup (ind_config->foreground_color);
+
+	context = gtk_widget_get_style_context (widget);
+	gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL, &rgba);
+
+	return g_strdup_printf ("%g %g %g", rgba.red, rgba.green, rgba.blue);
+}
+
+void
 gkbd_indicator_config_refresh_style (GkbdIndicatorConfig * ind_config)
 {
 	g_free (ind_config->font_family);
diff --git a/libgnomekbd/gkbd-indicator-config.h b/libgnomekbd/gkbd-indicator-config.h
index 2638895..9b9d935 100644
--- a/libgnomekbd/gkbd-indicator-config.h
+++ b/libgnomekbd/gkbd-indicator-config.h
@@ -62,6 +62,16 @@ extern void gkbd_indicator_config_load (GkbdIndicatorConfig
 extern void gkbd_indicator_config_save (GkbdIndicatorConfig *
 					applet_config);
 
+extern void
+gkbd_indicator_config_get_font_for_widget (GkbdIndicatorConfig * ind_config,
+					   GtkWidget           * widget,
+					   gchar               ** font_family,
+					   int                  * font_size);
+
+extern gchar *
+gkbd_indicator_config_get_fg_color_for_widget (GkbdIndicatorConfig * ind_config,
+					       GtkWidget           * widget);
+
 extern void gkbd_indicator_config_refresh_style (GkbdIndicatorConfig *
 						 applet_config);
 
diff --git a/libgnomekbd/gkbd-status.c b/libgnomekbd/gkbd-status.c
index 5785e4c..276fe54 100644
--- a/libgnomekbd/gkbd-status.c
+++ b/libgnomekbd/gkbd-status.c
@@ -59,22 +59,26 @@ static gki_globals globals;
 
 G_DEFINE_TYPE (GkbdStatus, gkbd_status, GTK_TYPE_STATUS_ICON)
 
+typedef struct {
+	GtkWidget *tray_icon;
+} GkbdStatusPrivHack;
+
 static void
 gkbd_status_global_init (void);
 static void
 gkbd_status_global_term (void);
 static GdkPixbuf *
-gkbd_status_prepare_drawing (int group);
+gkbd_status_prepare_drawing (GkbdStatus * gki, int group);
 static void
 gkbd_status_set_current_page_for_group (GkbdStatus * gki, int group);
 static void
 gkbd_status_set_current_page (GkbdStatus * gki);
 static void
-gkbd_status_reinit_globals (void);
+gkbd_status_reinit_globals (GkbdStatus * gki);
 static void
 gkbd_status_cleanup_icons (void);
 static void
-gkbd_status_fill_icons (void);
+gkbd_status_fill_icons (GkbdStatus * gki);
 static void
 gkbd_status_set_tooltips (GkbdStatus * gki, const char *str);
 
@@ -97,8 +101,8 @@ gkbd_status_cleanup_icons ()
 	}
 }
 
-void
-gkbd_status_fill_icons ()
+static void
+gkbd_status_fill_icons (GkbdStatus * gki)
 {
 	int grp;
 	int total_groups =
@@ -106,7 +110,7 @@ gkbd_status_fill_icons ()
 				       (globals.config));
 
 	for (grp = 0; grp < total_groups; grp++) {
-		GdkPixbuf *page = gkbd_status_prepare_drawing (grp);
+		GdkPixbuf *page = gkbd_status_prepare_drawing (gki, grp);
 		globals.icons = g_slist_append (globals.icons, page);
 	}
 }
@@ -119,9 +123,12 @@ gkbd_status_activate (GkbdStatus * gki)
 }
 
 static void
-gkbd_status_render_cairo (cairo_t * cr, int group)
+gkbd_status_render_cairo (GkbdStatusPrivHack * gkh, cairo_t * cr, int group)
 {
 	double r, g, b;
+	GdkColor *fg_color;
+	gchar *font_family;
+	int font_size;
 	PangoFontDescription *pfd;
 	PangoContext *pcc;
 	PangoLayout *pl;
@@ -146,28 +153,30 @@ gkbd_status_render_cairo (cairo_t * cr, int group)
 		}
 	}
 
-	if (ind_cfg->foreground_color != NULL &&
-	    ind_cfg->foreground_color[0] != 0) {
-		if (sscanf
-		    (ind_cfg->foreground_color, "%lg %lg %lg", &r,
-		     &g, &b) == 3) {
-			cairo_set_source_rgb (cr, r, g, b);
-		}
-	}
+	g_object_get (gkh->tray_icon, "fg-color", &fg_color, NULL);
+	cairo_set_source_rgb (cr, fg_color->red, fg_color->green, fg_color->blue);
+	gdk_color_free (fg_color);
+
+	gkbd_indicator_config_get_font_for_widget (ind_cfg,
+						   gkh->tray_icon,
+						   &font_family,
+						   &font_size);
 
-	if (ind_cfg->font_family != NULL && ind_cfg->font_family[0] != 0) {
-		cairo_select_font_face (cr, ind_cfg->font_family,
+	if (font_family != NULL && font_family[0] != 0) {
+		cairo_select_font_face (cr, font_family,
 					CAIRO_FONT_SLANT_NORMAL,
 					CAIRO_FONT_WEIGHT_NORMAL);
 	}
 
 	pfd = pango_font_description_new ();
-	pango_font_description_set_family (pfd, ind_cfg->font_family);
+	pango_font_description_set_family (pfd, font_family);
 	pango_font_description_set_style (pfd, PANGO_STYLE_NORMAL);
 	pango_font_description_set_weight (pfd, PANGO_WEIGHT_NORMAL);
 	pango_font_description_set_size (pfd,
 					 ind_cfg->font_size * PANGO_SCALE);
 
+	g_free (font_family);
+
 	pcc = pango_cairo_create_context (cr);
 
 	fo = cairo_font_options_copy (gdk_screen_get_font_options
@@ -261,7 +270,7 @@ convert_bgra_to_rgba (guint8 const *src, guint8 * dst, int width,
 }
 
 static GdkPixbuf *
-gkbd_status_prepare_drawing (int group)
+gkbd_status_prepare_drawing (GkbdStatus * gki, int group)
 {
 	GError *gerror = NULL;
 	char *image_filename;
@@ -321,7 +330,8 @@ gkbd_status_prepare_drawing (int group)
 						globals.current_height);
 		unsigned char *cairo_data;
 		guchar *pixbuf_data;
-		gkbd_status_render_cairo (cairo_create (cs), group);
+		gkbd_status_render_cairo ((GkbdStatusPrivHack *) GTK_STATUS_ICON (gki)->priv,
+					  cairo_create (cs), group);
 		cairo_data = cairo_image_surface_get_data (cs);
 #if 0
 		char pngfilename[20];
@@ -372,11 +382,11 @@ gkbd_status_update_tooltips (GkbdStatus * gki)
 	}
 }
 
-void
-gkbd_status_reinit_globals ()
+static void
+gkbd_status_reinit_globals (GkbdStatus * gki)
 {
 	gkbd_status_cleanup_icons ();
-	gkbd_status_fill_icons ();
+	gkbd_status_fill_icons (gki);
 }
 
 void
@@ -389,8 +399,11 @@ gkbd_status_reinit_ui (GkbdStatus * gki)
 static void
 gkbd_status_cfg_callback (GkbdConfiguration * configuration)
 {
+	GSList *objects;
 	xkl_debug (150, "Config changed: reinit ui\n");
-	gkbd_status_reinit_globals ();
+	objects = gkbd_configuration_get_all_objects (configuration);
+	if (objects)
+		gkbd_status_reinit_globals (objects->data);
 	ForAllObjects (configuration) {
 		gkbd_status_reinit_ui (GKBD_STATUS (gki));
 	} NextObject ()
@@ -499,7 +512,7 @@ gkbd_status_size_changed (GkbdStatus * gki, gint size)
 	if (globals.current_height != size) {
 		globals.current_height = size;
 		globals.current_width = size * 3 / 2;
-		gkbd_status_reinit_globals ();
+		gkbd_status_reinit_globals (gki);
 		gkbd_status_reinit_ui (gki);
 	}
 }
@@ -511,7 +524,7 @@ gkbd_status_theme_changed (GtkSettings * settings, GParamSpec * pspec,
 	xkl_debug (150, "Theme changed\n");
 	gkbd_indicator_config_refresh_style
 	    (gkbd_configuration_get_indicator_config (globals.config));
-	gkbd_status_reinit_globals ();
+	gkbd_status_reinit_globals (gki);
 	gkbd_status_reinit_ui (gki);
 }
 
-- 
1.7.4.1