summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukáš Tyrychtr <lukastyrychtr@gmail.com>2022-09-09 14:16:20 +0200
committerEmmanuele Bassi <ebassi@gnome.org>2023-02-03 11:49:17 +0100
commit94695bb2768249d2a6ad10c033983353ffc391ef (patch)
treea46def57c9f963f54f8ece5936f6cd625a02e116
parentbe3611382671283544a5b38b57a28f438e6ceb72 (diff)
downloadgtk+-94695bb2768249d2a6ad10c033983353ffc391ef.tar.gz
a11y: Use GtkAccessible for tree traversal
Remove the widget tree dependence from GtkAtSpiContext.
-rw-r--r--gtk/a11y/gtkatspicontext.c305
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;