a11y: support multiple levels of editable delegations in AT-SPI text

Gtk.Editable.get_delegate is allowed to return another
delegating Gtk.Editable. However, the AT-SPI text
implementationn for Gtk.Editables does not handle
delegate chaining.

In the wild, you will find a Gtk.Text as the delegate of
a Gtk.SpinButton, that is in turn the delegate of an
Adw.SpinRow in libadwaita.

Note: This does not handle the more dangerous possibility
of a delegate loop when built with G_DISABLE_ASSERT,
otherwise stops after the arbitrarily chosen number of
six steps of delegation.

Signed-off-by: Markus Göllnitz <camelcasenick@bewares.it>
This commit is contained in:
Markus Göllnitz
2024-03-01 04:01:56 +01:00
parent eba9b116ed
commit f284331f79

View File

@@ -1058,15 +1058,20 @@ gtk_editable_get_text_widget (GtkWidget *widget)
{
if (GTK_IS_EDITABLE (widget))
{
GtkEditable *delegate;
GtkEditable *editable;
guint redirects = 0;
delegate = gtk_editable_get_delegate (GTK_EDITABLE (widget));
editable = GTK_EDITABLE (widget);
if (GTK_IS_TEXT (delegate))
return GTK_TEXT (delegate);
do {
if (GTK_IS_TEXT (editable))
return GTK_TEXT (editable);
if (GTK_IS_TEXT (widget))
return GTK_TEXT (widget);
if (++redirects >= 6)
g_assert_not_reached ();
editable = gtk_editable_get_delegate (editable);
} while (editable != NULL);
}
return NULL;