Mark Accessible getters as transfer full
authorEmmanuele Bassi <ebassi@gnome.org>
Fri, 24 Feb 2023 12:10:16 +0000 (12:10 +0000)
committerEmmanuele Bassi <ebassi@gnome.org>
Fri, 3 Mar 2023 02:13:26 +0000 (02:13 +0000)
GtkAccessible implementations in C can get away returning objects just
by shuffling pointers around, but higher level languages prefer using
full ownership transfer in virtual functions.

Fixes: #5615
gtk/a11y/gtkatspicomponent.c
gtk/a11y/gtkatspicontext.c
gtk/a11y/gtkatspiroot.c
gtk/a11y/gtkatspiselection.c
gtk/gtkaccessible.c
gtk/gtkaccessible.h
gtk/gtkstack.c
gtk/gtkwidget.c

index 7da968d1d1dffc5c81b2809fc9cc1fd172736fd4..3a21a8a97f461eabde414f119e698589ee6ed9db 100644 (file)
@@ -158,9 +158,12 @@ component_handle_method (GDBusConnection       *connection,
         }
       else
         {
-          GtkAtSpiContext *ctx = GTK_AT_SPI_CONTEXT (gtk_accessible_get_at_context (GTK_ACCESSIBLE (child)));
+          GtkATContext *context = gtk_accessible_get_at_context (GTK_ACCESSIBLE (child));
+          GtkAtSpiContext *ctx = GTK_AT_SPI_CONTEXT (context);
 
           g_dbus_method_invocation_return_value (invocation, g_variant_new ("(@(so))", gtk_at_spi_context_to_ref (ctx)));
+
+          g_object_unref (context);
         }
     }
   else if (g_strcmp0 (method_name, "GetExtents") == 0)
index 18e5bcfce1796817b6455bcf5978b180f7f71120..d292e9e2cc5869478c1b7233e15d5e527df2fac4 100644 (file)
@@ -331,7 +331,6 @@ collect_relations (GtkAtSpiContext *self,
   };
   GtkAccessibleValue *value;
   GList *list, *l;
-  GtkATContext *target_ctx;
   int i;
 
   for (i = 0; i < G_N_ELEMENTS (map); i++)
