From f284331f79f13006e13e0e3d2894df5612d9a576 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20G=C3=B6llnitz?= Date: Fri, 1 Mar 2024 04:01:56 +0100 Subject: [PATCH] a11y: support multiple levels of editable delegations in AT-SPI text MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- gtk/a11y/gtkatspitext.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/gtk/a11y/gtkatspitext.c b/gtk/a11y/gtkatspitext.c index a1f16b6f00..0bdcc7aa33 100644 --- a/gtk/a11y/gtkatspitext.c +++ b/gtk/a11y/gtkatspitext.c @@ -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;