From 32f1f7280bb28a0a99a9e4174e78a0fa97505182 Mon Sep 17 00:00:00 2001 From: Evan Welsh Date: Thu, 25 Jan 2024 02:19:11 -0800 Subject: [PATCH] gtk: Add AccessibleList to enable relations in bindings Bindings need a boxed type to "wrap" lists of Gtk.Accessible objects. Closes #6358 --- gtk/gtkaccessible.c | 90 ++++++++++++++++++++++++++++++++++++++++ gtk/gtkaccessible.h | 24 +++++++++++ gtk/gtkaccessiblevalue.c | 13 +++++- 3 files changed, 126 insertions(+), 1 deletion(-) diff --git a/gtk/gtkaccessible.c b/gtk/gtkaccessible.c index b14a947aac..4c58c69032 100644 --- a/gtk/gtkaccessible.c +++ b/gtk/gtkaccessible.c @@ -1149,6 +1149,96 @@ gtk_accessible_get_bounds (GtkAccessible *self, return GTK_ACCESSIBLE_GET_IFACE (self)->get_bounds (self, x, y, width, height); } +struct _GtkAccessibleList +{ + GList *objects; +}; + +/** + * gtk_accessible_list_new_from_list: + * @list: (element-type GtkAccessible): a reference to a `GList` containing a list of accessible values + * + * Allocates a new `GtkAccessibleList`, doing a shallow copy of the + * passed list of `GtkAccessible` instances. + * + * Returns: (transfer full): the list of accessible instances + * + * Since: 4.14 + */ +GtkAccessibleList * +gtk_accessible_list_new_from_list (GList *list) +{ + GtkAccessibleList *accessible_list = g_new (GtkAccessibleList, 1); + + accessible_list->objects = g_list_copy (list); + + return accessible_list; +} + +/** + * gtk_accessible_list_new_from_array: + * @accessibles: (array length=n_accessibles): array of GtkAccessible + * @n_accessibles: length of @accessibles array + * + * Allocates a new list of accessible instances. + * + * Returns: (transfer full): the newly created list of accessible instances + * + * Since: 4.14 + */ +GtkAccessibleList * +gtk_accessible_list_new_from_array (GtkAccessible **accessibles, + gsize n_accessibles) +{ + GtkAccessibleList *accessible_list; + GList *list = NULL; + + g_return_val_if_fail (accessibles == NULL || n_accessibles == 0, NULL); + + accessible_list = g_new (GtkAccessibleList, 1); + + for (gsize i = 0; i < n_accessibles; i++) + { + list = g_list_prepend (list, accessibles[i]); + } + + accessible_list->objects = g_list_reverse (list); + + return accessible_list; +} + +static void +gtk_accessible_list_free (GtkAccessibleList *accessible_list) +{ + g_free (accessible_list->objects); + g_free (accessible_list); +} + +static GtkAccessibleList * +gtk_accessible_list_copy (GtkAccessibleList *accessible_list) +{ + return gtk_accessible_list_new_from_list (accessible_list->objects); +} + +/** + * gtk_accessible_list_get_objects: + * + * Gets the list of objects this boxed type holds + * + * Returns: (transfer container) (element-type GtkAccessible): a shallow copy of the objects + * + * Since: 4.14 + */ +GList * +gtk_accessible_list_get_objects (GtkAccessibleList *accessible_list) +{ + return g_list_copy (accessible_list->objects); +} + +G_DEFINE_BOXED_TYPE (GtkAccessibleList, gtk_accessible_list, + gtk_accessible_list_copy, + gtk_accessible_list_free) + /*< private > * gtk_accessible_should_present: * @self: a `GtkAccessible` diff --git a/gtk/gtkaccessible.h b/gtk/gtkaccessible.h index f4c1531f40..5327f48303 100644 --- a/gtk/gtkaccessible.h +++ b/gtk/gtkaccessible.h @@ -154,6 +154,15 @@ struct _GtkAccessibleInterface int *height); }; +/** + * GtkAccessibleList: + * + * A boxed type which wraps a list of references to GtkAccessible objects. + * + * Since: 4.14 + */ +typedef struct _GtkAccessibleList GtkAccessibleList; + GDK_AVAILABLE_IN_ALL GtkATContext * gtk_accessible_get_at_context (GtkAccessible *self); @@ -236,4 +245,19 @@ GDK_AVAILABLE_IN_ALL void gtk_accessible_relation_init_value (GtkAccessibleRelation relation, GValue *value); +#define GTK_ACCESSIBLE_LIST (gtk_accessible_list_get_type()) + +GDK_AVAILABLE_IN_4_14 +GType gtk_accessible_list_get_type (void); + +GDK_AVAILABLE_IN_4_14 +GList * gtk_accessible_list_get_objects (GtkAccessibleList *accessible_list); + +GDK_AVAILABLE_IN_4_14 +GtkAccessibleList * gtk_accessible_list_new_from_list (GList *list); + +GDK_AVAILABLE_IN_4_14 +GtkAccessibleList * gtk_accessible_list_new_from_array (GtkAccessible **accessibles, + gsize n_accessibles); + G_END_DECLS diff --git a/gtk/gtkaccessiblevalue.c b/gtk/gtkaccessiblevalue.c index e5d7cc29da..06e2bd8389 100644 --- a/gtk/gtkaccessiblevalue.c +++ b/gtk/gtkaccessiblevalue.c @@ -1332,7 +1332,18 @@ gtk_accessible_value_collect_value (const GtkAccessibleCollect *cstate, GtkAccessibleValueRefListCtor ctor = (GtkAccessibleValueRefListCtor) cstate->ctor; - GList *value = g_value_get_pointer (value_); + GList *value; + + if (g_type_is_a (G_VALUE_TYPE(value_), GTK_ACCESSIBLE_LIST)) + { + GtkAccessibleList *boxed = g_value_get_boxed (value_); + + value = gtk_accessible_list_get_objects (boxed); + } + else + { + value = g_value_get_pointer (value_); + } if (ctor == NULL) {