Support accessibility relation lists in bindings such as GJS and Python
This is follow-up from this GJS issue
Background
Currently when using GTK4 in GJS it is not possible to use accessibility relations such as LABELLED_BY
because they require passing a list of pointers inside of a GValue array.
The current signature is...
GDK_AVAILABLE_IN_ALL
void gtk_accessible_update_relation_value (GtkAccessible *self,
int n_relations,
GtkAccessibleRelation relations[],
const GValue values[]);
To use GJS as an example, we can generally convert values to GValue
and support this signature. The issue arises with this code:
widget.update_relation([Gtk.AccessibleRelation.LABELLED_BY], [[label1, label2]])
We can convert [...]
into an array of GValues, but there is no way to convert [label1, label2]
into a GValue - GValue has no built-in "list" notion.
Proposals
There are several ways we could go about solving this - we could even combine aspects of both methods. Regardless, GJS will likely need an override to make the existing update_relation
work as expected without user intervention.
Adding a boxed type
To support the existing signature GJS needs a way to "wrap" [label1, label2]
in a type it knows how to pass, a boxed type would work for this purpose:
widget.update_relation(Gtk.AccessibleRelation.LABELLED_BY, new Gtk.AccessibleRelationList([label1, label2]);
We could either add Gtk.AccessibleRelationList
or perhaps Gtk.AccessibleList
to keep it more generic. This boxed type would hold a reference to a list of GtkAccessible pointers.
We can then update GTK's internally handling to check if the passed GValue is BOXED or not, and in the BOXED case unwrap this type.
Adding new singular utility functions
We could also add new functions which avoid handling multiple relations at a time...
// Not sure what to name this given the current functions are singular, though perhaps we could expose this as-is given the current renaming
gtk_accessible_update_relation_value (GtkAccessibleRelation relation, GValue value);
gtk_accessible_update_relation_values (GtkAccessibleRelation relation, int n_values, GValue[] values);
This solves the issue by offering a "single value" utility function and a "multiple values" utility function, I believe GJS would be able to handle both of these without issue.
The hard part is naming given the current functions are "singular" but update multiple relations at once
Adding utility functions which handle specific relation types
I'm not a huge fan of this option, given we already have the init_value
utilities and this isn't as obvious for users... but we could also expose functions which are specific to the type of the relation value.
gtk_accessible_update_relation_string_value (GtkAccessibleRelation relation, const char* str);
gtk_accessible_update_relation_object_value (GtkAccessibleRelation relation, GtkAccessible* acc);
gtk_accessible_update_relation_list_value (GtkAccessibleRelation relation, int n_values, GValue[] values);
Exploration
I've started cleaning up some thoughts I had on the boxed type here
cc @ebassi