# HG changeset patch
# Node ID 053683f1d0f9
# Parent  c0b112005dbc
diff --git a/pidgin/gtkaccount.c b/pidgin/gtkaccount.c
--- a/pidgin/gtkaccount.c
+++ b/pidgin/gtkaccount.c
@@ -193,7 +193,6 @@ set_account_protocol_cb(GObject *obj, G_
 	if(g_set_object(&dialog->protocol, protocol)) {
 		g_clear_pointer(&dialog->protocol_id, g_free);
 	}
-	g_object_unref(G_OBJECT(protocol));
 
 	if(PURPLE_IS_PROTOCOL(dialog->protocol)) {
 		dialog->protocol_id = g_strdup(purple_protocol_get_id(dialog->protocol));
diff --git a/pidgin/pidginprotocolchooser.h b/pidgin/pidginprotocolchooser.h
--- a/pidgin/pidginprotocolchooser.h
+++ b/pidgin/pidginprotocolchooser.h
@@ -29,6 +29,7 @@
 #define PIDGIN_PROTOCOL_CHOOSER_H
 
 #include <gtk/gtk.h>
+#include <adwaita.h>
 
 #include <purple.h>
 
@@ -37,14 +38,14 @@ G_BEGIN_DECLS
 #define PIDGIN_TYPE_PROTOCOL_CHOOSER (pidgin_protocol_chooser_get_type())
 
 G_DECLARE_FINAL_TYPE(PidginProtocolChooser, pidgin_protocol_chooser, PIDGIN,
-                     PROTOCOL_CHOOSER, GtkComboBox)
+                     PROTOCOL_CHOOSER, AdwBin)
 
 /**
  * pidgin_protocol_chooser_new:
  *
- * Creates a combo box for a user to select a protocol from.
+ * Creates a drop down for a user to select a protocol from.
  *
- * Returns: (transfer full): The protocol chooser combo box.
+ * Returns: (transfer full): The protocol chooser drop down.
  *
  * Since: 3.0.0
  */
@@ -56,7 +57,7 @@ GtkWidget *pidgin_protocol_chooser_new(v
  *
  * Gets the currently selected protocol from @chooser.
  *
- * Returns: (transfer full): The selected [class@Purple.Protocol] or %NULL if
+ * Returns: (transfer none): The selected [class@Purple.Protocol] or %NULL if
  *          nothing is selected.
  *
  * Since: 3.0.0
diff --git a/pidgin/pidginprotocolchooser.c b/pidgin/pidginprotocolchooser.c
--- a/pidgin/pidginprotocolchooser.c
+++ b/pidgin/pidginprotocolchooser.c
@@ -23,8 +23,6 @@
 
 #include "pidginprotocolchooser.h"
 
-#include "pidginprotocolstore.h"
-
 enum {
 	PROP_ZERO,
 	PROP_PROTOCOL,
@@ -36,30 +34,20 @@ static GParamSpec *properties[N_PROPERTI
  * Structs
  *****************************************************************************/
 struct _PidginProtocolChooser {
-	GtkComboBox parent;
+	AdwBin parent;
 
-	GtkTreeModel *model;
+	GtkDropDown *dropdown;
+	GtkWidget *sort;
 };
 
 /******************************************************************************
  * Callbacks
  *****************************************************************************/
 static void
-pidgin_protocol_chooser_model_changed_cb(GObject *obj, GParamSpec *pspec,
-                                         gpointer data)
+dropdown_changed_cb(G_GNUC_UNUSED GObject *obj,
+                    G_GNUC_UNUSED GParamSpec *pspec,
+                    gpointer data)
 {
-	GtkComboBox *combo = GTK_COMBO_BOX(obj);
-	GtkTreeModel *model = gtk_combo_box_get_model(combo);
-	GtkTreeIter iter;
-
-	/* When the model for the combobox changes, select the first item. */
-	if(gtk_tree_model_get_iter_first(model, &iter)) {
-		gtk_combo_box_set_active_iter(combo, &iter);
-	}
-}
-
-static void
-dropdown_changed_cb(G_GNUC_UNUSED GtkComboBox *self, gpointer data) {
 	PidginProtocolChooser *chooser = PIDGIN_PROTOCOL_CHOOSER(data);
 
 	g_object_notify_by_pspec(G_OBJECT(chooser), properties[PROP_PROTOCOL]);
@@ -68,8 +56,7 @@ dropdown_changed_cb(G_GNUC_UNUSED GtkCom
 /******************************************************************************
  * GObject Implementation
  *****************************************************************************/
-G_DEFINE_TYPE(PidginProtocolChooser, pidgin_protocol_chooser,
-              GTK_TYPE_COMBO_BOX)
+G_DEFINE_TYPE(PidginProtocolChooser, pidgin_protocol_chooser, ADW_TYPE_BIN)
 
 static void
 pidgin_protocol_chooser_get_property(GObject *obj, guint prop_id,
@@ -134,24 +121,22 @@ pidgin_protocol_chooser_class_init(Pidgi
 	                                            "/im/pidgin/Pidgin3/Protocols/chooser.ui");
 
 	gtk_widget_class_bind_template_child(widget_class, PidginProtocolChooser,
-	                                     model);
+	                                     dropdown);
+	gtk_widget_class_bind_template_child(widget_class, PidginProtocolChooser,
+	                                     sort);
+
 	gtk_widget_class_bind_template_callback(widget_class, dropdown_changed_cb);
 }
 
 static void
 pidgin_protocol_chooser_init(PidginProtocolChooser *chooser) {
-	g_signal_connect_object(G_OBJECT(chooser), "notify::model",
-	                        G_CALLBACK(pidgin_protocol_chooser_model_changed_cb),
-	                        chooser, G_CONNECT_AFTER);
+	PurpleProtocolManager *manager = NULL;
 
 	gtk_widget_init_template(GTK_WIDGET(chooser));
 
-	gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(chooser->model),
-	                                     PIDGIN_PROTOCOL_STORE_COLUMN_NAME,
-	                                     GTK_SORT_ASCENDING);
-
-	gtk_combo_box_set_id_column(GTK_COMBO_BOX(chooser),
-	                            PIDGIN_PROTOCOL_STORE_COLUMN_ID);
+	manager = purple_protocol_manager_get_default();
+	gtk_sort_list_model_set_model(GTK_SORT_LIST_MODEL(chooser->sort),
+	                              G_LIST_MODEL(manager));
 }
 
 /******************************************************************************
@@ -164,16 +149,11 @@ pidgin_protocol_chooser_new(void) {
 
 PurpleProtocol *
 pidgin_protocol_chooser_get_protocol(PidginProtocolChooser *chooser) {
-	GtkTreeIter iter;
 	PurpleProtocol *protocol = NULL;
 
 	g_return_val_if_fail(PIDGIN_IS_PROTOCOL_CHOOSER(chooser), NULL);
 
-	if(gtk_combo_box_get_active_iter(GTK_COMBO_BOX(chooser), &iter)) {
-		gtk_tree_model_get(GTK_TREE_MODEL(chooser->model), &iter,
-		                   PIDGIN_PROTOCOL_STORE_COLUMN_PROTOCOL, &protocol,
-		                   -1);
-	}
+	protocol = gtk_drop_down_get_selected_item(chooser->dropdown);
 
 	return protocol;
 }
@@ -182,15 +162,25 @@ void
 pidgin_protocol_chooser_set_protocol(PidginProtocolChooser *chooser,
                                      PurpleProtocol *protocol)
 {
+	guint position = 0;
+
 	g_return_if_fail(PIDGIN_IS_PROTOCOL_CHOOSER(chooser));
 
 	if(protocol != NULL) {
-		const gchar *id = purple_protocol_get_id(protocol);
-		gtk_combo_box_set_active_id(GTK_COMBO_BOX(chooser), id);
-	} else {
-		GtkTreeIter first;
+		GListModel *model = gtk_drop_down_get_model(chooser->dropdown);
+		guint count = g_list_model_get_n_items(model);
+
+		for(guint i = 0; i < count; i++) {
+			PurpleProtocol *this_protocol = NULL;
+
+			this_protocol = g_list_model_get_item(model, i);
 
-		gtk_tree_model_get_iter_first(chooser->model, &first);
-		gtk_combo_box_set_active_iter(GTK_COMBO_BOX(chooser), &first);
+			if(this_protocol == protocol) {
+				position = i;
+				break;
+			}
+		}
 	}
+
+	gtk_drop_down_set_selected(chooser->dropdown, position);
 }
diff --git a/pidgin/resources/Protocols/chooser.ui b/pidgin/resources/Protocols/chooser.ui
--- a/pidgin/resources/Protocols/chooser.ui
+++ b/pidgin/resources/Protocols/chooser.ui
@@ -18,29 +18,66 @@ along with this library; if not, see <ht
 -->
 <interface domain="pidgin">
   <requires lib="gtk" version="4.0"/>
+  <requires lib="Adw" version="1.0"/>
   <requires lib="pidgin" version="3.0"/>
   <!-- interface-license-type gplv2 -->
   <!-- interface-name Pidgin -->
   <!-- interface-description Internet Messenger -->
   <!-- interface-copyright Pidgin Developers <devel@pidgin.im> -->
-  <object class="PidginProtocolStore" id="raw_model"/>
-  <object class="GtkTreeModelSort" id="model">
-    <property name="model">raw_model</property>
-  </object>
-  <template class="PidginProtocolChooser" parent="GtkComboBox">
-    <property name="model">model</property>
-    <child>
-      <object class="GtkCellRendererPixbuf" id="icon"/>
-      <attributes>
-        <attribute name="icon-name">3</attribute>
-      </attributes>
-    </child>
-    <child>
-      <object class="GtkCellRendererText" id="name"/>
-      <attributes>
-        <attribute name="text">2</attribute>
-      </attributes>
-    </child>
-    <signal name="changed" handler="dropdown_changed_cb" object="PidginProtocolChooser" swapped="no"/>
+  <template class="PidginProtocolChooser" parent="AdwBin">
+    <property name="child">
+      <object class="GtkDropDown" id="dropdown">
+        <property name="factory">
+          <object class="GtkBuilderListItemFactory">
+            <property name="bytes">
+<![CDATA[
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <template class="GtkListItem">
+    <property name="child">
+      <object class="GtkBox">
+        <property name="orientation">horizontal</property>
+        <property name="spacing">6</property>
+        <child>
+          <object class="GtkImage">
+            <binding name="icon-name">
+              <lookup name="icon-name" type="PurpleProtocol">
+                <lookup name="item">GtkListItem</lookup>
+              </lookup>
+            </binding>
+          </object>
+        </child>
+        <child>
+          <object class="GtkLabel">
+            <property name="xalign">0</property>
+            <binding name="label">
+              <lookup name="name" type="PurpleProtocol">
+                <lookup name="item">GtkListItem</lookup>
+              </lookup>
+            </binding>
+          </object>
+        </child>
+      </object>
+    </property>
   </template>
 </interface>
+]]>
+            </property>
+          </object>
+        </property>
+        <property name="model">
+          <object class="GtkSortListModel" id="sort">
+            <property name="sorter">
+              <object class="GtkStringSorter">
+                <property name="expression">
+                  <lookup name="name" type="PurpleProtocol"/>
+                </property>
+              </object>
+            </property>
+          </object>
+        </property>
+        <signal name="notify::selected" handler="dropdown_changed_cb" object="PidginProtocolChooser" swapped="no"/>
+      </object>
+    </property>
+  </template>
+</interface>
