[gtk/ebassi/issue-4825] a11y: Defer object registration after root registration
- From: Emmanuele Bassi <ebassi src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/ebassi/issue-4825] a11y: Defer object registration after root registration
- Date: Tue, 19 Apr 2022 15:14:58 +0000 (UTC)
commit 1c05cb9be18d32e6856292d3e46d0393262238e8
Author: Emmanuele Bassi <ebassi gnome org>
Date: Tue Apr 19 16:12:08 2022 +0100
a11y: Defer object registration after root registration
The root accessible object is registered asynchronously, as it needs to
call a method on the AT-SPI registry daemon. This means we need to defer
registering the GtkAtSpiContext on the accessibility bus and in the
cache until after the registration is complete.
Fixes: #4825
gtk/a11y/gtkatspicontext.c | 29 ++++++++++++++++----------
gtk/a11y/gtkatspiroot.c | 46 ++++++++++++++++++++++++++++++++----------
gtk/a11y/gtkatspirootprivate.h | 6 +++++-
3 files changed, 58 insertions(+), 23 deletions(-)
---
diff --git a/gtk/a11y/gtkatspicontext.c b/gtk/a11y/gtkatspicontext.c
index 43d40ee257..38c0590a65 100644
--- a/gtk/a11y/gtkatspicontext.c
+++ b/gtk/a11y/gtkatspicontext.c
@@ -1418,7 +1418,7 @@ gtk_at_spi_context_unregister_object (GtkAtSpiContext *self)
g_clear_pointer (&self->interfaces, g_variant_unref);
}
/* }}} */
-/* {{{ GObject boilerplate */
+/* {{{ GObject boilerplate */
static void
gtk_at_spi_context_finalize (GObject *gobject)
{
@@ -1443,6 +1443,22 @@ gtk_at_spi_context_constructed (GObject *gobject)
static const char *get_bus_address (GdkDisplay *display);
+static void
+register_object (GtkAtSpiRoot *root,
+ GtkAtSpiContext *context)
+{
+ GtkAccessible *accessible = gtk_at_context_get_accessible (GTK_AT_CONTEXT (context));
+
+ gtk_atspi_connect_text_signals (accessible,
+ (GtkAtspiTextChangedCallback *)emit_text_changed,
+ (GtkAtspiTextSelectionCallback *)emit_text_selection_changed,
+ context);
+ gtk_atspi_connect_selection_signals (accessible,
+ (GtkAtspiSelectionCallback *)emit_selection_changed,
+ context);
+ gtk_at_spi_context_register_object (context);
+}
+
static void
gtk_at_spi_context_realize (GtkATContext *context)
{
@@ -1504,16 +1520,7 @@ gtk_at_spi_context_realize (GtkATContext *context)
}
#endif
- gtk_atspi_connect_text_signals (accessible,
- (GtkAtspiTextChangedCallback *)emit_text_changed,
- (GtkAtspiTextSelectionCallback *)emit_text_selection_changed,
- self);
- gtk_atspi_connect_selection_signals (accessible,
- (GtkAtspiSelectionCallback *)emit_selection_changed,
- self);
- gtk_at_spi_context_register_object (self);
-
- gtk_at_spi_root_queue_register (self->root, self);
+ gtk_at_spi_root_queue_register (self->root, self, register_object);
}
static void
diff --git a/gtk/a11y/gtkatspiroot.c b/gtk/a11y/gtkatspiroot.c
index 88a366c05f..bffc632c18 100644
--- a/gtk/a11y/gtkatspiroot.c
+++ b/gtk/a11y/gtkatspiroot.c
@@ -474,16 +474,24 @@ gtk_at_spi_root_child_changed (GtkAtSpiRoot *self,
window_ref);
}
+typedef struct {
+ GtkAtSpiRoot *root;
+ GtkAtSpiRootRegisterFunc register_func;
+} RegistrationData;
+
static void
on_registration_reply (GObject *gobject,
GAsyncResult *result,
gpointer user_data)
{
- GtkAtSpiRoot *self = user_data;
+ RegistrationData *data = user_data;
+ GtkAtSpiRoot *self = data->root;
GError *error = NULL;
GVariant *reply = g_dbus_connection_call_finish (G_DBUS_CONNECTION (gobject), result, &error);
+ self->register_id = 0;
+
if (error != NULL)
{
g_critical ("Unable to register the application: %s", error->message);
@@ -509,19 +517,27 @@ on_registration_reply (GObject *gobject,
/* Drain the list of queued GtkAtSpiContexts, and add them to the cache */
if (self->queued_contexts != NULL)
{
- for (GList *l = self->queued_contexts; l != NULL; l = l->next)
- gtk_at_spi_cache_add_context (self->cache, l->data);
+ for (GList *l = g_list_reverse (self->queued_contexts); l != NULL; l = l->next)
+ {
+ if (data->register_func != NULL)
+ data->register_func (self, l->data);
+
+ gtk_at_spi_cache_add_context (self->cache, l->data);
+ }
g_clear_pointer (&self->queued_contexts, g_list_free);
}
self->toplevels = gtk_window_get_toplevels ();
+
+ g_free (data);
}
static gboolean
-root_register (gpointer data)
+root_register (gpointer user_data)
{
- GtkAtSpiRoot *self = data;
+ RegistrationData *data = user_data;
+ GtkAtSpiRoot *self = data->root;
const char *unique_name;
/* Register the root element; every application has a single root, so we only
@@ -577,9 +593,7 @@ root_register (gpointer data)
G_DBUS_CALL_FLAGS_NONE, -1,
NULL,
on_registration_reply,
- self);
-
- self->register_id = 0;
+ data);
return G_SOURCE_REMOVE;
}
@@ -587,18 +601,24 @@ root_register (gpointer data)
/*< private >
* gtk_at_spi_root_queue_register:
* @self: a `GtkAtSpiRoot`
+ * @context: the AtSpi context to register
+ * @func: the function to call when the root has been registered
*
* Queues the registration of the root object on the AT-SPI bus.
*/
void
-gtk_at_spi_root_queue_register (GtkAtSpiRoot *self,
- GtkAtSpiContext *context)
+gtk_at_spi_root_queue_register (GtkAtSpiRoot *self,
+ GtkAtSpiContext *context,
+ GtkAtSpiRootRegisterFunc func)
{
/* The cache is available if the root has finished registering itself; if we
* are still waiting for the registration to finish, add the context to a queue
*/
if (self->cache != NULL)
{
+ if (func != NULL)
+ func (self, context);
+
gtk_at_spi_cache_add_context (self->cache, context);
return;
}
@@ -612,7 +632,11 @@ gtk_at_spi_root_queue_register (GtkAtSpiRoot *self,
if (self->register_id != 0)
return;
- self->register_id = g_idle_add (root_register, self);
+ RegistrationData *data = g_new (RegistrationData, 1);
+ data->root = self;
+ data->register_func = func;
+
+ self->register_id = g_idle_add (root_register, data);
gdk_source_set_static_name_by_id (self->register_id, "[gtk] ATSPI root registration");
}
diff --git a/gtk/a11y/gtkatspirootprivate.h b/gtk/a11y/gtkatspirootprivate.h
index d8d42c0e26..7b626fc28e 100644
--- a/gtk/a11y/gtkatspirootprivate.h
+++ b/gtk/a11y/gtkatspirootprivate.h
@@ -34,9 +34,13 @@ G_DECLARE_FINAL_TYPE (GtkAtSpiRoot, gtk_at_spi_root, GTK, AT_SPI_ROOT, GObject)
GtkAtSpiRoot *
gtk_at_spi_root_new (const char *bus_address);
+typedef void (* GtkAtSpiRootRegisterFunc) (GtkAtSpiRoot *root,
+ GtkAtSpiContext *context);
+
void
gtk_at_spi_root_queue_register (GtkAtSpiRoot *self,
- GtkAtSpiContext *context);
+ GtkAtSpiContext *context,
+ GtkAtSpiRootRegisterFunc func);
void
gtk_at_spi_root_unregister (GtkAtSpiRoot *self,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]