summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@infradead.org>2018-03-22 22:30:12 +0000
committerDavid Woodhouse <dwmw2@infradead.org>2018-03-22 22:30:12 +0000
commit8bfdb64a5315c7ca18509ed8f64278abb22c5d92 (patch)
tree7e39b4a7944277cc91f6d41188ca861f0e9ad0d6
parent45ebbee337fbe81071c8693f8018e117d4723631 (diff)
downloadpidgin-8bfdb64a5315c7ca18509ed8f64278abb22c5d92.tar.gz
Add PURPLE_BLIST_NODE_FLAG_INVISIBLE to avoid showing nodes in UI
This allows a PRPL to create hidden buddies, which are used for providing presence and full name (alias) information for IM peers who *aren't* buddies. It works for chat room members too, although there may be a way to handle those with lower overhead. Fixes #17295
-rw-r--r--libpurple/blist.c9
-rw-r--r--libpurple/blist.h4
-rw-r--r--pidgin/gtkblist.c7
-rw-r--r--pidgin/gtkconv.c26
4 files changed, 29 insertions, 17 deletions
diff --git a/libpurple/blist.c b/libpurple/blist.c
index 2233835df6..3a7e36e5f6 100644
--- a/libpurple/blist.c
+++ b/libpurple/blist.c
@@ -2431,7 +2431,7 @@ const char *purple_chat_get_name(PurpleChat *chat)
PurpleBuddy *purple_find_buddy(PurpleAccount *account, const char *name)
{
- PurpleBuddy *buddy;
+ PurpleBuddy *buddy, *fallback_buddy = NULL;
struct _purple_hbuddy hb;
PurpleBlistNode *group;
@@ -2448,11 +2448,14 @@ PurpleBuddy *purple_find_buddy(PurpleAccount *account, const char *name)
hb.group = group;
if ((buddy = g_hash_table_lookup(purplebuddylist->buddies, &hb))) {
- return buddy;
+ if (PURPLE_BLIST_NODE_IS_VISIBLE(buddy))
+ return buddy;
+ /* Only return invisible buddies if there are no visible ones */
+ fallback_buddy = buddy;
}
}
- return NULL;
+ return fallback_buddy;
}
PurpleBuddy *purple_find_buddy_in_group(PurpleAccount *account, const char *name,
diff --git a/libpurple/blist.h b/libpurple/blist.h
index d3cae7a708..9db9fb371a 100644
--- a/libpurple/blist.h
+++ b/libpurple/blist.h
@@ -71,7 +71,8 @@ typedef enum
typedef enum
{
- PURPLE_BLIST_NODE_FLAG_NO_SAVE = 1 << 0 /**< node should not be saved with the buddy list */
+ PURPLE_BLIST_NODE_FLAG_NO_SAVE = 1 << 0, /**< node should not be saved with the buddy list */
+ PURPLE_BLIST_NODE_FLAG_INVISIBLE = 1 << 1, /**< node should not be displayed */
} PurpleBlistNodeFlags;
@@ -82,6 +83,7 @@ typedef enum
#define PURPLE_BLIST_NODE_HAS_FLAG(b, f) (purple_blist_node_get_flags((PurpleBlistNode*)(b)) & (f))
#define PURPLE_BLIST_NODE_SHOULD_SAVE(b) (! PURPLE_BLIST_NODE_HAS_FLAG(b, PURPLE_BLIST_NODE_FLAG_NO_SAVE))
+#define PURPLE_BLIST_NODE_IS_VISIBLE(b) (! PURPLE_BLIST_NODE_HAS_FLAG(b, PURPLE_BLIST_NODE_FLAG_INVISIBLE))
#define PURPLE_BLIST_NODE_NAME(n) (purple_blist_node_get_type(n) == PURPLE_BLIST_CHAT_NODE ? purple_chat_get_name((PurpleChat*)n) : \
purple_blist_node_get_type(n) == PURPLE_BLIST_BUDDY_NODE ? purple_buddy_get_name((PurpleBuddy*)n) : NULL)
diff --git a/pidgin/gtkblist.c b/pidgin/gtkblist.c
index f200eb4fd5..71361f7082 100644
--- a/pidgin/gtkblist.c
+++ b/pidgin/gtkblist.c
@@ -3202,7 +3202,7 @@ static gboolean buddy_is_displayable(PurpleBuddy *buddy)
{
struct _pidgin_blist_node *gtknode;
- if(!buddy)
+ if(!buddy || !PURPLE_BLIST_NODE_IS_VISIBLE(buddy))
return FALSE;
gtknode = ((PurpleBlistNode*)buddy)->ui_data;
@@ -6386,14 +6386,15 @@ static void pidgin_blist_update_group(PurpleBuddyList *list,
else
count = purple_blist_get_group_online_count(group);
- if (count > 0 || purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_empty_groups"))
+ if (!PURPLE_BLIST_NODE_IS_VISIBLE(gnode) || !PURPLE_BLIST_NODE_IS_VISIBLE(node))
+ show = FALSE;
+ else if (count > 0 || purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_empty_groups"))
show = TRUE;
else if (PURPLE_BLIST_NODE_IS_BUDDY(node) && buddy_is_displayable((PurpleBuddy*)node)) { /* Or chat? */
show = TRUE;
} else if (!show_offline) {
show = pidgin_blist_group_has_show_offline_buddy(group);
}
-
if (show) {
gchar *title;
gboolean biglist;
diff --git a/pidgin/gtkconv.c b/pidgin/gtkconv.c
index 5c3e2d5505..74dbe69618 100644
--- a/pidgin/gtkconv.c
+++ b/pidgin/gtkconv.c
@@ -632,7 +632,7 @@ add_remove_cb(GtkWidget *widget, PidginConversation *gtkconv)
PurpleBuddy *b;
b = purple_find_buddy(account, name);
- if (b != NULL)
+ if (b != NULL && PURPLE_BLIST_NODE_IS_VISIBLE(b))
pidgin_dialogs_remove_buddy(b);
else if (account != NULL && purple_account_is_connected(account))
purple_blist_request_add_buddy(account, (char *)name, NULL, NULL);
@@ -1686,7 +1686,8 @@ create_chat_menu(PurpleConversation *conv, const char *who, PurpleConnection *gc
}
if (!is_me && prpl_info && !(prpl_info->options & OPT_PROTO_UNIQUE_CHATNAME) && (prpl_info->add_buddy != NULL)) {
- if ((buddy = purple_find_buddy(conv->account, who)) != NULL)
+ if ((buddy = purple_find_buddy(conv->account, who)) != NULL &&
+ PURPLE_BLIST_NODE_IS_VISIBLE(buddy))
button = pidgin_new_item_from_stock(menu, _("Remove"), GTK_STOCK_REMOVE,
G_CALLBACK(menu_chat_add_remove_cb), PIDGIN_CONVERSATION(conv), 0, 0, NULL);
else
@@ -4542,7 +4543,7 @@ buddy_cb_common(PurpleBuddy *buddy, PurpleConversation *conv, gboolean is_buddy)
static void
buddy_added_cb(PurpleBlistNode *node, PurpleConversation *conv)
{
- if (!PURPLE_BLIST_NODE_IS_BUDDY(node))
+ if (!PURPLE_BLIST_NODE_IS_BUDDY(node) || !PURPLE_BLIST_NODE_IS_VISIBLE(node))
return;
buddy_cb_common(PURPLE_BUDDY(node), conv, TRUE);
@@ -4551,12 +4552,15 @@ buddy_added_cb(PurpleBlistNode *node, PurpleConversation *conv)
static void
buddy_removed_cb(PurpleBlistNode *node, PurpleConversation *conv)
{
+ PurpleBuddy *buddy;
+
if (!PURPLE_BLIST_NODE_IS_BUDDY(node))
return;
- /* If there's another buddy for the same "dude" on the list, do nothing. */
- if (purple_find_buddy(purple_buddy_get_account(PURPLE_BUDDY(node)),
- purple_buddy_get_name(PURPLE_BUDDY(node))) != NULL)
+ /* If there's another real buddy for the same "dude" on the list, do nothing. */
+ buddy = purple_find_buddy(purple_buddy_get_account(PURPLE_BUDDY(node)),
+ purple_buddy_get_name(PURPLE_BUDDY(node)));
+ if (buddy && PURPLE_BLIST_NODE_IS_VISIBLE(buddy))
return;
buddy_cb_common(PURPLE_BUDDY(node), conv, FALSE);
@@ -6544,6 +6548,7 @@ gray_stuff_out(PidginConversation *gtkconv)
* is sensitive or not.
*/
if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) {
+ PurpleBuddy *buddy;
/* Show stuff that applies to IMs, hide stuff that applies to chats */
/* Deal with menu items */
@@ -6562,12 +6567,13 @@ gray_stuff_out(PidginConversation *gtkconv)
gtk_widget_show(win->menu.unblock);
}
- if (purple_find_buddy(account, purple_conversation_get_name(conv)) == NULL) {
- gtk_widget_show(win->menu.add);
- gtk_widget_hide(win->menu.remove);
- } else {
+ buddy = purple_find_buddy(account, purple_conversation_get_name(conv));
+ if (buddy && PURPLE_BLIST_NODE_IS_VISIBLE(buddy)) {
gtk_widget_show(win->menu.remove);
gtk_widget_hide(win->menu.add);
+ } else {
+ gtk_widget_show(win->menu.add);
+ gtk_widget_hide(win->menu.remove);
}
gtk_widget_show(win->menu.insert_link);