[gtk/matthiasc/atspi-child] a11y: Improve child notification for toplevels



commit e7b290debbca685220a0c96ddc8c5aab13138f4f
Author: Matthias Clasen <mclasen redhat com>
Date:   Sat Oct 24 13:13:07 2020 -0400

    a11y: Improve child notification for toplevels
    
    We need to translate the list model position into
    an accessible tree position, since hidden toplevels
    will be skipped.
    
    While we are at it, add an api for this notification
    that will be used in the next commit.

 gtk/a11y/gtkatspiroot.c        | 78 ++++++++++++++++++++++++++++++++----------
 gtk/a11y/gtkatspirootprivate.h |  6 ++++
 2 files changed, 65 insertions(+), 19 deletions(-)
---
diff --git a/gtk/a11y/gtkatspiroot.c b/gtk/a11y/gtkatspiroot.c
index 8c35fb6a29..21beb2eab3 100644
--- a/gtk/a11y/gtkatspiroot.c
+++ b/gtk/a11y/gtkatspiroot.c
@@ -412,8 +412,59 @@ root_toplevels__items_changed (GtkAtSpiRoot *self,
                                guint         added,
                                GListModel   *toplevels)
 {
-  GtkWidget *window = g_list_model_get_item (self->toplevels, position);
-  GVariant *window_ref = NULL;
+  if (added == 1 && removed == 0)
+    {
+      GtkWidget *window;
+
+      window = GTK_WIDGET (g_list_model_get_item (self->toplevels, position));
+      gtk_at_spi_root_child_changed (self,
+                                     GTK_ACCESSIBLE_CHILD_STATE_ADDED,
+                                     G_MAXUINT,
+                                     window);
+      g_object_unref (window);
+    }
+  else if (added == 0 && removed == 1)
+    {
+      gtk_at_spi_root_child_changed (self,
+                                     GTK_ACCESSIBLE_CHILD_STATE_REMOVED,
+                                     position,
+                                     NULL);
+    }
+  else
+    {
+      g_assert_not_reached ();
+    }
+}
+
+void
+gtk_at_spi_root_child_changed (GtkAtSpiRoot             *self,
+                               GtkAccessibleChildState   state,
+                               guint                     position,
+                               GtkWidget                *window)
+{
+  guint n, i;
+  int idx = 0;
+  GVariant *window_ref;
+
+  /* We can be called either with a valid position and window == NULL
+   * or with position == G_MAXUINT and a valid window. In both cases,
+   * we need to determine the index of where the removed object would
+   * have been in the accessible tree.
+   */
+  for (i = 0, n = g_list_model_get_n_items (self->toplevels); i < n; i++)
+    {
+      GtkAccessible *item = g_list_model_get_item (self->toplevels, i);
+
+      g_object_unref (item);
+
+      if (i == position || item == GTK_ACCESSIBLE (window))
+        break;
+
+      if (!gtk_accessible_should_present (item))
+        continue;
+
+      idx++;
+    }
 
   if (window == NULL)
     {
@@ -426,23 +477,12 @@ root_toplevels__items_changed (GtkAtSpiRoot *self,
       window_ref = gtk_at_spi_context_to_ref (GTK_AT_SPI_CONTEXT (context));
     }
 
-  if (added == 1 && removed == 0)
-    gtk_at_spi_emit_children_changed (self->connection,
-                                      self->root_path,
-                                      GTK_ACCESSIBLE_CHILD_STATE_ADDED,
-                                      position,
-                                      gtk_at_spi_root_to_ref (self),
-                                      window_ref);
-  else if (removed == 1 && added == 0)
-    gtk_at_spi_emit_children_changed (self->connection,
-                                      self->root_path,
-                                      GTK_ACCESSIBLE_CHILD_STATE_REMOVED,
-                                      position,
-                                      gtk_at_spi_root_to_ref (self),
-                                      window_ref);
-
-  if (window != NULL)
-    g_object_unref (window);
+  gtk_at_spi_emit_children_changed (self->connection,
+                                    self->root_path,
+                                    state,
+                                    idx,
+                                    gtk_at_spi_root_to_ref (self),
+                                    window_ref);
 }
 
 static void
diff --git a/gtk/a11y/gtkatspirootprivate.h b/gtk/a11y/gtkatspirootprivate.h
index 0ce5e6b693..12cba41085 100644
--- a/gtk/a11y/gtkatspirootprivate.h
+++ b/gtk/a11y/gtkatspirootprivate.h
@@ -42,4 +42,10 @@ gtk_at_spi_root_get_cache (GtkAtSpiRoot *self);
 GVariant *
 gtk_at_spi_root_to_ref (GtkAtSpiRoot *self);
 
+void
+gtk_at_spi_root_child_changed (GtkAtSpiRoot             *self,
+                               GtkAccessibleChildState   state,
+                               guint                     position,
+                               GtkWidget                *window);
+
 G_END_DECLS


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]