Update Pidgin.ProtocolChooser to hide in-development protocols

Fri, 16 May 2025 00:01:26 -0500

author
Gary Kramlich <grim@reaperworld.com>
date
Fri, 16 May 2025 00:01:26 -0500
changeset 43259
490b270f217e
parent 43258
488acc773d7c
child 43260
d5b9da0df929

Update Pidgin.ProtocolChooser to hide in-development protocols

If developer-mode is enabled then in-development protocols will be shown,
otherwise they are hidden.

Testing Done:
Opened the account manager with the setting off and verified that only ircv3 and demo were shown. Turned the setting on with the account manager still opened and verified that the chooser updated to show the in-development protocols.

Also called in the turtles.

Reviewed at https://reviews.imfreedom.org/r/4008/

pidgin/pidginprotocolchooser.c file | annotate | diff | comparison | revisions
pidgin/resources/Protocols/chooser.ui file | annotate | diff | comparison | revisions
--- a/pidgin/pidginprotocolchooser.c	Fri May 16 00:00:24 2025 -0500
+++ b/pidgin/pidginprotocolchooser.c	Fri May 16 00:01:26 2025 -0500
@@ -36,7 +36,10 @@
 struct _PidginProtocolChooser {
 	AdwComboRow parent;
 
-	GtkWidget *sort;
+	GListModel *filter_model;
+	GtkFilter *filter;
+
+	GSettings *developer_settings;
 };
 
 /******************************************************************************
@@ -52,6 +55,36 @@
 	g_object_notify_by_pspec(G_OBJECT(chooser), properties[PROP_PROTOCOL]);
 }
 
+static gboolean
+pidgin_protocol_chooser_filter_func(GObject *item,
+                                    G_GNUC_UNUSED gpointer data)
+{
+	PurpleProtocol *protocol = NULL;
+	PurpleTags *tags = NULL;
+	gboolean in_development = FALSE;
+
+	if(purple_core_get_developer_mode()) {
+		return TRUE;
+	}
+
+	protocol = PURPLE_PROTOCOL(item);
+	tags = purple_protocol_get_tags(protocol);
+
+	purple_tags_lookup(tags, "in-development", &in_development);
+
+	return !in_development;
+}
+
+static void
+pidgin_protocol_chooser_developer_mode_changed_cb(G_GNUC_UNUSED GSettings *self,
+                                                  G_GNUC_UNUSED const char *key,
+                                                  gpointer data)
+{
+	PidginProtocolChooser *chooser = data;
+
+	gtk_filter_changed(chooser->filter, GTK_FILTER_CHANGE_DIFFERENT);
+}
+
 /******************************************************************************
  * GObject Implementation
  *****************************************************************************/
@@ -59,6 +92,15 @@
                     ADW_TYPE_COMBO_ROW)
 
 static void
+pidgin_protocol_chooser_finalize(GObject *obj) {
+	PidginProtocolChooser *chooser = PIDGIN_PROTOCOL_CHOOSER(obj);
+
+	g_clear_object(&chooser->developer_settings);
+
+	G_OBJECT_CLASS(pidgin_protocol_chooser_parent_class)->finalize(obj);
+}
+
+static void
 pidgin_protocol_chooser_get_property(GObject *obj, guint prop_id,
                                      GValue *value, GParamSpec *pspec)
 {
@@ -98,6 +140,7 @@
 	GObjectClass *obj_class = G_OBJECT_CLASS(klass);
 	GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
 
+	obj_class->finalize = pidgin_protocol_chooser_finalize;
 	obj_class->get_property = pidgin_protocol_chooser_get_property;
 	obj_class->set_property = pidgin_protocol_chooser_set_property;
 
@@ -119,7 +162,9 @@
 	                                            "/im/pidgin/Pidgin3/Protocols/chooser.ui");
 
 	gtk_widget_class_bind_template_child(widget_class, PidginProtocolChooser,
-	                                     sort);
+	                                     filter_model);
+	gtk_widget_class_bind_template_child(widget_class, PidginProtocolChooser,
+	                                     filter);
 
 	gtk_widget_class_bind_template_callback(widget_class, dropdown_changed_cb);
 }
@@ -131,8 +176,23 @@
 	gtk_widget_init_template(GTK_WIDGET(chooser));
 
 	manager = purple_protocol_manager_get_default();
-	gtk_sort_list_model_set_model(GTK_SORT_LIST_MODEL(chooser->sort),
-	                              G_LIST_MODEL(manager));
+	gtk_filter_list_model_set_model(GTK_FILTER_LIST_MODEL(chooser->filter_model),
+	                                G_LIST_MODEL(manager));
+
+	gtk_custom_filter_set_filter_func(GTK_CUSTOM_FILTER(chooser->filter),
+	                                  (GtkCustomFilterFunc)pidgin_protocol_chooser_filter_func,
+	                                  NULL,
+	                                  NULL);
+
+	/* Connect to the changed signal for the developer-mode settings so we can
+	 * invalidate our filter.
+	 */
+	chooser->developer_settings = purple_core_new_settings("im.pidgin.Purple.Core");
+	g_signal_connect_object(chooser->developer_settings,
+	                        "changed::developer-mode",
+	                        G_CALLBACK(pidgin_protocol_chooser_developer_mode_changed_cb),
+	                        chooser,
+	                        G_CONNECT_DEFAULT);
 }
 
 /******************************************************************************
--- a/pidgin/resources/Protocols/chooser.ui	Fri May 16 00:00:24 2025 -0500
+++ b/pidgin/resources/Protocols/chooser.ui	Fri May 16 00:01:26 2025 -0500
@@ -69,7 +69,7 @@
       </object>
     </property>
     <property name="model">
-      <object class="GtkSortListModel" id="sort">
+      <object class="GtkSortListModel">
         <property name="sorter">
           <object class="GtkStringSorter">
             <property name="expression">
@@ -77,6 +77,13 @@
             </property>
           </object>
         </property>
+        <property name="model">
+          <object class="GtkFilterListModel" id="filter_model">
+            <property name="filter">
+              <object class="GtkCustomFilter" id="filter"/>
+            </property>
+          </object>
+        </property>
       </object>
     </property>
     <signal name="notify::selected" handler="dropdown_changed_cb" object="PidginProtocolChooser" swapped="no"/>

mercurial