From 450e51fd4bcce597382a42ba417489b0f2147888 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));