--- a/ChangeLog.API Mon Jun 14 23:59:42 2021 -0500
+++ b/ChangeLog.API Tue Jun 15 00:27:09 2021 -0500
@@ -576,7 +576,6 @@
* purple_time_build. Use g_date_time_new* instead.
* purple_time_format. Use g_date_time_format instead.
* purple_timeout_*. Use g_timeout_* or g_idle_* instead.
- * pidgin_tooltip_setup_for_widget
* purple_txt_resolve_account
* PurpleType, use GType instead.
@@ -689,6 +688,7 @@
+ * pidgin_blist_draw_tooltip * pidgin_blist_layout_get_type
@@ -726,6 +726,7 @@
* pidgin_blist_theme_set_status_text_info
* pidgin_blist_theme_set_unread_message_nick_said_text_info
* pidgin_blist_theme_set_unread_message_text_info
+ * pidgin_blist_tooltip_destroy * pidgin_blist_update_account_error_state
* PidginBuddyList.connection_errors
@@ -785,6 +786,13 @@
* pidgin_theme_font_set_font_face
* pidgin_toggle_sensitive, pidgin_toggle_sensitive_array, and
pidgin_toggle_showhide; use g_object_bind_property instead
+ * PidginTooltipCreateForTree + * pidgin_tooltip_destroy + * pidgin_tooltip_setup_for_treeview + * pidgin_tooltip_setup_for_widget * struct _GtkIMHtmlAnimation
* struct _GtkIMHtmlFontDetail
--- a/pidgin/gtkblist.c Mon Jun 14 23:59:42 2021 -0500
+++ b/pidgin/gtkblist.c Tue Jun 15 00:27:09 2021 -0500
@@ -52,7 +52,6 @@
#include "pidgin/pidginplugininfo.h"
#include "pidginscrollbook.h"
#include "pidgin/pidginstylecontext.h"
-#include "pidgin/pidgintooltip.h"
#include "pidgin/pidginwindow.h"
@@ -707,7 +706,7 @@
- pidgin_blist_tooltip_destroy();
+ gtk_widget_trigger_tooltip_query(gtkblist->treeview); path = gtk_tree_model_get_path(GTK_TREE_MODEL(gtkblist->treemodel), &iter);
g_object_set(G_OBJECT(gtkblist->text_rend), "editable", TRUE, NULL);
@@ -1192,7 +1191,7 @@
purple_blist_node_set_bool(node, "collapsed", FALSE);
- pidgin_blist_tooltip_destroy();
+ gtk_widget_trigger_tooltip_query(gtkblist->treeview); @@ -1227,7 +1226,7 @@
pidgin_blist_update_contact(NULL, cnode);
- pidgin_blist_tooltip_destroy();
+ gtk_widget_trigger_tooltip_query(gtkblist->treeview); } else if(PURPLE_IS_CONTACT(node)) {
pidgin_blist_collapse_contact_cb(NULL, node);
@@ -1922,10 +1921,6 @@
menu = create_buddy_menu(node, b);
- pidgin_blist_tooltip_destroy();
/* Now display the menu */
gtk_widget_show_all(menu);
@@ -2141,14 +2136,6 @@
-static void pidgin_blist_drag_begin(GtkWidget *widget,
- GdkDragContext *drag_context, gpointer user_data)
- pidgin_blist_tooltip_destroy();
static void pidgin_blist_drag_data_get_cb(GtkWidget *widget,
@@ -2711,369 +2698,6 @@
- * +--- STATUS_SIZE +--- td->avatar_width
- * | +-- td->name_width |
- * +----+ +-------+ +---------+
- * +-------------------------------------------+
- * | [ = [ |--- TOOLTIP_BORDER
- *name_height --+-| ######[BuddyName = PP [ AAAAAAAAAAA |--+
- * | | ######[ = PP [ AAAAAAAAAAA | |
- * STATUS SIZE -| | ######[[[[[[[[[[[[[[[[[[[[[ AAAAAAAAAAA | |
- * +--+-| ######[Account: So-and-so [ AAAAAAAAAAA | |-- td->avatar_height
- * | | [Idle: 4h 15m [ AAAAAAAAAAA | |
- * height --+ | [Foo: Bar, Baz [ AAAAAAAAAAA | |
- * | | [Status: Awesome [ AAAAAAAAAAA |--+
- * +----| [Stop: Hammer Time [ |
- * | [ [ |--- TOOLTIP_BORDER
- * +-------------------------------------------+
- * | +----------------+ |
- * +---- TOOLTIP_BORDER +---- TOOLTIP_BORDER
-#define TOOLTIP_BORDER 12
-#define PROTOCOL_SIZE 16
- PangoLayout *name_layout;
- GdkPixbuf *protocol_icon;
- GdkPixbuf *status_icon;
- gboolean avatar_is_protocol_icon;
-static PangoLayout * create_pango_layout(const char *markup, int *width, int *height)
- layout = gtk_widget_create_pango_layout(gtkblist->tipwindow, NULL);
- pango_layout_set_markup(layout, markup, -1);
- pango_layout_set_wrap(layout, PANGO_WRAP_WORD);
- pango_layout_set_width(layout, 300000);
- pango_layout_get_size (layout, &w, &h);
- *width = PANGO_PIXELS(w);
- *height = PANGO_PIXELS(h);
-static struct tooltip_data * create_tip_for_account(PurpleAccount *account)
- struct tooltip_data *td = g_new0(struct tooltip_data, 1);
- td->status_icon = pidgin_create_protocol_icon(account, PIDGIN_PROTOCOL_ICON_SMALL);
- /* Yes, status_icon, not protocol_icon */
- if (purple_account_is_disconnected(account))
- gdk_pixbuf_saturate_and_pixelate(td->status_icon, td->status_icon, 0.0, FALSE);
- td->layout = create_pango_layout(purple_account_get_username(account), &td->width, &td->height);
- td->padding = SMALL_SPACE;
-static struct tooltip_data * create_tip_for_node(PurpleBlistNode *node, gboolean full)
- struct tooltip_data *td = g_new0(struct tooltip_data, 1);
- PurpleAccount *account = NULL;
- char *tmp = NULL, *node_name = NULL, *tooltip_text = NULL;
- if (PURPLE_IS_BUDDY(node)) {
- account = purple_buddy_get_account((PurpleBuddy*)(node));
- } else if (PURPLE_IS_CHAT(node)) {
- account = purple_chat_get_account((PurpleChat*)(node));
- td->padding = TOOLTIP_BORDER;
- td->status_icon = pidgin_blist_get_status_icon(node, PIDGIN_STATUS_ICON_LARGE);
- td->avatar = pidgin_blist_get_buddy_icon(node, !full, FALSE);
- td->protocol_icon = pidgin_create_protocol_icon(account, PIDGIN_PROTOCOL_ICON_SMALL);
- tooltip_text = pidgin_get_tooltip_text(node, full);
- if (tooltip_text && *tooltip_text) {
- td->layout = create_pango_layout(tooltip_text, &td->width, &td->height);
- if (PURPLE_IS_BUDDY(node)) {
- tmp = g_markup_escape_text(purple_buddy_get_name((PurpleBuddy*)node), -1);
- } else if (PURPLE_IS_CHAT(node)) {
- tmp = g_markup_escape_text(purple_chat_get_name((PurpleChat*)node), -1);
- } else if (PURPLE_IS_GROUP(node)) {
- tmp = g_markup_escape_text(purple_group_get_name((PurpleGroup*)node), -1);
- /* I don't believe this can happen currently, I think
- * everything that calls this function checks for one of the
- * above node types first. */
- tmp = g_strdup(_("Unknown node type"));
- node_name = g_strdup_printf("<span size='x-large' weight='bold'>%s</span>",
- td->name_layout = create_pango_layout(node_name, &td->name_width, &td->name_height);
- td->name_width += SMALL_SPACE + PROTOCOL_SIZE;
- td->name_height = MAX(td->name_height, PROTOCOL_SIZE + SMALL_SPACE);
-#if 0 /* Protocol Icon as avatar */
- if(!td->avatar && full) {
- td->avatar = pidgin_create_protocol_icon(account, PIDGIN_PROTOCOL_ICON_LARGE);
- td->avatar_is_protocol_icon = TRUE;
- td->avatar_width = gdk_pixbuf_get_width(td->avatar);
- td->avatar_height = gdk_pixbuf_get_height(td->avatar);
-pidgin_blist_paint_tip(GtkWidget *widget, cairo_t *cr, gpointer null)
- GtkStyleContext *context;
- int current_height, max_width;
- GtkTextDirection dir = gtk_widget_get_direction(widget);
- if(gtkblist->tooltipdata == NULL)
- context = gtk_widget_get_style_context(gtkblist->tipwindow);
- gtk_style_context_add_class(context, GTK_STYLE_CLASS_TOOLTIP);
- for(l = gtkblist->tooltipdata; l; l = l->next)
- struct tooltip_data *td = l->data;
- max_text_width = MAX(max_text_width,
- MAX(td->width, td->name_width));
- max_avatar_width = MAX(max_avatar_width, td->avatar_width);
- status_size = STATUS_SIZE;
- max_width = TOOLTIP_BORDER + status_size + SMALL_SPACE + max_text_width + SMALL_SPACE + max_avatar_width + TOOLTIP_BORDER;
- if (dir == GTK_TEXT_DIR_RTL)
- protocol_col = TOOLTIP_BORDER + max_avatar_width + SMALL_SPACE;
- protocol_col = TOOLTIP_BORDER + status_size + SMALL_SPACE + max_text_width - PROTOCOL_SIZE;
- for(l = gtkblist->tooltipdata; l; l = l->next)
- struct tooltip_data *td = l->data;
- if (td->avatar && pidgin_gdk_pixbuf_is_opaque(td->avatar))
- gtk_style_context_save(context);
- gtk_style_context_add_class(context, GTK_STYLE_CLASS_FRAME);
- if (dir == GTK_TEXT_DIR_RTL) {
- gtk_render_frame(context, cr,
- TOOLTIP_BORDER - 1, current_height - 1,
- td->avatar_width + 2, td->avatar_height + 2);
- gtk_render_frame(context, cr,
- max_width - (td->avatar_width + TOOLTIP_BORDER) - 1,
- td->avatar_width + 2, td->avatar_height + 2);
- gtk_style_context_restore(context);
- if (dir == GTK_TEXT_DIR_RTL) {
- gdk_cairo_set_source_pixbuf(cr, td->status_icon,
- max_width - TOOLTIP_BORDER - status_size,
- gdk_cairo_set_source_pixbuf(cr, td->status_icon,
- TOOLTIP_BORDER, current_height);
- if (dir == GTK_TEXT_DIR_RTL) {
- gdk_cairo_set_source_pixbuf(cr, td->avatar,
- TOOLTIP_BORDER, current_height);
- gdk_cairo_set_source_pixbuf(cr, td->avatar,
- max_width - (td->avatar_width + TOOLTIP_BORDER),
- if (!td->avatar_is_protocol_icon && td->protocol_icon) {
- gdk_cairo_set_source_pixbuf(cr, td->protocol_icon, protocol_col,
- (td->name_height - PROTOCOL_SIZE) / 2);
- if (dir == GTK_TEXT_DIR_RTL) {
- gtk_render_layout(context, cr,
- max_width - (TOOLTIP_BORDER + status_size + SMALL_SPACE) - PANGO_PIXELS(300000),
- current_height, td->name_layout);
- gtk_render_layout(context, cr,
- TOOLTIP_BORDER + status_size + SMALL_SPACE,
- current_height, td->name_layout);
- if (dir != GTK_TEXT_DIR_RTL) {
- gtk_render_layout(context, cr,
- TOOLTIP_BORDER + status_size + SMALL_SPACE,
- current_height + td->name_height,
- gtk_render_layout(context, cr,
- max_width - (TOOLTIP_BORDER + status_size + SMALL_SPACE) - PANGO_PIXELS(300000),
- current_height + td->name_height,
- current_height += MAX(td->name_height + td->height, td->avatar_height) + td->padding;
-tooltip_data_free(struct tooltip_data *td)
- g_return_if_fail(td != NULL);
- g_clear_object(&td->avatar);
- g_clear_object(&td->status_icon);
- g_clear_object(&td->protocol_icon);
- g_clear_object(&td->layout);
- g_clear_object(&td->name_layout);
-pidgin_blist_destroy_tooltip_data(void)
- g_list_free_full(gtkblist->tooltipdata, (GDestroyNotify)tooltip_data_free);
- gtkblist->tooltipdata = NULL;
-void pidgin_blist_tooltip_destroy()
- pidgin_blist_destroy_tooltip_data();
- pidgin_tooltip_destroy();
-pidgin_blist_create_tooltip_for_node(GtkWidget *widget, gpointer data, int *w, int *h)
- PurpleBlistNode *node = data;
- int width = 0, height = 0;
- int max_text_width = 0;
- int max_avatar_width = 0;
- if (gtkblist->tooltipdata) {
- gtkblist->tipwindow = NULL;
- pidgin_blist_destroy_tooltip_data();
- gtkblist->tipwindow = widget;
- if (PURPLE_IS_CHAT(node) ||
- PURPLE_IS_BUDDY(node)) {
- struct tooltip_data *td = create_tip_for_node(node, TRUE);
- gtkblist->tooltipdata = g_list_append(gtkblist->tooltipdata, td);
- } else if (PURPLE_IS_GROUP(node)) {
- PurpleGroup *group = (PurpleGroup*)node;
- struct tooltip_data *td = create_tip_for_node(node, TRUE);
- gtkblist->tooltipdata = g_list_append(gtkblist->tooltipdata, td);
- /* Accounts with buddies in group */
- accounts = purple_group_get_accounts(group);
- for (; accounts != NULL;
- accounts = g_slist_delete_link(accounts, accounts)) {
- PurpleAccount *account = accounts->data;
- td = create_tip_for_account(account);
- gtkblist->tooltipdata = g_list_append(gtkblist->tooltipdata, td);
- } else if (PURPLE_IS_CONTACT(node)) {
- PurpleBlistNode *child;
- PurpleBuddy *b = purple_contact_get_priority_buddy((PurpleContact *)node);
- for(child = node->child; child; child = child->next)
- if(PURPLE_IS_BUDDY(child) && buddy_is_displayable((PurpleBuddy*)child)) {
- struct tooltip_data *td = create_tip_for_node(child, (b == (PurpleBuddy*)child));
- if (b == (PurpleBuddy *)child) {
- gtkblist->tooltipdata = g_list_prepend(gtkblist->tooltipdata, td);
- gtkblist->tooltipdata = g_list_append(gtkblist->tooltipdata, td);
- for (list = gtkblist->tooltipdata; list; list = list->next) {
- struct tooltip_data *td = list->data;
- max_text_width = MAX(max_text_width, MAX(td->width, td->name_width));
- max_avatar_width = MAX(max_avatar_width, td->avatar_width);
- height += MAX(MAX(STATUS_SIZE, td->avatar_height), td->height + td->name_height) + td->padding;
- status_size = MAX(status_size, STATUS_SIZE);
- height += TOOLTIP_BORDER;
- width = TOOLTIP_BORDER + status_size + SMALL_SPACE + max_text_width + SMALL_SPACE + max_avatar_width + TOOLTIP_BORDER;
static gboolean pidgin_blist_expand_timeout(GtkWidget *tv)
@@ -3136,11 +2760,6 @@
purple_blist_node_get_bool(PURPLE_BLIST_NODE(buddy), "show_offline")));
-void pidgin_blist_draw_tooltip(PurpleBlistNode *node, GtkWidget *widget)
- pidgin_tooltip_show(widget, node, pidgin_blist_create_tooltip_for_node, pidgin_blist_paint_tip);
static gboolean pidgin_blist_drag_motion_cb(GtkWidget *tv, GdkDragContext *drag_context,
gint x, gint y, guint time, gpointer user_data)
@@ -3221,6 +2840,11 @@
+#define TOOLTIP_BORDER 12 add_tip_for_account(GtkWidget *grid, gint row, PurpleAccount *account)
@@ -4503,15 +4127,6 @@
account_modified(account, gtkblist);
-gtk_blist_window_key_press_cb(GtkWidget *w, GdkEventKey *event, PidginBuddyList *gtkblist)
- /* clear any tooltips */
- pidgin_blist_tooltip_destroy();
reset_headline(PidginBuddyList *gtkblist)
@@ -5270,7 +4885,6 @@
G_CALLBACK(gtk_blist_size_allocate_cb), NULL);
g_signal_connect(G_OBJECT(gtkblist->window), "visibility_notify_event", G_CALLBACK(gtk_blist_visibility_cb), NULL);
g_signal_connect(G_OBJECT(gtkblist->window), "window_state_event", G_CALLBACK(gtk_blist_window_state_cb), NULL);
- g_signal_connect(G_OBJECT(gtkblist->window), "key_press_event", G_CALLBACK(gtk_blist_window_key_press_cb), gtkblist);
gtk_widget_add_events(gtkblist->window, GDK_VISIBILITY_NOTIFY_MASK);
/****************************** Notebook *************************************/
@@ -5377,9 +4991,6 @@
g_signal_connect(G_OBJECT(gtkblist->treeview), "drag-data-received", G_CALLBACK(pidgin_blist_drag_data_rcv_cb), NULL);
g_signal_connect(G_OBJECT(gtkblist->treeview), "drag-data-get", G_CALLBACK(pidgin_blist_drag_data_get_cb), NULL);
- g_signal_connect(G_OBJECT(gtkblist->treeview), "drag-begin", G_CALLBACK(pidgin_blist_drag_begin), NULL);
g_signal_connect(G_OBJECT(gtkblist->treeview), "drag-motion", G_CALLBACK(pidgin_blist_drag_motion_cb), NULL);
g_signal_connect(G_OBJECT(gtkblist->treeview), "motion-notify-event", G_CALLBACK(pidgin_blist_motion_cb), NULL);
g_signal_connect(G_OBJECT(gtkblist->treeview), "leave-notify-event", G_CALLBACK(pidgin_blist_leave_cb), NULL);
@@ -6801,8 +6412,6 @@
gtk_widget_destroy(gtkblist->window);
- pidgin_blist_tooltip_destroy();
if (gtkblist->refresh_timer) {
g_source_remove(gtkblist->refresh_timer);
gtkblist->refresh_timer = 0;
--- a/pidgin/gtkblist.h Mon Jun 14 23:59:42 2021 -0500
+++ b/pidgin/gtkblist.h Tue Jun 15 00:27:09 2021 -0500
@@ -64,8 +64,6 @@
* @contact_rect: This is the bounding rectangle of the contact node and
* its children. This is used for auto-expand on mouseover.
* @mouseover_contact: This is the contact currently mouse-over expanded
- * @tipwindow: The window used by the tooltip
- * @tooltipdata: The data for each "chunk" of the tooltip
* @selected_node: The currently selected node
* @scrollbook: Scrollbook for alerts
* @headline: Widget for headline notifications
@@ -103,9 +101,6 @@
GdkRectangle contact_rect;
PurpleBlistNode *mouseover_contact;
PurpleBlistNode *selected_node;
@@ -413,18 +408,6 @@
gchar *pidgin_blist_get_name_markup(PurpleBuddy *buddy, gboolean selected, gboolean aliased);
- * pidgin_blist_draw_tooltip:
- * @node: The buddy list node to show a tooltip for
- * @widget: The widget to draw the tooltip on
- * Creates the Buddy List tooltip at the current pointer location for the given buddy list node.
- * This tooltip will be destroyed the next time this function is called, or when XXXX
-void pidgin_blist_draw_tooltip(PurpleBlistNode *node, GtkWidget *widget);
* pidgin_blist_query_tooltip_for_node:
* @node: The buddy list to query a tooltip for.
* @tooltip: The tooltip object to add a tooltip to.
@@ -437,13 +420,6 @@
gboolean pidgin_blist_query_tooltip_for_node(PurpleBlistNode *node, GtkTooltip *tooltip);
- * pidgin_blist_tooltip_destroy:
- * Destroys the current (if any) Buddy List tooltip
-void pidgin_blist_tooltip_destroy(void);
#endif /* _PIDGINBLIST_H_ */
--- a/pidgin/gtkroomlist.c Mon Jun 14 23:59:42 2021 -0500
+++ b/pidgin/gtkroomlist.c Tue Jun 15 00:27:09 2021 -0500
@@ -30,7 +30,6 @@
#include "pidginaccountchooser.h"
-#include "pidgintooltip.h"
#define PIDGIN_TYPE_ROOMLIST_DIALOG (pidgin_roomlist_dialog_get_type())
G_DECLARE_FINAL_TYPE(PidginRoomlistDialog, pidgin_roomlist_dialog, PIDGIN,
@@ -734,10 +733,7 @@
g_signal_connect(G_OBJECT(tree), "button-press-event", G_CALLBACK(room_click_cb), list);
g_signal_connect(G_OBJECT(tree), "row-expanded", G_CALLBACK(row_expanded_cb), list);
g_signal_connect(G_OBJECT(tree), "row-activated", G_CALLBACK(row_activated_cb), list);
-#if 0 /* uncomment this when the tooltips are slightly less annoying and more well behaved */
- g_signal_connect(G_OBJECT(tree), "motion-notify-event", G_CALLBACK(row_motion_cb), list);
- g_signal_connect(G_OBJECT(tree), "leave-notify-event", G_CALLBACK(row_leave_cb), list);
gtk_widget_set_has_tooltip(tree, TRUE);
g_signal_connect(G_OBJECT(tree), "query-tooltip",
G_CALLBACK(pidgin_roomlist_query_tooltip), list);