Old paradigms...

David Woodhouse dwmw2 at infradead.org
Thu Mar 15 05:54:58 EDT 2018

On Mon, 2017-08-07 at 17:42 +0100, David Woodhouse wrote:
> On Mon, 2017-07-31 at 10:38 +0100, David Woodhouse wrote:
> > On Sun, 2017-07-30 at 23:04 -0500, Gary Kramlich wrote:
> > > On Tue, Jul 25, 2017 at 3:48 AM, David Woodhouse  wrote:
> > > > IF I get an incoming IM from someone I've never heard of, then for the
> > > > duration of that IM chat window, I *could* show that person's full name
> > > > and presence.
> > > > 
> > > > Right now it only works for individuals who *happen* to already be
> > > > known buddies. I have all the information in my prpl but no way to
> > > > convey it to libpurple/Pidgin.
> > > So you're thinking of something like always have a buddy or whatever
> > > we're calling it for everyone (and get rid of the just name thing for
> > > them) and have an option to not show/store them in the contact list?
> >
> > Do you mean 'get rid of the just name thing' for serv_got_im() and
> > purple_conv_chat_add_user(), and to pass a PurpleBuddy (or whatever
> > that's called) instead? 
> > 
> > I suppose we could, although that wasn't what I was thinking. It's fine
> > to just pass the name up from the prpl as we do now, and let
> > Pidgin/libpurple handle what happens next.
> > 
> > It so happens that Pidgin chooses to display the contact's presence at
> > the top of the IM window, and wants that information. And that it shows
> > the contact's full name by preference in the list of chat members, so
> > it wants that too.
> > 
> > Pidgin *already* creates a transient PurpleBuddy for that purpose, if
> > no known buddy already exists. My prpl already *receives* status
> > information for that buddy; it's just that there's no way for me to
> > make the two meet in the middle. My prpl doesn't even get a *signal*
> > let alone a direct invocation when code elsewhere creates a buddy for
> > the account, which seems odd.
> Annoyingly, we already *have* a get_cb_real_name() function but Pidgin
> doesn't actually call it, so members in a chat window are shown by
> their ID (in my case email address). Unless, as I said, they were
> already known Buddies. That one is probably fairly simple to fix, but
> still doesn't get me presence for incoming IM from "random" people.
I finally got a chance to poke at this. Here's a really nasty hack :)

The problem is that throughout gtkconv.c we look up buddies by name
with purple_find_buddy() or purple_find_buddies() when we want to find
presence status or aliases. And none of that exists for the transient
buddy which is created in populate_menu_with_options().

So... I changed purple_buddy_new() to add the newly-created buddy tyo
the hash tables immediately, with hb.group==NULL. I extended the
purple_find_budd{y,ies}() functions with a parameter which allows them
to find those "transient" buddies. And I hacked my PRPL for now to
spuriously generate a new purple_prpl_got_user_status() and
purple_blist_server_alias_buddy() call when a conversation is created;
we can think about hooking into purple_buddy_new() later.

It does work, and now I see the full name and presence of people who IM
me but aren't "buddies". It's kind of horrid though, and would get
worse before it's complete.

 • I'd need to fix it for chat room members, who are also currently 
   showing up without their full name.

 • We'd probably need a *refcount* on the transient buddies, because
   if that same "unknown" person is in an IM window and chat rooms,
   there will be multiple consumers of the same transient buddy.

 • The purple_find_buddies_transient() API is kind of icky, although
   that was mostly a proof-of-concept and could probably be improved.

 • Various places which *assume* that a buddy will have a contact in
   node->parent need to be fixed to cope, if they can see transient
   buddies. I fixed the ones that actually crashed in my testing.

I suppose it could be bashed into shape, and it *is* an important
feature for a number of protocols. But before I press on and try to
make it tolerable, I'm interested in whether anyone has ideas for a
better approach?

One option is *not* to base it on buddies at all, and to provide new
PRPL methods to obtain presence/alias for individuals by name alone,
without there ever being a PurpleBuddy associated with them. The PRPL
*already* doesn't need a PurpleBuddy in order to call
purple_prpl_got_user_status(), and we could add a similar
purple_prpl_got_server_alias() to avoid the PRPL having to see a
PurpleBuddy for that too. Then we have to add a way for the code in
gtkconv.c to receive signals about those changes, which also aren't
based on a PurpleBuddy. Which is probably OK...

Another option is to stick with the "transient buddy" concept but to
let the PRPL manage them. My PRPL already *has* a big list of the
contacts that it's dealing with (in conversations and chat rooms), and
could create a PurpleBuddy for each. The refcounting requirement goes
away then (or at least is pushed down into the PRPL, which in my case
already does it). And instead of the 'hb.group==NULL' thing, maybe we
could just make a special group in the blist which *isn't* displayed in
the UI, and put the "transient" contacts there? That might make a lot
of the complexity of my hack go away...

-------------- next part --------------
A non-text attachment was scrubbed...
Name: pidgin-im-nonbuddy-status.patch
Type: text/x-patch
Size: 18971 bytes
Desc: not available
URL: <https://pidgin.im/pipermail/devel/attachments/20180315/4615216b/attachment-0002.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/x-pkcs7-signature
Size: 5213 bytes
Desc: not available
URL: <https://pidgin.im/pipermail/devel/attachments/20180315/4615216b/attachment-0003.bin>

More information about the Devel mailing list