[gtk/a11y/atspi] atspi: Unregister objects on the bus



commit 62747eb243d6e02c4d0884595b131f8ea329a523
Author: Matthias Clasen <mclasen redhat com>
Date:   Mon Oct 12 14:41:38 2020 -0400

    atspi: Unregister objects on the bus
    
    When a widget is going away, we need to remove
    the context from the bus, or else ATs might have
    the idea to call methods on them, leading to badness.

 gtk/a11y/gtkatspicontext.c | 90 +++++++++++++++++++++++++++++++---------------
 1 file changed, 62 insertions(+), 28 deletions(-)
---
diff --git a/gtk/a11y/gtkatspicontext.c b/gtk/a11y/gtkatspicontext.c
index 5b904c4097..7f330921e7 100644
--- a/gtk/a11y/gtkatspicontext.c
+++ b/gtk/a11y/gtkatspicontext.c
@@ -81,6 +81,9 @@ struct _GtkAtSpiContext
    * collect the answer here.
    */
   GVariant *interfaces;
+
+  guint registration_ids[20];
+  guint n_registered_objects;
 };
 
 enum
@@ -585,55 +588,75 @@ gtk_at_spi_context_register_object (GtkAtSpiContext *self)
   const GDBusInterfaceVTable *vtable;
 
   g_variant_builder_add (&interfaces, "s", "org.a11y.atspi.Accessible");
-  g_dbus_connection_register_object (self->connection,
-                                     self->context_path,
-                                     (GDBusInterfaceInfo *) &atspi_accessible_interface,
-                                     &accessible_vtable,
-                                     self,
-                                     NULL,
-                                     NULL);
-
-  vtable = gtk_atspi_get_text_vtable (widget);
-  if (vtable)
-    {
-      g_variant_builder_add (&interfaces, "s", "org.a11y.atspi.Text");
+  self->registration_ids[self->n_registered_objects] =
       g_dbus_connection_register_object (self->connection,
                                          self->context_path,
-                                         (GDBusInterfaceInfo *) &atspi_text_interface,
-                                         vtable,
+                                         (GDBusInterfaceInfo *) &atspi_accessible_interface,
+                                         &accessible_vtable,
                                          self,
                                          NULL,
                                          NULL);
+  self->n_registered_objects++;
+
+  vtable = gtk_atspi_get_text_vtable (widget);
+  if (vtable)
+    {
+      g_variant_builder_add (&interfaces, "s", "org.a11y.atspi.Text");
+      self->registration_ids[self->n_registered_objects] =
+          g_dbus_connection_register_object (self->connection,
+                                             self->context_path,
+                                             (GDBusInterfaceInfo *) &atspi_text_interface,
+                                             vtable,
+                                             self,
+                                             NULL,
+                                             NULL);
+      self->n_registered_objects++;
     }
 
   vtable = gtk_atspi_get_editable_text_vtable (widget);
   if (vtable)
     {
       g_variant_builder_add (&interfaces, "s", "org.a11y.atspi.EditableText");
-      g_dbus_connection_register_object (self->connection,
-                                         self->context_path,
-                                         (GDBusInterfaceInfo *) &atspi_editable_text_interface,
-                                         vtable,
-                                         self,
-                                         NULL,
-                                         NULL);
+      self->registration_ids[self->n_registered_objects] =
+          g_dbus_connection_register_object (self->connection,
+                                             self->context_path,
+                                             (GDBusInterfaceInfo *) &atspi_editable_text_interface,
+                                             vtable,
+                                             self,
+                                             NULL,
+                                             NULL);
+      self->n_registered_objects++;
     }
   vtable = gtk_atspi_get_value_vtable (widget);
   if (vtable)
     {
       g_variant_builder_add (&interfaces, "s", "org.a11y.atspi.Value");
-      g_dbus_connection_register_object (self->connection,
-                                         self->context_path,
-                                         (GDBusInterfaceInfo *) &atspi_value_interface,
-                                         vtable,
-                                         self,
-                                         NULL,
-                                         NULL);
+      self->registration_ids[self->n_registered_objects] =
+          g_dbus_connection_register_object (self->connection,
+                                             self->context_path,
+                                             (GDBusInterfaceInfo *) &atspi_value_interface,
+                                             vtable,
+                                             self,
+                                             NULL,
+                                             NULL);
+      self->n_registered_objects++;
     }
 
   self->interfaces = g_variant_ref_sink (g_variant_builder_end (&interfaces));
 }
 
+static void
+gtk_at_spi_context_unregister_object (GtkAtSpiContext *self)
+{
+  while (self->n_registered_objects > 0)
+    {
+      self->n_registered_objects--;
+      g_dbus_connection_unregister_object (self->connection,
+                                           self->registration_ids[self->n_registered_objects]);
+      self->registration_ids[self->n_registered_objects] = 0;
+    }
+}
+
 static void
 emit_state_changed (GtkAtSpiContext *self,
                     const char      *name,
@@ -832,6 +855,16 @@ gtk_at_spi_context_state_change (GtkATContext                *ctx,
     emit_state_changed (self, "focused", gtk_widget_has_focus (widget));
 }
 
+static void
+gtk_at_spi_context_dispose (GObject *gobject)
+{
+  GtkAtSpiContext *self = GTK_AT_SPI_CONTEXT (gobject);
+
+  gtk_at_spi_context_unregister_object (self);
+
+  G_OBJECT_CLASS (gtk_at_spi_context_parent_class)->dispose (gobject);
+}
+
 static void
 gtk_at_spi_context_finalize (GObject *gobject)
 {
@@ -965,6 +998,7 @@ gtk_at_spi_context_class_init (GtkAtSpiContextClass *klass)
   gobject_class->set_property = gtk_at_spi_context_set_property;
   gobject_class->get_property = gtk_at_spi_context_get_property;
   gobject_class->finalize = gtk_at_spi_context_finalize;
+  gobject_class->dispose = gtk_at_spi_context_dispose;
 
   context_class->state_change = gtk_at_spi_context_state_change;
 


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