From 3a867e26d0a6454ea6b0f8aec499ffefca123758 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sat, 10 Oct 2020 10:43:59 -0400 Subject: [PATCH] atspicontext: Implement GetRelationSet This translates relations as far as the match. I'm not sure yet what we can do about the fact that atspi expects relations to be bidirectional (ie have label-for *and* labelled-by) while aria has only one direction. --- gtk/a11y/gtkatspicontext.c | 50 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/gtk/a11y/gtkatspicontext.c b/gtk/a11y/gtkatspicontext.c index 32b85ffabd..b7031a9a92 100644 --- a/gtk/a11y/gtkatspicontext.c +++ b/gtk/a11y/gtkatspicontext.c @@ -180,6 +180,50 @@ collect_states (GtkAtSpiContext *self, g_variant_builder_add (builder, "u", (guint32) (state >> 32)); } +static void +collect_relations (GtkAtSpiContext *self, + GVariantBuilder *builder) +{ + GtkATContext *ctx = GTK_AT_CONTEXT (self); + struct { + GtkAccessibleRelation r; + AtspiRelationType s; + } map[] = { + { GTK_ACCESSIBLE_RELATION_LABELLED_BY, ATSPI_RELATION_LABELLED_BY }, + { GTK_ACCESSIBLE_RELATION_CONTROLS, ATSPI_RELATION_CONTROLLER_FOR }, + { GTK_ACCESSIBLE_RELATION_DESCRIBED_BY, ATSPI_RELATION_DESCRIBED_BY }, + { GTK_ACCESSIBLE_RELATION_FLOW_TO, ATSPI_RELATION_FLOWS_TO}, + }; + GtkAccessibleValue *value; + GList *list, *l; + GtkATContext *target_ctx; + const char *unique_name; + int i; + + unique_name = g_dbus_connection_get_unique_name (self->connection); + + for (i = 0; i < G_N_ELEMENTS (map); i++) + { + if (!gtk_at_context_has_accessible_relation (ctx, map[i].r)) + continue; + + GVariantBuilder b = G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE ("a(so)")); + + value = gtk_at_context_get_accessible_relation (ctx, map[i].r); + list = gtk_reference_list_accessible_value_get (value); + + for (l = list; l; l = l->next) + { + target_ctx = gtk_accessible_get_at_context (GTK_ACCESSIBLE (l->data)); + g_variant_builder_add (&b, "(so)", + unique_name, + GTK_AT_SPI_CONTEXT (target_ctx)->context_path); + } + + g_variant_builder_add (builder, "(ua(so))", map[i].s, &b); + } +} + static void handle_accessible_method (GDBusConnection *connection, const gchar *sender, @@ -324,6 +368,12 @@ handle_accessible_method (GDBusConnection *connection, g_dbus_method_invocation_return_value (invocation, g_variant_new ("(i)", idx)); } + else if (g_strcmp0 (method_name, "GetRelationSet") == 0) + { + GVariantBuilder builder = G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE ("a(ua(so))")); + collect_relations (self, &builder); + g_dbus_method_invocation_return_value (invocation, g_variant_new ("(a(ua(so)))", &builder)); + } else if (g_strcmp0 (method_name, "GetInterfaces") == 0) { GtkAccessible *accessible = gtk_at_context_get_accessible (GTK_AT_CONTEXT (self));