diff options
author | Lukáš Tyrychtr <lukastyrychtr@gmail.com> | 2022-09-09 14:16:20 +0200 |
---|---|---|
committer | Emmanuele Bassi <ebassi@gnome.org> | 2023-02-03 11:49:17 +0100 |
commit | 94695bb2768249d2a6ad10c033983353ffc391ef (patch) | |
tree | a46def57c9f963f54f8ece5936f6cd625a02e116 | |
parent | be3611382671283544a5b38b57a28f438e6ceb72 (diff) | |
download | gtk+-94695bb2768249d2a6ad10c033983353ffc391ef.tar.gz |
a11y: Use GtkAccessible for tree traversal
Remove the widget tree dependence from GtkAtSpiContext.
-rw-r--r-- | gtk/a11y/gtkatspicontext.c | 305 |
1 files changed, 71 insertions, 234 deletions
diff --git a/gtk/a11y/gtkatspicontext.c b/gtk/a11y/gtkatspicontext.c index 8380d156b4..034dbdc05a 100644 --- a/gtk/a11y/gtkatspicontext.c +++ b/gtk/a11y/gtkatspicontext.c @@ -329,24 +329,24 @@ collect_relations (GtkAtSpiContext *self, /* }}} */ /* {{{ Accessible implementation */ static int -get_index_in_parent (GtkWidget *widget) +get_index_in (GtkAccessible *parent, GtkAccessible *child) { - GtkWidget *parent = gtk_widget_get_parent (widget); - GtkWidget *child; + GtkAccessible *candidate; int idx; if (parent == NULL) return -1; idx = 0; - for (child = gtk_widget_get_first_child (parent); - child; - child = gtk_widget_get_next_sibling (child)) + while (true) { - if (child == widget) + candidate = gtk_accessible_get_child_at_index (parent, idx); + if (!candidate) + break; + if (candidate == child) return idx; - if (!gtk_accessible_should_present (GTK_ACCESSIBLE (child))) + if (!gtk_accessible_should_present (candidate)) continue; idx++; @@ -356,6 +356,13 @@ get_index_in_parent (GtkWidget *widget) } static int +get_index_in_parent (GtkAccessible *accessible) +{ + GtkAccessible *parent = gtk_accessible_get_parent (accessible); + return get_index_in(parent, accessible); +} + +static int get_index_in_toplevels (GtkWidget *widget) { GListModel *toplevels = gtk_window_get_toplevels (); @@ -387,61 +394,21 @@ get_parent_context_ref (GtkAccessible *accessible) { GVariant *res = NULL; - if (GTK_IS_WIDGET (accessible)) - { - GtkWidget *widget = GTK_WIDGET (accessible); - GtkWidget *parent = gtk_widget_get_parent (widget); - - if (parent == NULL) - { - GtkATContext *context = gtk_accessible_get_at_context (accessible); - GtkAtSpiContext *self = GTK_AT_SPI_CONTEXT (context); - - res = gtk_at_spi_root_to_ref (self->root); - } - else if (GTK_IS_STACK (parent)) - { - GtkStackPage *page = - gtk_stack_get_page (GTK_STACK (parent), widget); - GtkATContext *parent_context = - gtk_accessible_get_at_context (GTK_ACCESSIBLE (page)); - - if (parent_context != NULL) - { - gtk_at_context_realize (parent_context); + GtkAccessible *parent = gtk_accessible_get_parent (accessible); - res = gtk_at_spi_context_to_ref (GTK_AT_SPI_CONTEXT (parent_context)); - } - } - else - { - GtkATContext *parent_context = - gtk_accessible_get_at_context (GTK_ACCESSIBLE (parent)); - - if (parent_context != NULL) - { - /* XXX: This realize() is needed otherwise opening a GtkPopover will - * emit a warning when getting the context's reference - */ - gtk_at_context_realize (parent_context); + if (parent == NULL) + { + GtkATContext *context = gtk_accessible_get_at_context (accessible); + GtkAtSpiContext *self = GTK_AT_SPI_CONTEXT (context); - res = gtk_at_spi_context_to_ref (GTK_AT_SPI_CONTEXT (parent_context)); - } - } + res = gtk_at_spi_root_to_ref (self->root); } - else if (GTK_IS_STACK_PAGE (accessible)) + else { - GtkWidget *parent = - gtk_widget_get_parent (gtk_stack_page_get_child (GTK_STACK_PAGE (accessible))); - GtkATContext *parent_context = - gtk_accessible_get_at_context (GTK_ACCESSIBLE (parent)); + GtkATContext *parent_context = gtk_accessible_get_at_context (parent); + gtk_at_context_realize (parent_context); - if (parent_context != NULL) - { - gtk_at_context_realize (parent_context); - - res = gtk_at_spi_context_to_ref (GTK_AT_SPI_CONTEXT (parent_context)); - } + res = gtk_at_spi_context_to_ref (GTK_AT_SPI_CONTEXT (parent_context)); } if (res == NULL) @@ -528,43 +495,25 @@ handle_accessible_method (GDBusConnection *connection, accessible = gtk_at_context_get_accessible (GTK_AT_CONTEXT (self)); - if (GTK_IS_STACK_PAGE (accessible)) - { - if (idx == 0) - { - GtkWidget *child; + GtkAccessible *child; - child = gtk_stack_page_get_child (GTK_STACK_PAGE (accessible)); - if (gtk_accessible_should_present (GTK_ACCESSIBLE (child))) - context = gtk_accessible_get_at_context (GTK_ACCESSIBLE (child)); - } - } - else if (GTK_IS_WIDGET (accessible)) + real_idx = 0; + do { - GtkWidget *widget = GTK_WIDGET (accessible); - GtkWidget *child; - - real_idx = 0; - for (child = gtk_widget_get_first_child (widget); - child; - child = gtk_widget_get_next_sibling (child)) - { - if (!gtk_accessible_should_present (GTK_ACCESSIBLE (child))) - continue; + child = gtk_accessible_get_child_at_index (accessible, real_idx); + if (!gtk_accessible_should_present (child)) + continue; - if (real_idx == idx) - break; + if (real_idx == idx) + break; - real_idx += 1; - } + real_idx += 1; + } + while (child != NULL); - if (child) - { - if (GTK_IS_STACK (accessible)) - context = gtk_accessible_get_at_context (GTK_ACCESSIBLE (gtk_stack_get_page (GTK_STACK (accessible), child))); - else - context = gtk_accessible_get_at_context (GTK_ACCESSIBLE (child)); - } + if (child) + { + context = gtk_accessible_get_at_context (child); } if (context == NULL) @@ -588,45 +537,27 @@ handle_accessible_method (GDBusConnection *connection, GVariantBuilder builder = G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE ("a(so)")); GtkAccessible *accessible = gtk_at_context_get_accessible (GTK_AT_CONTEXT (self)); - if (GTK_IS_WIDGET (accessible)) - { - GtkWidget *widget = GTK_WIDGET (accessible); - GtkWidget *child; - - for (child = gtk_widget_get_first_child (widget); - child; - child = gtk_widget_get_next_sibling (child)) - { - if (!gtk_accessible_should_present (GTK_ACCESSIBLE (child))) - continue; - GtkATContext *context = gtk_accessible_get_at_context (GTK_ACCESSIBLE (child)); + GtkAccessible *child; + guint idx = 0; - /* Realize the child ATContext in order to get its ref */ - gtk_at_context_realize (context); - - GVariant *ref = gtk_at_spi_context_to_ref (GTK_AT_SPI_CONTEXT (context)); - - if (ref != NULL) - g_variant_builder_add (&builder, "@(so)", ref); - } - } - else if (GTK_IS_STACK_PAGE (accessible)) + while (true) { - GtkWidget *child = gtk_stack_page_get_child (GTK_STACK_PAGE (accessible)); + child = gtk_accessible_get_child_at_index (accessible, idx); + if(!child) + break; + if (!gtk_accessible_should_present (child)) + continue; - if (gtk_accessible_should_present (GTK_ACCESSIBLE (child))) - { - GtkATContext *context = gtk_accessible_get_at_context (GTK_ACCESSIBLE (child)); + GtkATContext *context = gtk_accessible_get_at_context (child); - /* Realize the child ATContext in order to get its ref */ - gtk_at_context_realize (context); + /* Realize the child ATContext in order to get its ref */ + gtk_at_context_realize (context); - GVariant *ref = gtk_at_spi_context_to_ref (GTK_AT_SPI_CONTEXT (context)); + GVariant *ref = gtk_at_spi_context_to_ref (GTK_AT_SPI_CONTEXT (context)); - if (ref != NULL) - g_variant_builder_add (&builder, "@(so)", ref); - } + if (ref != NULL) + g_variant_builder_add (&builder, "@(so)", ref); } g_dbus_method_invocation_return_value (invocation, g_variant_new ("(a(so))", &builder)); @@ -915,7 +846,7 @@ gtk_at_spi_context_state_change (GtkATContext *ctx, if (changed_states & GTK_ACCESSIBLE_STATE_CHANGE_HIDDEN) { - GtkWidget *parent; + GtkAccessible *parent; GtkATContext *context; GtkAccessibleChildChange change; @@ -932,14 +863,9 @@ gtk_at_spi_context_state_change (GtkATContext *ctx, } else { - if (GTK_IS_WIDGET (accessible)) - parent = gtk_widget_get_parent (GTK_WIDGET (accessible)); - else if (GTK_IS_STACK_PAGE (accessible)) - parent = gtk_widget_get_parent (gtk_stack_page_get_child (GTK_STACK_PAGE (accessible))); - else - g_assert_not_reached (); + parent = gtk_accessible_get_parent (accessible); - context = gtk_accessible_get_at_context (GTK_ACCESSIBLE (parent)); + context = gtk_accessible_get_at_context (parent); gtk_at_context_child_changed (context, change, accessible); } } @@ -1201,98 +1127,19 @@ gtk_at_spi_context_child_change (GtkATContext *ctx, GtkAtSpiContext *self = GTK_AT_SPI_CONTEXT (ctx); GtkAccessible *accessible = gtk_at_context_get_accessible (ctx); GtkATContext *child_context = gtk_accessible_get_at_context (child); - GtkWidget *parent_widget; - GtkWidget *child_widget; - int idx = 0; - if (!GTK_IS_WIDGET (accessible)) - return; + int idx = 0; if (child_context == NULL) return; - /* handle the stack page special case */ - if (GTK_IS_WIDGET (child) && - GTK_IS_STACK (gtk_widget_get_parent (GTK_WIDGET (child)))) + if (gtk_accessible_get_parent (child) != accessible) { - GtkWidget *stack; - GtkStackPage *page; - GListModel *pages; - - stack = gtk_widget_get_parent (GTK_WIDGET (child)); - page = gtk_stack_get_page (GTK_STACK (stack), GTK_WIDGET (child)); - pages = G_LIST_MODEL (gtk_stack_get_pages (GTK_STACK (stack))); idx = 0; - for (guint i = 0; i < g_list_model_get_n_items (pages); i++) - { - GtkStackPage *item = g_list_model_get_item (pages, i); - - g_object_unref (item); - - if (!gtk_accessible_should_present (GTK_ACCESSIBLE (item))) - continue; - - if (item == page) - break; - - idx++; - } - g_object_unref (pages); - - if (change & GTK_ACCESSIBLE_CHILD_CHANGE_ADDED) - { - emit_children_changed (GTK_AT_SPI_CONTEXT (gtk_accessible_get_at_context (GTK_ACCESSIBLE (stack))), - GTK_AT_SPI_CONTEXT (gtk_accessible_get_at_context (GTK_ACCESSIBLE (page))), - idx, - GTK_ACCESSIBLE_CHILD_STATE_ADDED); - - emit_children_changed (GTK_AT_SPI_CONTEXT (gtk_accessible_get_at_context (GTK_ACCESSIBLE (page))), - GTK_AT_SPI_CONTEXT (gtk_accessible_get_at_context (child)), - 0, - GTK_ACCESSIBLE_CHILD_STATE_ADDED); - } - - if (change & GTK_ACCESSIBLE_CHILD_CHANGE_REMOVED) - { - emit_children_changed (GTK_AT_SPI_CONTEXT (gtk_accessible_get_at_context (GTK_ACCESSIBLE (page))), - GTK_AT_SPI_CONTEXT (gtk_accessible_get_at_context (child)), - 0, - GTK_ACCESSIBLE_CHILD_STATE_REMOVED); - emit_children_changed (GTK_AT_SPI_CONTEXT (gtk_accessible_get_at_context (GTK_ACCESSIBLE (stack))), - GTK_AT_SPI_CONTEXT (gtk_accessible_get_at_context (GTK_ACCESSIBLE (page))), - idx, - GTK_ACCESSIBLE_CHILD_STATE_REMOVED); - - } - - return; } - - parent_widget = GTK_WIDGET (accessible); - - if (GTK_IS_STACK_PAGE (child)) - child_widget = gtk_stack_page_get_child (GTK_STACK_PAGE (child)); else - child_widget = GTK_WIDGET (child); - - if (gtk_widget_get_parent (child_widget) != parent_widget) { - idx = 0; - } - else - { - for (GtkWidget *iter = gtk_widget_get_first_child (parent_widget); - iter != NULL; - iter = gtk_widget_get_next_sibling (iter)) - { - if (!gtk_accessible_should_present (GTK_ACCESSIBLE (iter))) - continue; - - if (iter == child_widget) - break; - - idx += 1; - } + idx = get_index_in(accessible, child); } if (change & GTK_ACCESSIBLE_CHILD_CHANGE_ADDED) @@ -1858,12 +1705,8 @@ gtk_at_spi_context_get_index_in_parent (GtkAtSpiContext *self) if (GTK_IS_ROOT (accessible)) idx = get_index_in_toplevels (GTK_WIDGET (accessible)); - else if (GTK_IS_STACK_PAGE (accessible)) - idx = get_index_in_parent (gtk_stack_page_get_child (GTK_STACK_PAGE (accessible))); - else if (GTK_IS_STACK (gtk_widget_get_parent (GTK_WIDGET (accessible)))) - idx = 1; else - idx = get_index_in_parent (GTK_WIDGET (accessible)); + idx = get_index_in_parent (accessible); return idx; } @@ -1874,26 +1717,20 @@ gtk_at_spi_context_get_child_count (GtkAtSpiContext *self) g_return_val_if_fail (GTK_IS_AT_SPI_CONTEXT (self), -1); GtkAccessible *accessible = gtk_at_context_get_accessible (GTK_AT_CONTEXT (self)); - int n_children = -1; + int n_children = 0; + + GtkAccessible *child; - if (GTK_IS_WIDGET (accessible)) + + while (true) { - GtkWidget *child; - - n_children = 0; - for (child = gtk_widget_get_first_child (GTK_WIDGET (accessible)); - child; - child = gtk_widget_get_next_sibling (child)) - { - if (!gtk_accessible_should_present (GTK_ACCESSIBLE (child))) - continue; + child = gtk_accessible_get_child_at_index (accessible, n_children); + if (!child) + break; + if (!gtk_accessible_should_present (child)) + continue; - n_children++; - } - } - else if (GTK_IS_STACK_PAGE (accessible)) - { - n_children = 1; + n_children++; } return n_children; |