Color updates for dark themes in the conversation tabs and the buddy list. release-2.x.y

Thu, 24 Aug 2017 21:18:49 -0500

author
Alyssa Rosenzweig <alyssa@rosenzweig.io>
date
Thu, 24 Aug 2017 21:18:49 -0500
branch
release-2.x.y
changeset 38698
9b2ec7257913
parent 38601
e0a7ee3692a6
child 38699
e7b5011e4728

Color updates for dark themes in the conversation tabs and the buddy list.

pidgin/gtkblist.c file | annotate | diff | comparison | revisions
pidgin/gtkconv.c file | annotate | diff | comparison | revisions
pidgin/gtkimhtml.c file | annotate | diff | comparison | revisions
pidgin/gtkimhtml.h file | annotate | diff | comparison | revisions
--- a/pidgin/gtkblist.c	Mon Jul 24 21:19:47 2017 -0500
+++ b/pidgin/gtkblist.c	Thu Aug 24 21:18:49 2017 -0500
@@ -4178,7 +4178,7 @@
 gchar *
 pidgin_blist_get_name_markup(PurpleBuddy *b, gboolean selected, gboolean aliased)
 {
-	const char *name, *name_color, *name_font, *status_color, *status_font;
+	const char *name, *name_color, *name_font, *status_color, *status_font, *dim_grey;
 	char *text = NULL;
 	PurplePlugin *prpl;
 	PurplePluginProtocolInfo *prpl_info = NULL;
@@ -4281,13 +4281,15 @@
 	theme = pidgin_blist_get_theme();
 	name_color = NULL;
 
+	dim_grey = gtk_is_dark_mode(NULL) ? "light slate grey" : "dim grey";
+
 	if (theme) {
 		if (purple_presence_is_idle(presence)) {
 			namefont = statusfont = pidgin_blist_theme_get_idle_text_info(theme);
-			name_color = "dim grey";
+			name_color = dim_grey;
 		} else if (!purple_presence_is_online(presence)) {
 			namefont = pidgin_blist_theme_get_offline_text_info(theme);
-			name_color = "dim grey";
+			name_color = dim_grey;
 			statusfont = pidgin_blist_theme_get_status_text_info(theme);
 		} else if (purple_presence_is_available(presence)) {
 			namefont = pidgin_blist_theme_get_online_text_info(theme);
@@ -4301,14 +4303,14 @@
 				&& (purple_presence_is_idle(presence)
 							|| !purple_presence_is_online(presence)))
 		{
-			name_color = "dim grey";
+			name_color = dim_grey;
 		}
 	}
 
 	name_color = theme_font_get_color_default(namefont, name_color);
 	name_font = theme_font_get_face_default(namefont, "");
 
-	status_color = theme_font_get_color_default(statusfont, "dim grey");
+	status_color = theme_font_get_color_default(statusfont, dim_grey);
 	status_font = theme_font_get_face_default(statusfont, "");
 
 	if (aliased && selected) {
@@ -6535,7 +6537,7 @@
 				textcolor = pidgin_theme_font_get_color_describe(pair);
 			else
 				/* If no theme them default to making idle buddy names grey */
-				textcolor = "dim grey";
+				textcolor = gtk_is_dark_mode(NULL) ? "light slate grey" : "dim grey";
 
 			if (textcolor) {
 				idle = g_strdup_printf("<span color='%s' font_desc='%s'>%d:%02d</span>",
--- a/pidgin/gtkconv.c	Mon Jul 24 21:19:47 2017 -0500
+++ b/pidgin/gtkconv.c	Thu Aug 24 21:18:49 2017 -0500
@@ -8176,41 +8176,57 @@
 	purple_signal_connect(purple_conversations_get_handle(), "wrote-chat-msg", handle,
 			PURPLE_CALLBACK(wrote_msg_update_unseen_cb), NULL);
 
-	{
-		/* Set default tab colors */
-		GString *str = g_string_new(NULL);
-		GtkSettings *settings = gtk_settings_get_default();
-		GtkStyle *parent = gtk_rc_get_style_by_paths(settings, "tab-container.tab-label*", NULL, G_TYPE_NONE), *now;
-		struct {
-			const char *stylename;
-			const char *labelname;
-			const char *color;
-		} styles[] = {
-			{"pidgin_tab_label_typing_default", "tab-label-typing", "#4e9a06"},
-			{"pidgin_tab_label_typed_default", "tab-label-typed", "#c4a000"},
-			{"pidgin_tab_label_attention_default", "tab-label-attention", "#006aff"},
-			{"pidgin_tab_label_unreadchat_default", "tab-label-unreadchat", "#cc0000"},
-			{"pidgin_tab_label_event_default", "tab-label-event", "#888a85"},
-			{NULL, NULL, NULL}
-		};
-		int iter;
-		for (iter = 0; styles[iter].stylename; iter++) {
-			now = gtk_rc_get_style_by_paths(settings, styles[iter].labelname, NULL, G_TYPE_NONE);
-			if (parent == now ||
-					(parent && now && parent->rc_style == now->rc_style)) {
-				g_string_append_printf(str, "style \"%s\" {\n"
-						"fg[ACTIVE] = \"%s\"\n"
-						"}\n"
-						"widget \"*%s\" style \"%s\"\n",
-						styles[iter].stylename,
-						styles[iter].color,
-						styles[iter].labelname, styles[iter].stylename);
-			}
-		}
-		gtk_rc_parse_string(str->str);
-		g_string_free(str, TRUE);
-		gtk_rc_reset_styles(settings);
-	}
+}
+
+/* Invalidate the first tab color set */
+static gboolean tab_color_fuse = TRUE;
+
+static void
+pidgin_conversations_set_tab_colors(void)
+{
+	/* Set default tab colors */
+	GString *str = g_string_new(NULL);
+	GtkSettings *settings = gtk_settings_get_default();
+	GtkStyle *parent = gtk_rc_get_style_by_paths(settings, "tab-container.tab-label*", NULL, G_TYPE_NONE), *now;
+	struct {
+		const char *stylename;
+		const char *labelname;
+		const char *color;
+	} styles[] = {
+		{"pidgin_tab_label_typing_default", "tab-label-typing", "#4e9a06"},
+		{"pidgin_tab_label_typed_default", "tab-label-typed", "#c4a000"},
+		{"pidgin_tab_label_attention_default", "tab-label-attention", "#006aff"},
+		{"pidgin_tab_label_unreadchat_default", "tab-label-unreadchat", "#cc0000"},
+		{"pidgin_tab_label_event_default", "tab-label-event", "#888a85"},
+		{NULL, NULL, NULL}
+	};
+	int iter;
+
+	if(tab_color_fuse) {
+		tab_color_fuse = FALSE;
+		return;
+	}
+
+	for (iter = 0; styles[iter].stylename; iter++) {
+		now = gtk_rc_get_style_by_paths(settings, styles[iter].labelname, NULL, G_TYPE_NONE);
+		if (parent == now ||
+				(parent && now && parent->rc_style == now->rc_style)) {
+			GdkColor color;
+			gdk_color_parse(styles[iter].color, &color);
+			gtk_adjust_color_dark_mode(gtk_widget_get_default_style(), &color);
+
+			g_string_append_printf(str, "style \"%s\" {\n"
+					"fg[ACTIVE] = \"%s\"\n"
+					"}\n"
+					"widget \"*%s\" style \"%s\"\n",
+					styles[iter].stylename,
+					gdk_color_to_string(&color),
+					styles[iter].labelname, styles[iter].stylename);
+		}
+	}
+	gtk_rc_parse_string(str->str);
+	g_string_free(str, TRUE);
+	gtk_rc_reset_styles(settings);
 }
 
 void
@@ -9385,6 +9401,9 @@
 		gtk_window_iconify(GTK_WINDOW(win->window));
 #endif
 
+	/* Fix colours */
+	pidgin_conversations_set_tab_colors();
+
 	return win;
 }
 
@@ -10252,6 +10271,9 @@
 	gdk_color_parse(DEFAULT_HIGHLIGHT_COLOR, &nick_highlight);
 	gdk_color_parse(DEFAULT_SEND_COLOR, &send_color);
 
+	gtk_adjust_color_dark_mode(NULL, &nick_highlight);
+	gtk_adjust_color_dark_mode(NULL, &send_color);
+
 	srand(background.red + background.green + background.blue + 1);
 
 	breakout_time = time(NULL) + 3;
--- a/pidgin/gtkimhtml.c	Mon Jul 24 21:19:47 2017 -0500
+++ b/pidgin/gtkimhtml.c	Thu Aug 24 21:18:49 2017 -0500
@@ -426,6 +426,49 @@
 		gtk_imhtml_scroll_to_end(imhtml, FALSE);
 }
 
+/* Assume light mode */
+static gboolean dark_mode_cache = FALSE;
+
+gboolean
+gtk_is_dark_mode(GtkStyle *style) {
+	GdkColor bg;
+
+	if (!style) {
+		return dark_mode_cache;
+	}
+
+	bg = style->base[GTK_STATE_NORMAL];
+
+	if (bg.red != 0xFFFF || bg.green != 0xFFFF || bg.blue != 0xFFFF) {
+		dark_mode_cache =  ((int) bg.red + (int) bg.green + (int) bg.blue) < (65536 * 3 / 2);
+	}
+
+	return dark_mode_cache;
+}
+
+void
+gtk_adjust_color_dark_mode(GtkStyle *style, GdkColor *color) {
+	if (gtk_is_dark_mode(style)) {
+		gdouble r, g, b, h, s, v;
+
+		r = ((gdouble) color->red) / 65535.0;
+		g = ((gdouble) color->green) / 65535.0;
+		b = ((gdouble) color->blue) / 65535.0;
+
+		gtk_rgb_to_hsv(r, g, b, &h, &s, &v);
+
+		v += 0.3;
+		v = v > 1.0 ? 1.0 : v;
+		s = 0.7;
+
+		gtk_hsv_to_rgb(h, s, v, &r, &g, &b);
+
+		color->red = (guint16) (r * 65535.0);
+		color->green = (guint16) (g * 65535.0);
+		color->blue = (guint16) (b * 65535.0);
+	}
+}
+
 #define DEFAULT_SEND_COLOR "#204a87"
 #define DEFAULT_RECV_COLOR "#cc0000"
 #define DEFAULT_HIGHLIGHT_COLOR "#AF7F00"
@@ -469,6 +512,7 @@
 		} else {
 			GdkColor defcolor;
 			gdk_color_parse(styles[i].def, &defcolor);
+			gtk_adjust_color_dark_mode(gtk_widget_get_style(widget), &defcolor);
 			g_object_set(tag, "foreground-gdk", &defcolor, NULL);
 		}
 	}
--- a/pidgin/gtkimhtml.h	Mon Jul 24 21:19:47 2017 -0500
+++ b/pidgin/gtkimhtml.h	Thu Aug 24 21:18:49 2017 -0500
@@ -974,6 +974,26 @@
  */
 void gtk_imhtml_set_populate_primary_clipboard(GtkIMHtml *imhtml, gboolean populate);
 
+/**
+ * Returns TRUE if dark mode is enabled and foreground colours should be invertred
+ *
+ * @param style The GtkStyle in use, or NULL to use a cached version.
+ *
+ * @return @c TRUE if dark mode, @c FALSE otherwise
+ */
+
+gboolean gtk_is_dark_mode(GtkStyle *style);
+
+/**
+ * Lighten a color if dark mode is enabled.
+ *
+ * @param style The GtkStyle in use.
+ *
+ * @param color Color to be lightened. Transformed color will be written here.
+ */
+
+void gtk_adjust_color_dark_mode(GtkStyle *style, GdkColor *color);
+
 /*@}*/
 
 #ifdef __cplusplus

mercurial