@@ -346,13 +345,16 @@ collect_relations (GtkAtSpiContext *self,
 
       for (l = list; l; l = l->next)
         {
-          target_ctx = gtk_accessible_get_at_context (GTK_ACCESSIBLE (l->data));
+          GtkATContext *target_ctx =
+            gtk_accessible_get_at_context (GTK_ACCESSIBLE (l->data));
 
           /* Realize the ATContext of the target, so we can ask for its ref */
           gtk_at_context_realize (target_ctx);
 
           g_variant_builder_add (&b, "@(so)",
                                  gtk_at_spi_context_to_ref (GTK_AT_SPI_CONTEXT (target_ctx)));
+
+          g_object_unref (target_ctx);
         }
 
       g_variant_builder_add (builder, "(ua(so))", map[i].s, &b);
@@ -364,24 +366,30 @@ static int
 get_index_in (GtkAccessible *parent,
               GtkAccessible *child)
 {
-  GtkAccessible *candidate;
-  guint res;
-
   if (parent == NULL)
     return -1;
 
-  res = 0;
+  guint res = 0;
+  GtkAccessible *candidate;
   for (candidate = gtk_accessible_get_first_accessible_child (parent);
        candidate != NULL;
        candidate = gtk_accessible_get_next_accessible_sibling (candidate))
     {
       if (candidate == child)
-        return res;
+        {
+          g_object_unref (candidate);
+          return res;
+        }
 
       if (!gtk_accessible_should_present (candidate))
-        continue;
+        {
+          g_object_unref (candidate);
+          continue;
+        }
 
       res++;
+
+      g_object_unref (candidate);
     }
 
   return -1;
@@ -393,7 +401,13 @@ get_index_in_parent (GtkAccessible *accessible)
   GtkAccessible *parent = gtk_accessible_get_accessible_parent (accessible);
 
   if (parent != NULL)
-    return get_index_in (parent, accessible);
+    {
+      int res = get_index_in (parent, accessible);
+
+      g_object_unref (parent);
+
+      return res;
+    }
 
   return -1;
 }
@@ -429,7 +443,6 @@ static GVariant *
 get_parent_context_ref (GtkAccessible *accessible)
 {
   GVariant *res = NULL;
-
   GtkAccessible *parent = gtk_accessible_get_accessible_parent (accessible);
 
   if (parent == NULL)
@@ -438,13 +451,19 @@ get_parent_context_ref (GtkAccessible *accessible)
       GtkAtSpiContext *self = GTK_AT_SPI_CONTEXT (context);
 
       res = gtk_at_spi_root_to_ref (self->root);
+
+      g_object_unref (context);
     }
   else
     {
       GtkATContext *parent_context = gtk_accessible_get_at_context (parent);
+
       gtk_at_context_realize (parent_context);
 
       res = gtk_at_spi_context_to_ref (GTK_AT_SPI_CONTEXT (parent_context));
+
+      g_object_unref (parent_context);
+      g_object_unref (parent);
     }
 
   if (res == NULL)
@@ -525,30 +544,37 @@ handle_accessible_method (GDBusConnection       *connection,
     {
       GtkATContext *context = NULL;
       GtkAccessible *accessible;
+      GtkAccessible *child = NULL;
       int idx, presentable_idx;
 
       g_variant_get (parameters, "(i)", &idx);
 
       accessible = gtk_at_context_get_accessible (GTK_AT_CONTEXT (self));
 
-      GtkAccessible *child;
-
       presentable_idx = 0;
+
       for (child = gtk_accessible_get_first_accessible_child (accessible);
            child != NULL;
            child = gtk_accessible_get_next_accessible_sibling (child))
         {
           if (!gtk_accessible_should_present (child))
+            {
+              g_object_unref (child);
               continue;
+            }
 
           if (presentable_idx == idx)
             break;
-          presentable_idx++;
 
+          presentable_idx += 1;
+
+          g_object_unref (child);
         }
-      if (child)
+
+      if (child != NULL)
         {
           context = gtk_accessible_get_at_context (child);
+          g_object_unref (child);
         }
 
       if (context == NULL)
@@ -564,22 +590,26 @@ handle_accessible_method (GDBusConnection       *connection,
       gtk_at_context_realize (context);
 
       GVariant *ref = gtk_at_spi_context_to_ref (GTK_AT_SPI_CONTEXT (context));
-
       g_dbus_method_invocation_return_value (invocation, g_variant_new ("(@(so))", ref));
+
+      g_object_unref (context);
     }
   else if (g_strcmp0 (method_name, "GetChildren") == 0)
     {
       GVariantBuilder builder = G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE ("a(so)"));
 
       GtkAccessible *accessible = gtk_at_context_get_accessible (GTK_AT_CONTEXT (self));
+      GtkAccessible *child = NULL;
 
-      GtkAccessible *child;
       for (child = gtk_accessible_get_first_accessible_child (accessible);
            child != NULL;
            child = gtk_accessible_get_next_accessible_sibling (child))
-      {
+        {
           if (!gtk_accessible_should_present (child))
-            continue;
+            {
+              g_object_unref (child);
+              continue;
+            }
 
           GtkATContext *context = gtk_accessible_get_at_context (child);
 
@@ -590,6 +620,9 @@ handle_accessible_method (GDBusConnection       *connection,
 
           if (ref != NULL)
             g_variant_builder_add (&builder, "@(so)", ref);
+
+          g_object_unref (context);
+          g_object_unref (child);
         }
 
       g_dbus_method_invocation_return_value (invocation, g_variant_new ("(a(so))", &builder));
@@ -878,8 +911,6 @@ gtk_at_spi_context_state_change (GtkATContext                *ctx,
 
   if (changed_states & GTK_ACCESSIBLE_STATE_CHANGE_HIDDEN)
     {
-      GtkAccessible *parent;
-      GtkATContext *context;
       GtkAccessibleChildChange change;
 
       value = gtk_accessible_attribute_set_get_value (states, GTK_ACCESSIBLE_STATE_HIDDEN);
@@ -895,10 +926,15 @@ gtk_at_spi_context_state_change (GtkATContext                *ctx,
         }
       else
         {
-          parent = gtk_accessible_get_accessible_parent (accessible);
+          GtkAccessible *parent =
+            gtk_accessible_get_accessible_parent (accessible);
+          GtkATContext *context =
+            gtk_accessible_get_at_context (parent);
 
-          context = gtk_accessible_get_at_context (parent);
           gtk_at_context_child_changed (context, change, accessible);
+
+          g_object_unref (context);
+          g_object_unref (parent);
         }
     }
 
@@ -1147,9 +1183,18 @@ gtk_at_spi_context_child_change (GtkATContext             *ctx,
   int idx = 0;
 
   if (parent == NULL)
-    idx = -1;
+    {
+      idx = -1;
+    }
   else if (parent == accessible)
-    idx = get_index_in (accessible, child);
+    {
+      idx = get_index_in (accessible, child);
+      g_object_unref (parent);
+    }
+  else
+    {
+      g_object_unref (parent);
+    }
 
   if (change & GTK_ACCESSIBLE_CHILD_CHANGE_ADDED)
     emit_children_changed (self,
@@ -1161,6 +1206,8 @@ gtk_at_spi_context_child_change (GtkATContext             *ctx,
                            GTK_AT_SPI_CONTEXT (child_context),
                            idx,
                            GTK_ACCESSIBLE_CHILD_STATE_REMOVED);
+
+  g_object_unref (child_context);
 }
 /* }}} */
 /* {{{ D-Bus Registration */
@@ -1729,15 +1776,19 @@ gtk_at_spi_context_get_child_count (GtkAtSpiContext *self)
   int n_children = 0;
 
   GtkAccessible *child = NULL;
-
   for (child = gtk_accessible_get_first_accessible_child (accessible);
        child != NULL;
        child = gtk_accessible_get_next_accessible_sibling (child))
     {
       if (!gtk_accessible_should_present (child))
-        continue;
+        {
+          g_object_unref (child);
+          continue;
+        }
+
+      n_children += 1;
 
-      n_children++;
+      g_object_unref (child);
     }
 
   return n_children;
index 78c4d7c0de0c0eebbc84f1288db3adfc5453cfe4..d3b488b0aeb61efdf17c6fccd9a375c8a6b4088c 100644 (file)
@@ -314,6 +314,8 @@ handle_accessible_method (GDBusConnection       *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_object_unref (context);
     }
   else if (g_strcmp0 (method_name, "GetChildren") == 0)
     {
@@ -334,6 +336,8 @@ handle_accessible_method (GDBusConnection       *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));
@@ -453,6 +457,8 @@ gtk_at_spi_root_child_changed (GtkAtSpiRoot             *self,
       GtkATContext *context = gtk_accessible_get_at_context (child);
 
       window_ref = gtk_at_spi_context_to_ref (GTK_AT_SPI_CONTEXT (context));
+
+      g_object_unref (context);
     }
 
   switch (change)
index e5d9172f14d582e6b37db5dd86ebb44cb0c20c75..db2c76c03e3ae540eb1f72cf132a514c01613314 100644 (file)
@@ -94,7 +94,9 @@ listbox_handle_method (GDBusConnection       *connection,
       else
         {
           GtkATContext *ctx = gtk_accessible_get_at_context (GTK_ACCESSIBLE (counter.child));
-          g_dbus_method_invocation_return_value (invocation, g_variant_new ("(@(so))", gtk_at_spi_context_to_ref (GTK_AT_SPI_CONTEXT (ctx))));
+          g_dbus_method_invocation_return_value (invocation,
+            g_variant_new ("(@(so))", gtk_at_spi_context_to_ref (GTK_AT_SPI_CONTEXT (ctx))));
+          g_object_unref (ctx);
         }
     }
   else if (g_strcmp0 (method_name, "SelectChild") == 0)
@@ -271,7 +273,8 @@ listview_handle_method (GDBusConnection       *connection,
         {
           GtkATContext *ctx = gtk_accessible_get_at_context (GTK_ACCESSIBLE (child));
           g_dbus_method_invocation_return_value (invocation,
-              g_variant_new ("(@(so))", gtk_at_spi_context_to_ref (GTK_AT_SPI_CONTEXT (ctx))));
+            g_variant_new ("(@(so))", gtk_at_spi_context_to_ref (GTK_AT_SPI_CONTEXT (ctx))));
+          g_object_unref (ctx);
         }
     }
   else if (g_strcmp0 (method_name, "SelectChild") == 0)
@@ -495,7 +498,9 @@ flowbox_handle_method (GDBusConnection       *connection,
       else
         {
           GtkATContext *ctx = gtk_accessible_get_at_context (GTK_ACCESSIBLE (counter.child));
-          g_dbus_method_invocation_return_value (invocation, g_variant_new ("(@(so))", gtk_at_spi_context_to_ref (GTK_AT_SPI_CONTEXT (ctx))));
+          g_dbus_method_invocation_return_value (invocation,
+            g_variant_new ("(@(so))", gtk_at_spi_context_to_ref (GTK_AT_SPI_CONTEXT (ctx))));
+          g_object_unref (ctx);
         }
     }
   else if (g_strcmp0 (method_name, "SelectChild") == 0)
@@ -761,7 +766,8 @@ stackswitcher_handle_method (GDBusConnection       *connection,
         {
           GtkATContext *ctx = gtk_accessible_get_at_context (GTK_ACCESSIBLE (child));
           g_dbus_method_invocation_return_value (invocation,
-               g_variant_new ("(@(so))", gtk_at_spi_context_to_ref (GTK_AT_SPI_CONTEXT (ctx))));
+            g_variant_new ("(@(so))", gtk_at_spi_context_to_ref (GTK_AT_SPI_CONTEXT (ctx))));
+          g_object_unref (ctx);
         }
     }
   else if (g_strcmp0 (method_name, "SelectChild") == 0)
@@ -891,7 +897,8 @@ notebook_handle_method (GDBusConnection       *connection,
         {
           GtkATContext *ctx = gtk_accessible_get_at_context (GTK_ACCESSIBLE (child));
           g_dbus_method_invocation_return_value (invocation,
-               g_variant_new ("(@(so))", gtk_at_spi_context_to_ref (GTK_AT_SPI_CONTEXT (ctx))));
+            g_variant_new ("(@(so))", gtk_at_spi_context_to_ref (GTK_AT_SPI_CONTEXT (ctx))));
+          g_object_unref (ctx);
         }
     }
   else if (g_strcmp0 (method_name, "SelectChild") == 0)
index e12ec8f3c30eba6b31c4756fd0af86a23dcc9aae..3d3839cb6865767b85fb4a3c0a5121c914a389b2 100644 (file)
@@ -91,9 +91,9 @@ gtk_accessible_default_init (GtkAccessibleInterface *iface)
  * gtk_accessible_get_at_context:
  * @self: a `GtkAccessible`
  *
- * Retrieves the `GtkATContext` for the given `GtkAccessible`.
+ * Retrieves the accessible implementation for the given `GtkAccessible`.
  *
- * Returns: (transfer none): the `GtkATContext`
+ * Returns: (transfer full): the accessible implementation object
  *
  * Since: 4.10
  */
@@ -109,11 +109,11 @@ gtk_accessible_get_at_context (GtkAccessible *self)
  * gtk_accessible_get_accessible_parent:
  * @self: a `GtkAccessible`
  *
- * Retrieves the accessible accessible for an accessible object
+ * Retrieves the accessible parent for an accessible object.
  *
- * This function returns `NULL` for top level widgets
+ * This function returns `NULL` for top level widgets.
  *
- * Returns: (transfer none) (nullable): the accessible parent
+ * Returns: (transfer full) (nullable): the accessible parent
  *
  * Since: 4.10
  */
@@ -128,9 +128,9 @@ gtk_accessible_get_accessible_parent (GtkAccessible *self)
   context = gtk_accessible_get_at_context (self);
   if (context != NULL)
     parent = gtk_at_context_get_accessible_parent (context);
+
   if (parent != NULL)
-    return parent;
+    return g_object_ref (parent);
   else
     return GTK_ACCESSIBLE_GET_IFACE (self)->get_accessible_parent (self);
 }
@@ -177,6 +177,7 @@ gtk_accessible_set_accessible_parent (GtkAccessible *self,
  * @new_sibling: (nullable): the new next accessible sibling to set
  *
  * Updates the next accessible sibling of @self.
+ *
  * That might be useful when a new child of a custom `GtkAccessible`
  * is created, and it needs to be linked to a previous child.
  *
@@ -193,7 +194,7 @@ gtk_accessible_update_next_accessible_sibling (GtkAccessible *self,
   context = gtk_accessible_get_at_context (self);
   if (!context)
     return;
-  
+
   if (gtk_at_context_get_accessible_parent (context) == NULL)
   {
     g_critical ("Failed to update next accessible sibling: no parent accessible set for this accessible");
@@ -209,7 +210,7 @@ gtk_accessible_update_next_accessible_sibling (GtkAccessible *self,
  *
  * Retrieves the first accessible child of an accessible object.
  *
- * Returns: (transfer none) (nullable): the first accessible child
+ * Returns: (transfer full) (nullable): the first accessible child
  *
  * since: 4.10
  */
@@ -227,7 +228,7 @@ gtk_accessible_get_first_accessible_child (GtkAccessible *self)
  *
  * Retrieves the next accessible sibling of an accessible object
  *
- * Returns: (transfer none) (nullable): the next accessible sibling
+ * Returns: (transfer full) (nullable): the next accessible sibling
  *
  * since: 4.10
  */
@@ -240,7 +241,14 @@ gtk_accessible_get_next_accessible_sibling (GtkAccessible *self)
 
   context = gtk_accessible_get_at_context (self);
   if (context != NULL && gtk_at_context_get_accessible_parent (context) != NULL)
-    return gtk_at_context_get_next_accessible_sibling (context);
+    {
+      GtkAccessible *sibling = gtk_at_context_get_next_accessible_sibling (context);
+
+      if (sibling != NULL)
+        return g_object_ref (sibling);
+
+      return NULL;
+    }
   else
     return GTK_ACCESSIBLE_GET_IFACE (self)->get_next_accessible_sibling (self);
 }
index 8b40cf8272fd20094313bc687d219d8289006c22..f4c1531f4000b0d66e9021d8c25e8323485c3b16 100644 (file)
@@ -73,7 +73,7 @@ struct _GtkAccessibleInterface
    * Retrieves the platform-specific accessibility context for the
    * accessible implementation.
    *
-   * Returns: (transfer none) (nullable): the accessibility context
+   * Returns: (transfer full) (nullable): the accessibility context
    *
    * Since: 4.10
    */
@@ -101,7 +101,7 @@ struct _GtkAccessibleInterface
    *
    * This virtual function should return `NULL` for top level objects.
    *
-   * Returns: (nullable) (transfer none): the accessible parent
+   * Returns: (nullable) (transfer full): the accessible parent
    *
    * Since: 4.10
    */
@@ -113,7 +113,7 @@ struct _GtkAccessibleInterface
    *
    * Retrieves the first accessible child of an accessible object.
    *
-   * Returns: (transfer none) (nullable): an accessible object
+   * Returns: (transfer full) (nullable): an accessible object
    *
    * Since: 4.10
    */
@@ -125,7 +125,7 @@ struct _GtkAccessibleInterface
    *
    * Retrieves the next accessible sibling of an accessible object.
    *
-   * Returns: (transfer none) (nullable): an accessible object
+   * Returns: (transfer full) (nullable): an accessible object
    *
    * Since: 4.10
    */
index 05ad60504b55062d73e484503812708829866c7d..8669493d4fb61197849550d0ca1389efacb55194 100644 (file)
@@ -246,9 +246,11 @@ gtk_stack_page_accessible_get_at_context (GtkAccessible *accessible)
         display = gdk_display_get_default ();
 
       page->at_context = gtk_at_context_create (role, accessible, display);
+      if (page->at_context == NULL)
+        return NULL;
     }
 
-  return page->at_context;
+  return g_object_ref (page->at_context);
 }
 
 static gboolean
@@ -262,30 +264,39 @@ static GtkAccessible *
 gtk_stack_page_accessible_get_accessible_parent (GtkAccessible *accessible)
 {
   GtkStackPage *page = GTK_STACK_PAGE (accessible);
+  GtkWidget *parent;
 
   if (page->widget == NULL)
     return NULL;
-  else
-    return GTK_ACCESSIBLE (gtk_widget_get_parent (page->widget));
+
+  parent = _gtk_widget_get_parent (page->widget);
+
+  return GTK_ACCESSIBLE (g_object_ref (parent));
 }
 
 static GtkAccessible *
-gtk_stack_page_accessible_get_first_accessible_child(GtkAccessible *accessible)
+gtk_stack_page_accessible_get_first_accessible_child (GtkAccessible *accessible)
 {
   GtkStackPage *page = GTK_STACK_PAGE (accessible);
+  GtkWidget *child;
 
-  if (page->widget != NULL)
-    return GTK_ACCESSIBLE (page->widget);
-  else
+  if (page->widget == NULL)
     return NULL;
+
+  child = _gtk_widget_get_first_child (page->widget);
+
+  return GTK_ACCESSIBLE (g_object_ref (child));
 }
 
 static GtkAccessible *
-gtk_stack_page_accessible_get_next_accessible_sibling(GtkAccessible *accessible)
+gtk_stack_page_accessible_get_next_accessible_sibling (GtkAccessible *accessible)
 {
   GtkStackPage *page = GTK_STACK_PAGE (accessible);
 
-  return GTK_ACCESSIBLE (page->next_page);
+  if (page->next_page == NULL)
+    return NULL;
+
+  return GTK_ACCESSIBLE (g_object_ref (page->next_page));
 }
 
 static gboolean
@@ -791,7 +802,8 @@ gtk_stack_accessible_get_first_accessible_child (GtkAccessible *accessible)
   GtkStack *stack = GTK_STACK (accessible);
   GtkStackPrivate *priv = gtk_stack_get_instance_private (stack);
   GtkStackPage *page = g_ptr_array_index (priv->children, 0);
-  return GTK_ACCESSIBLE (page);
+
+  return GTK_ACCESSIBLE (g_object_ref (page));
 }
 
 static void
index 0560b638403c484035e711dd7d1f67b32a13178f..f67893837f6d9c2a639923c8274510d4b74a7310 100644 (file)
@@ -8486,19 +8486,34 @@ gtk_widget_accessible_get_platform_state (GtkAccessible              *self,
 static GtkAccessible *
 gtk_widget_accessible_get_accessible_parent (GtkAccessible *self)
 {
-  return GTK_ACCESSIBLE (gtk_widget_get_parent (GTK_WIDGET (self)));
+  GtkWidget *parent = _gtk_widget_get_parent (GTK_WIDGET (self));
+
+  if (parent == NULL)
+    return NULL;
+
+  return GTK_ACCESSIBLE (g_object_ref (parent));
 }
 
 static GtkAccessible *
 gtk_widget_accessible_get_next_accessible_sibling (GtkAccessible *self)
 {
-  return GTK_ACCESSIBLE (gtk_widget_get_next_sibling (GTK_WIDGET (self)));
+  GtkWidget *sibling = _gtk_widget_get_next_sibling (GTK_WIDGET (self));
+
+  if (sibling == NULL)
+    return NULL;
+
+  return GTK_ACCESSIBLE (g_object_ref (sibling));
 }
 
 static GtkAccessible *
 gtk_widget_accessible_get_first_accessible_child (GtkAccessible *self)
 {
-  return GTK_ACCESSIBLE (gtk_widget_get_first_child (GTK_WIDGET (self)));
+  GtkWidget *child = _gtk_widget_get_first_child (GTK_WIDGET (self));
+
+  if (child == NULL)
+    return NULL;
+
+  return GTK_ACCESSIBLE (g_object_ref (child));
 }
 
 static gboolean