[gtk/matthiasc/atspi-child: 2/2] a11y: Handle stack case for addition/removal




commit a11ab6c995a38fde0eba10a26a2bcebd62ebfefd
Author: Matthias Clasen <mclasen redhat com>
Date:   Thu Oct 22 09:55:50 2020 -0400

    a11y: Handle stack case for addition/removal
    
    Since we interpose stack pages as non-widget accessibles,
    we need to tweak the signals we emit when their corresponding
    widgets get added or removed.

 gtk/a11y/gtkatspicontext.c | 70 ++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 64 insertions(+), 6 deletions(-)
---
diff --git a/gtk/a11y/gtkatspicontext.c b/gtk/a11y/gtkatspicontext.c
index a3b5d8bb22..be3cb128e6 100644
--- a/gtk/a11y/gtkatspicontext.c
+++ b/gtk/a11y/gtkatspicontext.c
@@ -1065,18 +1065,76 @@ 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;
+  GtkATContext *child_context = gtk_accessible_get_at_context (child);
+  GtkWidget *parent_widget;
+  GtkWidget *child_widget;
+  int idx = 0;
 
-  if (!GTK_IS_WIDGET (accessible))
+  if (!GTK_IS_WIDGET (accessible) || !GTK_IS_WIDGET (child))
     return;
 
-  child_context = gtk_accessible_get_at_context (child);
   if (child_context == NULL)
     return;
 
-  GtkWidget *parent_widget = GTK_WIDGET (accessible);
-  GtkWidget *child_widget = GTK_WIDGET (child);
-  int idx = 0;
+  parent_widget = GTK_WIDGET (accessible);
+  child_widget = GTK_WIDGET (child);
+
+  /* handle the stack page special case */
+  if (GTK_IS_WIDGET (child) &&
+      GTK_IS_STACK (gtk_widget_get_parent (GTK_WIDGET (child))))
+    {
+      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;
+    }
 
   if (gtk_widget_get_parent (child_widget) != parent_widget)
     {


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