# HG changeset patch
# Node ID f0c2695336c2c875bd268475421880cfe7cb3ad1
# Parent  b67583622d6e17edd62aef552231826e4159a48e
diff --git a/pidgin/pidginconversation.c b/pidgin/pidginconversation.c
--- a/pidgin/pidginconversation.c
+++ b/pidgin/pidginconversation.c
@@ -48,7 +48,9 @@
 	GtkWidget *history;
 	GtkAdjustment *history_adjustment;
 
-	GtkCustomSorter *memberlist_sorter;
+	GtkWidget *member_list_search_entry;
+	GtkCustomFilter *member_list_filter;
+	GtkCustomSorter *member_list_sorter;
 
 	GtkWidget *input;
 
@@ -269,6 +271,23 @@
 	}
 }
 
+static void
+pidgin_conversation_members_search_changed_cb(GtkSearchEntry *self,
+                                              gpointer data)
+{
+	PidginConversation *conversation = data;
+
+	gtk_filter_changed(GTK_FILTER(conversation->member_list_filter),
+	                   GTK_FILTER_CHANGE_DIFFERENT);
+
+	/* Make sure the search widget has focus, this allows the user to clear a
+	 * search that has filtered out every item in the list via their keyboard.
+	 */
+	if(!gtk_widget_has_focus(GTK_WIDGET(self))) {
+		gtk_widget_grab_focus(GTK_WIDGET(self));
+	}
+}
+
 static int
 pidgin_conversation_member_list_sort(gconstpointer a, gconstpointer b,
                                      G_GNUC_UNUSED gpointer data)
@@ -287,6 +306,17 @@
 	return purple_contact_info_compare(info_a, info_b);
 }
 
+static gboolean
+pidgin_conversation_member_list_filter(GObject *item, gpointer data) {
+	PidginConversation *conversation = data;
+	PurpleConversationMember *member = PURPLE_CONVERSATION_MEMBER(item);
+	const char *needle = NULL;
+
+	needle = gtk_editable_get_text(GTK_EDITABLE(conversation->member_list_search_entry));
+
+	return purple_conversation_member_matches(member, needle);
+}
+
 static void
 pidgin_conversation_message_setup(G_GNUC_UNUSED GtkSignalListItemFactory *self,
                                   GObject *object,
@@ -375,9 +405,13 @@
 pidgin_conversation_init(PidginConversation *conversation) {
 	gtk_widget_init_template(GTK_WIDGET(conversation));
 
-	gtk_custom_sorter_set_sort_func(conversation->memberlist_sorter,
+	gtk_custom_sorter_set_sort_func(conversation->member_list_sorter,
 	                                pidgin_conversation_member_list_sort,
 	                                NULL, NULL);
+
+	gtk_custom_filter_set_filter_func(conversation->member_list_filter,
+	                                  (GtkCustomFilterFunc)pidgin_conversation_member_list_filter,
+	                                  conversation, NULL);
 }
 
 static void
@@ -416,7 +450,11 @@
 	gtk_widget_class_bind_template_child(widget_class, PidginConversation,
 	                                     history_adjustment);
 	gtk_widget_class_bind_template_child(widget_class, PidginConversation,
-	                                     memberlist_sorter);
+	                                     member_list_search_entry);
+	gtk_widget_class_bind_template_child(widget_class, PidginConversation,
+	                                     member_list_filter);
+	gtk_widget_class_bind_template_child(widget_class, PidginConversation,
+	                                     member_list_sorter);
 	gtk_widget_class_bind_template_child(widget_class, PidginConversation,
 	                                     input);
 	gtk_widget_class_bind_template_child(widget_class, PidginConversation,
@@ -427,6 +465,8 @@
 	gtk_widget_class_bind_template_callback(widget_class,
 	                                        pidgin_conversation_escape_topic);
 	gtk_widget_class_bind_template_callback(widget_class,
+	                                        pidgin_conversation_members_search_changed_cb);
+	gtk_widget_class_bind_template_callback(widget_class,
 	                                        pidgin_conversation_conversation_members_items_changed);
 	gtk_widget_class_bind_template_callback(widget_class,
 	                                        pidgin_conversation_get_status_label);
diff --git a/pidgin/resources/Conversations/conversation.ui b/pidgin/resources/Conversations/conversation.ui
--- a/pidgin/resources/Conversations/conversation.ui
+++ b/pidgin/resources/Conversations/conversation.ui
@@ -107,8 +107,8 @@
             <property name="orientation">vertical</property>
             <property name="vexpand">true</property>
             <child>
-              <object class="GtkLabel">
-                <binding name="label">
+              <object class="GtkSearchEntry" id="member_list_search_entry">
+                <binding name="placeholder-text">
                   <closure type="gchararray" function="pidgin_conversation_conversation_members_items_changed">
                     <lookup name="n_items" type="PurpleConversationMembers">
                       <lookup name="members" type="PurpleConversation">
@@ -117,6 +117,7 @@
                     </lookup>
                   </closure>
                 </binding>
+                <signal name="search-changed" handler="pidgin_conversation_members_search_changed_cb"/>
               </object>
             </child>
             <child>
@@ -142,15 +143,23 @@
                       <object class="GtkSingleSelection">
                         <property name="autoselect">false</property>
                         <property name="model">
-                          <object class="GtkSortListModel">
-                            <property name="sorter">
-                              <object class="GtkCustomSorter" id="memberlist_sorter"/>
+                          <object class="GtkFilterListModel" id="member_list_filter_model">
+                            <property name="incremental">0</property>
+                            <property name="filter">
+                              <object class="GtkCustomFilter" id="member_list_filter"/>
                             </property>
-                            <binding name="model">
-                              <lookup name="members" type="PurpleConversation">
-                                <lookup name="conversation">PidginConversation</lookup>
-                              </lookup>
-                            </binding>
+                            <property name="model">
+                              <object class="GtkSortListModel">
+                                <property name="sorter">
+                                  <object class="GtkCustomSorter" id="member_list_sorter"/>
+                                </property>
+                                <binding name="model">
+                                  <lookup name="members" type="PurpleConversation">
+                                    <lookup name="conversation">PidginConversation</lookup>
+                                  </lookup>
+                                </binding>
+                              </object>
+                            </property>
                           </object>
                         </property>
                       </object>
