--- a/ChangeLog.API Tue Apr 25 00:46:17 2023 -0500
+++ b/ChangeLog.API Tue Apr 25 01:02:47 2023 -0500
@@ -134,6 +134,9 @@
* PurpleContact and PurpleGroup inherit PurpleCountingNode
* PurpleBuddyList is now a GObject. Please see the documentation for
+ * PurpleFilterAccountFunc renamed to + PurpleRequestFieldAccountFilterFunc, and now takes a user * purple_find_buddies renamed to purple_blist_find_buddies
* purple_find_buddy_in_group renamed to purple_blist_find_buddy_in_group
* purple_find_buddy renamed to purple_blist_find_buddy
--- a/libpurple/account.h Tue Apr 25 00:46:17 2023 -0500
+++ b/libpurple/account.h Tue Apr 25 01:02:47 2023 -0500
@@ -33,8 +33,6 @@
typedef struct _PurpleAccount PurpleAccount;
-typedef gboolean (*PurpleFilterAccountFunc)(PurpleAccount *account);
--- a/libpurple/plugins/idle/idle.c Tue Apr 25 00:46:17 2023 -0500
+++ b/libpurple/plugins/idle/idle.c Tue Apr 25 01:02:47 2023 -0500
@@ -35,7 +35,7 @@
static GList *idled_accts = NULL;
-unidle_filter(PurpleAccount *acct)
+unidle_filter(PurpleAccount *acct, G_GNUC_UNUSED gpointer data) if (g_list_find(idled_accts, acct))
@@ -44,7 +44,7 @@
-idleable_filter(PurpleAccount *account)
+idleable_filter(PurpleAccount *account, G_GNUC_UNUSED gpointer data) PurpleProtocol *protocol;
@@ -89,7 +89,7 @@
int tm = purple_request_page_get_integer(page, "mins");
/* only add the account to the GList if it's not already been idled */
- if(!unidle_filter(acct)) {
+ if(!unidle_filter(acct, NULL)) { purple_debug_misc("idle", "%s hasn't been idled yet; adding to list.",
purple_contact_info_get_username(info));
idled_accts = g_list_append(idled_accts, acct);
@@ -110,7 +110,7 @@
for(iter = list; iter; iter = iter->next) {
acct = (PurpleAccount *)(iter->data);
- if(acct && idleable_filter(acct)) {
+ if(acct && idleable_filter(acct, NULL)) { PurpleContactInfo *info = PURPLE_CONTACT_INFO(acct);
purple_debug_misc("idle", "Idling %s.\n",
@@ -164,7 +164,7 @@
field = purple_request_field_account_new("acct", _("Account"), NULL);
afield = PURPLE_REQUEST_FIELD_ACCOUNT(field);
- purple_request_field_account_set_filter(afield, idleable_filter);
+ purple_request_field_account_set_filter(afield, idleable_filter, NULL, NULL); purple_request_field_account_set_show_all(afield, FALSE);
purple_request_group_add_field(group, field);
@@ -204,7 +204,7 @@
field = purple_request_field_account_new("acct", _("Account"), NULL);
afield = PURPLE_REQUEST_FIELD_ACCOUNT(field);
- purple_request_field_account_set_filter(afield, unidle_filter);
+ purple_request_field_account_set_filter(afield, unidle_filter, NULL, NULL); purple_request_field_account_set_show_all(afield, FALSE);
purple_request_group_add_field(group, field);
--- a/libpurple/request/purplerequestfieldaccount.c Tue Apr 25 00:46:17 2023 -0500
+++ b/libpurple/request/purplerequestfieldaccount.c Tue Apr 25 01:02:47 2023 -0500
@@ -33,7 +33,7 @@
- PurpleFilterAccountFunc filter_func;
@@ -108,6 +108,7 @@
g_clear_object(&field->default_account);
g_clear_object(&field->account);
+ g_clear_pointer(&field->filter_func, g_closure_unref); G_OBJECT_CLASS(purple_request_field_account_parent_class)->finalize(obj);
@@ -261,11 +262,20 @@
purple_request_field_account_set_filter(PurpleRequestFieldAccount *field,
- PurpleFilterAccountFunc filter_func)
+ PurpleRequestFieldAccountFilterFunc filter_func, + GDestroyNotify destroy_data) g_return_if_fail(PURPLE_IS_REQUEST_FIELD_ACCOUNT(field));
- field->filter_func = filter_func;
+ g_clear_pointer(&field->filter_func, g_closure_unref); + if(filter_func != NULL) { + field->filter_func = g_cclosure_new(G_CALLBACK(filter_func), user_data, + (GClosureNotify)G_CALLBACK(destroy_data)); + g_closure_ref(field->filter_func); + g_closure_sink(field->filter_func); + g_closure_set_marshal(field->filter_func, g_cclosure_marshal_generic); @@ -285,14 +295,34 @@
purple_request_field_account_get_show_all(PurpleRequestFieldAccount *field) {
- g_return_val_if_fail(PURPLE_IS_REQUEST_FIELD(field), FALSE);
+ g_return_val_if_fail(PURPLE_IS_REQUEST_FIELD_ACCOUNT(field), FALSE);
-purple_request_field_account_get_filter(PurpleRequestFieldAccount *field) {
- g_return_val_if_fail(PURPLE_IS_REQUEST_FIELD(field), NULL);
+purple_request_field_account_match(PurpleRequestFieldAccount *field, + PurpleAccount *account) + g_return_val_if_fail(PURPLE_IS_REQUEST_FIELD_ACCOUNT(field), FALSE); - return field->filter_func;
+ if(field->filter_func != NULL) { + GValue result = G_VALUE_INIT; + GValue params[] = {G_VALUE_INIT}; + g_value_init(&result, G_TYPE_BOOLEAN); + g_value_set_instance(g_value_init(¶ms[0], PURPLE_TYPE_ACCOUNT), + g_closure_invoke(field->filter_func, &result, + G_N_ELEMENTS(params), params, NULL); + ret = g_value_get_boolean(&result); + g_value_unset(&result); + for(gsize i = 0; i < G_N_ELEMENTS(params); i++) { + g_value_unset(¶ms[i]); --- a/libpurple/request/purplerequestfieldaccount.h Tue Apr 25 00:46:17 2023 -0500
+++ b/libpurple/request/purplerequestfieldaccount.h Tue Apr 25 01:02:47 2023 -0500
@@ -33,6 +33,22 @@
#include "purplerequestfield.h"
+ * PurpleRequestFieldAccountFilterFunc: + * @account: The account. + * @user_data: The data passed to [method@Purple.RequestFieldAccount.set_filter]. + * A function that is called to determine if the account should be matched. + * If the filter matches the account, this function must return %TRUE. If the + * account should be filtered out, %FALSE must be returned. + * Returns: %TRUE to keep the account. +typedef gboolean (*PurpleRequestFieldAccountFilterFunc)(PurpleAccount *account, gpointer user_data); @@ -93,14 +109,17 @@
* purple_request_field_account_set_filter:
* @field: The account field.
- * @filter_func: (scope notified): The account filter function.
+ * @filter_func: (scope notified) (closure user_data): The account filter + * function, or %NULL to disable additional filtering. + * @user_data: The data to pass to the filter callback. + * @destroy_data: A cleanup function for @user_data. * Sets the account filter function in an account field.
* This function will determine which accounts get displayed and which
-void purple_request_field_account_set_filter(PurpleRequestFieldAccount *field, PurpleFilterAccountFunc filter_func);
+void purple_request_field_account_set_filter(PurpleRequestFieldAccount *field, PurpleRequestFieldAccountFilterFunc filter_func, gpointer user_data, GDestroyNotify destroy_data); * purple_request_field_account_get_default_value:
@@ -136,17 +155,17 @@
gboolean purple_request_field_account_get_show_all(PurpleRequestFieldAccount *field);
- * purple_request_field_account_get_filter: (skip):
+ * purple_request_field_account_match: * @field: The account field.
+ * @account: The account to check. - * Returns the account filter function in an account field.
+ * Returns whether the specified account is matched by the filter or not. - * This function will determine which accounts get displayed and which
+ * Returns: Whether or not to show the account. - * Returns: (transfer none): The account filter function.
-PurpleFilterAccountFunc purple_request_field_account_get_filter(PurpleRequestFieldAccount *field);
+gboolean purple_request_field_account_match(PurpleRequestFieldAccount *field, PurpleAccount *account); --- a/pidgin/gtkrequest.c Tue Apr 25 00:46:17 2023 -0500
+++ b/pidgin/gtkrequest.c Tue Apr 25 01:02:47 2023 -0500
@@ -1192,12 +1192,12 @@
-field_custom_account_filter_cb(gpointer item, G_GNUC_UNUSED gpointer data) {
- PurpleFilterAccountFunc func = data;
+field_custom_account_filter_cb(gpointer item, gpointer data) { + PurpleRequestFieldAccount *field = data; if(PURPLE_IS_ACCOUNT(item)) {
- ret = func(PURPLE_ACCOUNT(item));
+ ret = purple_request_field_account_match(field, PURPLE_ACCOUNT(item)); @@ -1209,7 +1209,7 @@
PurpleRequestFieldAccount *afield = NULL;
GtkWidget *widget = NULL;
PurpleAccount *account = NULL;
- PurpleFilterAccountFunc account_filter = NULL;
+ GtkCustomFilter *custom_filter = NULL; GtkFilter *filter = NULL;
const char *type_hint = NULL;
@@ -1217,15 +1217,9 @@
afield = PURPLE_REQUEST_FIELD_ACCOUNT(field);
account = purple_request_field_account_get_default_value(afield);
- account_filter = purple_request_field_account_get_filter(afield);
- if(account_filter != NULL) {
- GtkCustomFilter *custom_filter = NULL;
- custom_filter = gtk_custom_filter_new(field_custom_account_filter_cb,
- filter = GTK_FILTER(custom_filter);
+ custom_filter = gtk_custom_filter_new(field_custom_account_filter_cb, + filter = GTK_FILTER(custom_filter); if(!purple_request_field_account_get_show_all(afield)) {
GtkEveryFilter *every = NULL;