summaryrefslogtreecommitdiff
path: root/gui-libs/gtk/files/hedronfire-atspi-stale-child.patch
blob: 943f13584c186d5cad90af2ab017b0d45ca0b5f5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
--- a/gtk/a11y/gtkatspiroot.c
+++ b/gtk/a11y/gtkatspiroot.c
@@ -305,30 +305,35 @@
       guint n_toplevels = g_list_model_get_n_items (self->toplevels);
       for (guint i = 0; i < n_toplevels; i++)
         {
-          window = g_list_model_get_item (self->toplevels, i);
-
-          g_object_unref (window);
-
-          if (!gtk_widget_get_visible (window))
-            continue;
-
-          if (real_idx == idx)
-            break;
-
-          real_idx += 1;
-        }
-
+          GtkWidget *candidate = g_list_model_get_item (self->toplevels, i);
+
+          if (gtk_widget_get_visible (candidate) && real_idx++ == idx)
+            {
+              window = candidate;
+              break;
+            }
+
+          g_object_unref (candidate);
+        }
+
+      /* The visible child list can shrink between ChildCount and this call.
+       * Never reuse the last (possibly hidden or unrealized) toplevel for an
+       * index that no longer exists, and always complete the D-Bus request. */
       if (window == NULL)
-        return;
+        {
+          g_dbus_method_invocation_return_value (invocation,
+                                               g_variant_new ("(@(so))", gtk_at_spi_null_ref ()));
+          return;
+        }
 
       GtkATContext *context = gtk_accessible_get_at_context (GTK_ACCESSIBLE (window));
 
-      const char *name = g_dbus_connection_get_unique_name (self->connection);
-      const char *path = gtk_at_spi_context_get_context_path (GTK_AT_SPI_CONTEXT (context));
-
-      g_dbus_method_invocation_return_value (invocation, g_variant_new ("((so))", name, path));
+      g_dbus_method_invocation_return_value (invocation,
+                                           g_variant_new ("(@(so))",
+                                                          gtk_at_spi_context_to_ref (GTK_AT_SPI_CONTEXT (context))));
 
       g_object_unref (context);
+      g_object_unref (window);
     }
   else if (g_strcmp0 (method_name, "GetChildren") == 0)
     {
@@ -339,18 +344,15 @@
         {
           GtkWidget *window = g_list_model_get_item (self->toplevels, i);
 
+          if (gtk_widget_get_visible (window))
+            {
+              GtkATContext *context = gtk_accessible_get_at_context (GTK_ACCESSIBLE (window));
+              g_variant_builder_add_value (&builder,
+                                           gtk_at_spi_context_to_ref (GTK_AT_SPI_CONTEXT (context)));
+              g_object_unref (context);
+            }
+
           g_object_unref (window);
-
-          if (!gtk_widget_get_visible (window))
-            continue;
-
-          GtkATContext *context = gtk_accessible_get_at_context (GTK_ACCESSIBLE (window));
-          const char *name = g_dbus_connection_get_unique_name (self->connection);
-          const char *path = gtk_at_spi_context_get_context_path (GTK_AT_SPI_CONTEXT (context));
-
-          g_variant_builder_add (&builder, "(so)", name, path);
-
-          g_object_unref (context);
         }
 
       g_dbus_method_invocation_return_value (invocation, g_variant_new ("(a(so))", &builder));