Mark Accessible getters as transfer full

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
This commit is contained in:
Emmanuele Bassi 2023-02-24 12:10:16 +00:00
parent 1b4f240883
commit eb0f33d76b
8 changed files with 163 additions and 61 deletions

View 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)

View 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++;
n_children += 1;
g_object_unref (child);
}
return n_children;

View 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)

View 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)

View 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);
}

View 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
*/

View 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

View 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