diff --git a/src/common/text.c b/src/common/text.c
index 4fb653e7..e22ceedf 100644
--- a/src/common/text.c
+++ b/src/common/text.c
@@ -1751,59 +1751,39 @@ text_event_uses_color (const char *text, int color)
return FALSE;
}
-char *
-text_color_event_list (int color)
+char **
+text_color_event_names (int color, int *count)
{
- GString *events;
- GString *tip;
- int count = 0;
- int line_len = 0;
+ GPtrArray *names;
+ int found = 0;
int i;
- events = g_string_new (NULL);
+ if (count)
+ *count = 0;
+
+ names = g_ptr_array_new ();
for (i = 0; i < NUM_XP; i++)
{
- const char *name;
const char *text = pntevts_text[i] ? pntevts_text[i] : te[i].def;
- int name_len;
if (!text_event_uses_color (text, color))
continue;
- name = _(te[i].name);
- name_len = strlen (name);
- if (count)
- {
- if (line_len + name_len + 2 > 76)
- {
- g_string_append (events, ",\n");
- line_len = 0;
- }
- else
- {
- g_string_append (events, ", ");
- line_len += 2;
- }
- }
-
- g_string_append (events, name);
- line_len += name_len;
- count++;
+ g_ptr_array_add (names, g_strdup (_(te[i].name)));
+ found++;
}
- if (!count)
+ if (!found)
{
- g_string_free (events, TRUE);
- return g_strdup (_("No text events use this color."));
+ g_ptr_array_free (names, TRUE);
+ return NULL;
}
- tip = g_string_new (NULL);
- g_string_append_printf (tip, _("Text events using this color (%d):"), count);
- g_string_append_c (tip, '\n');
- g_string_append (tip, events->str);
- g_string_free (events, TRUE);
- return g_string_free (tip, FALSE);
+ g_ptr_array_add (names, NULL);
+ if (count)
+ *count = found;
+ return (char **) g_ptr_array_free (names, FALSE);
}
static void
diff --git a/src/common/text.h b/src/common/text.h
index 32d58c30..f164263e 100644
--- a/src/common/text.h
+++ b/src/common/text.h
@@ -53,7 +53,7 @@ int pevt_build_string (const char *input, char **output, int *max_arg);
int pevent_load (char *filename);
void pevent_make_pntevts (void);
int text_color_of (char *name);
-char *text_color_event_list (int color);
+char **text_color_event_names (int color, int *count);
void text_emit (int index, session *sess, char *a, char *b, char *c, char *d,
time_t timestamp);
int text_emit_by_name (char *name, session *sess, time_t timestamp,
diff --git a/src/fe-gtk/theme/tests/test-theme-preferences-gtk3-populate.c b/src/fe-gtk/theme/tests/test-theme-preferences-gtk3-populate.c
index 38962b2b..00875c1e 100644
--- a/src/fe-gtk/theme/tests/test-theme-preferences-gtk3-populate.c
+++ b/src/fe-gtk/theme/tests/test-theme-preferences-gtk3-populate.c
@@ -70,11 +70,13 @@ load_text_events (void)
{
}
-char *
-text_color_event_list (int color)
+char **
+text_color_event_names (int color, int *count)
{
(void)color;
- return g_strdup ("No text events use this color.");
+ if (count)
+ *count = 0;
+ return NULL;
}
gboolean
diff --git a/src/fe-gtk/theme/theme-preferences.c b/src/fe-gtk/theme/theme-preferences.c
index 3ddc7d6e..e6e925ef 100644
--- a/src/fe-gtk/theme/theme-preferences.c
+++ b/src/fe-gtk/theme/theme-preferences.c
@@ -38,7 +38,7 @@
#include "theme-runtime.h"
extern void load_text_events (void);
-extern char *text_color_event_list (int color);
+extern char **text_color_event_names (int color, int *count);
typedef struct
{
@@ -244,6 +244,9 @@ theme_preferences_stage_discard (void)
static void
theme_preferences_show_import_error (GtkWidget *button, const char *message);
+static void
+theme_preferences_color_set_tooltip (GtkWidget *widget, ThemeSemanticToken token);
+
static void
theme_preferences_manager_row_free (gpointer data)
{
@@ -269,15 +272,6 @@ theme_preferences_manager_ui_free (gpointer data)
g_free (ui);
}
-static char *
-theme_preferences_color_events_tooltip (ThemeSemanticToken token)
-{
- if (token < THEME_TOKEN_MIRC_0 || token > THEME_TOKEN_MIRC_31)
- return NULL;
-
- return text_color_event_list (token - THEME_TOKEN_MIRC_0);
-}
-
static void
theme_preferences_manager_update_preview (theme_color_manager_ui *ui)
{
@@ -491,6 +485,7 @@ theme_preferences_color_response_cb (GtkDialog *dialog, gint response_id, gpoint
data->color_change_flag,
TRUE);
theme_preferences_color_button_apply (data->button, &rgba);
+ theme_preferences_color_set_tooltip (data->button, data->token);
theme_preferences_manager_update_preview ((theme_color_manager_ui *) data->manager_ui);
}
@@ -569,6 +564,113 @@ theme_preferences_token_display_name (ThemeSemanticToken token)
}
}
+static char *
+theme_preferences_color_tooltip_markup (ThemeSemanticToken token)
+{
+ GString *tip;
+ GdkRGBA rgba;
+ char *display;
+ char *hex;
+ char *escaped;
+ char **names;
+ int count = 0;
+
+ if (token < THEME_TOKEN_MIRC_0 || token > THEME_TOKEN_MIRC_31)
+ return NULL;
+
+ if (!theme_preferences_staged_get_color (token, &rgba))
+ return NULL;
+
+ tip = g_string_new (NULL);
+
+ display = theme_preferences_token_display_name (token);
+ hex = theme_preferences_format_hex (&rgba);
+ escaped = g_markup_escape_text (display, -1);
+ g_string_append_printf (tip,
+ "\xe2\x80\x83\xe2\x80\x83 %s %s",
+ hex, escaped, hex);
+ g_free (escaped);
+ g_free (display);
+
+ names = text_color_event_names (token - THEME_TOKEN_MIRC_0, &count);
+ if (names)
+ {
+ int line_target;
+ int line_len = 0;
+ int i;
+
+ display = g_strdup_printf (ngettext ("Used by %d text event",
+ "Used by %d text events", count), count);
+ escaped = g_markup_escape_text (display, -1);
+ g_string_append_printf (tip,
+ "\n%s\n\n",
+ escaped);
+ g_free (escaped);
+ g_free (display);
+
+ /* Explicit line breaks keep the tooltip geometry stable;
+ * heavily-used colors get wider lines so the full list
+ * stays on screen. */
+ if (count <= 12)
+ line_target = 44;
+ else if (count <= 40)
+ line_target = 60;
+ else
+ line_target = 76;
+
+ for (i = 0; i < count; i++)
+ {
+ int name_len = (int) g_utf8_strlen (names[i], -1);
+
+ if (i)
+ {
+ if (line_len + name_len + 5 > line_target)
+ {
+ g_string_append_c (tip, '\n');
+ line_len = 0;
+ }
+ else
+ {
+ g_string_append (tip, " \xc2\xb7 ");
+ line_len += 5;
+ }
+ }
+ escaped = g_markup_escape_text (names[i], -1);
+ g_string_append (tip, escaped);
+ line_len += name_len;
+ g_free (escaped);
+ }
+ g_string_append (tip, "");
+ g_strfreev (names);
+ }
+ else
+ {
+ escaped = g_markup_escape_text (_("Not used by any text events"), -1);
+ g_string_append_printf (tip,
+ "\n%s",
+ escaped);
+ g_free (escaped);
+ }
+
+ g_free (hex);
+ return g_string_free (tip, FALSE);
+}
+
+/* Static markup tooltips only: building tooltip widgets from a
+ * query-tooltip handler makes GtkTooltip flicker on some setups, so the
+ * markup is set once and refreshed whenever the color changes. */
+static void
+theme_preferences_color_set_tooltip (GtkWidget *widget, ThemeSemanticToken token)
+{
+ char *markup = theme_preferences_color_tooltip_markup (token);
+
+ if (!markup)
+ return;
+
+ gtk_widget_set_tooltip_markup (widget, markup);
+ g_free (markup);
+}
+
static void
theme_preferences_manager_row_apply (theme_color_manager_row *row, const GdkRGBA *rgba)
{
@@ -579,6 +681,7 @@ theme_preferences_manager_row_apply (theme_color_manager_row *row, const GdkRGBA
hex = theme_preferences_format_hex (rgba);
gtk_entry_set_text (GTK_ENTRY (row->entry), hex);
g_free (hex);
+ theme_preferences_color_set_tooltip (row->row, row->token);
}
static void
@@ -894,19 +997,7 @@ theme_preferences_create_color_manager_dialog (GtkWindow *parent, gboolean *colo
if (theme_preferences_staged_get_color (token, &rgba))
theme_preferences_manager_row_apply (row, &rgba);
- {
- char *tip = theme_preferences_color_events_tooltip (token);
- if (tip)
- {
- gtk_widget_set_tooltip_text (list_row, tip);
- gtk_widget_set_tooltip_text (hbox, tip);
- gtk_widget_set_tooltip_text (name, tip);
- gtk_widget_set_tooltip_text (preview, tip);
- gtk_widget_set_tooltip_text (button, tip);
- gtk_widget_set_tooltip_text (entry, tip);
- g_free (tip);
- }
- }
+ theme_preferences_color_set_tooltip (list_row, token);
g_signal_connect (G_OBJECT (button), "clicked",
G_CALLBACK (theme_preferences_manager_pick_cb), row);
@@ -1222,15 +1313,7 @@ theme_preferences_create_color_button (GtkWidget *table,
g_object_set_data (G_OBJECT (but), "zoitechat-color-box", box);
g_object_set_data (G_OBJECT (but), "zoitechat-theme-token", GINT_TO_POINTER (token));
g_object_set_data (G_OBJECT (but), "zoitechat-theme-color-change", color_change_flag);
- {
- char *tip = theme_preferences_color_events_tooltip (token);
- if (tip)
- {
- gtk_widget_set_tooltip_text (but, tip);
- gtk_widget_set_tooltip_text (box, tip);
- g_free (tip);
- }
- }
+ theme_preferences_color_set_tooltip (but, token);
gtk_grid_attach (GTK_GRID (table), but, col, row, 1, 1);
g_signal_connect (G_OBJECT (but), "clicked", G_CALLBACK (theme_preferences_color_cb), parent);
if (theme_preferences_staged_get_color (token, &color))