summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmmanuele Bassi <ebassi@gmail.com>2021-01-21 18:57:34 +0000
committerEmmanuele Bassi <ebassi@gmail.com>2021-01-21 18:57:34 +0000
commitc46391420fdec46c63219138f124c9354e942092 (patch)
treeeba757850ead7fac31ef6d27be70d0a920d88136
parent68df7527f72ebbb1ed09ca6f0582373b960aec41 (diff)
parent95ceb4977055a3659369551364088340321c1224 (diff)
downloadgtk+-c46391420fdec46c63219138f124c9354e942092.tar.gz
Merge branch 'ebassi/lazier-a11y' into 'master'
Lazier accessibility See merge request GNOME/gtk!3102
-rw-r--r--gtk/a11y/gtkatspicache.c16
-rw-r--r--gtk/gtkwidget.c26
-rw-r--r--gtk/gtkwidgetprivate.h3
-rw-r--r--gtk/gtkwindow.c4
4 files changed, 35 insertions, 14 deletions
diff --git a/gtk/a11y/gtkatspicache.c b/gtk/a11y/gtkatspicache.c
index 10736341e5..e1c7b5d628 100644
--- a/gtk/a11y/gtkatspicache.c
+++ b/gtk/a11y/gtkatspicache.c
@@ -58,6 +58,9 @@ struct _GtkAtSpiCache
/* HashTable<GtkAtSpiContext, str> */
GHashTable *contexts_to_path;
+
+ /* Re-entrancy guard */
+ gboolean in_get_items;
};
enum
@@ -250,10 +253,17 @@ handle_cache_method (GDBusConnection *connection,
{
GVariantBuilder builder = G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE ("(" GET_ITEMS_SIGNATURE ")"));
+ /* Prevent the emission os signals while collecting accessible
+ * objects as the result of walking the accessible tree
+ */
+ self->in_get_items = TRUE;
+
g_variant_builder_open (&builder, G_VARIANT_TYPE (GET_ITEMS_SIGNATURE));
collect_cached_objects (self, &builder);
g_variant_builder_close (&builder);
+ self->in_get_items = FALSE;
+
g_dbus_method_invocation_return_value (invocation, g_variant_builder_end (&builder));
}
}
@@ -371,7 +381,11 @@ gtk_at_spi_cache_add_context (GtkAtSpiCache *self,
GTK_NOTE (A11Y, g_message ("Adding context '%s' to cache", path_key));
- emit_add_accessible (self, context);
+ /* GetItems is safe from re-entrancy, but we still don't want to
+ * emit an unnecessary signal while we're collecting ATContexts
+ */
+ if (!self->in_get_items)
+ emit_add_accessible (self, context);
}
void
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index 5ac8b9ac84..217293cd23 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -2374,7 +2374,7 @@ gtk_widget_init (GTypeInstance *instance, gpointer g_class)
priv->at_context = gtk_accessible_get_at_context (GTK_ACCESSIBLE (widget));
}
-static void
+void
gtk_widget_realize_at_context (GtkWidget *self)
{
GtkWidgetPrivate *priv = gtk_widget_get_instance_private (self);
@@ -2383,10 +2383,6 @@ gtk_widget_realize_at_context (GtkWidget *self)
if (priv->at_context == NULL || gtk_at_context_is_realized (priv->at_context))
return;
- /* Realize the root ATContext first */
- if (!GTK_IS_ROOT (self))
- gtk_widget_realize_at_context (GTK_WIDGET (priv->root));
-
/* Reset the accessible role to its current value */
if (role == GTK_ACCESSIBLE_ROLE_WIDGET)
{
@@ -2401,6 +2397,18 @@ gtk_widget_realize_at_context (GtkWidget *self)
}
void
+gtk_widget_unrealize_at_context (GtkWidget *widget)
+{
+ GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
+
+ if (priv->at_context != NULL)
+ {
+ gtk_at_context_set_display (priv->at_context, gdk_display_get_default ());
+ gtk_at_context_unrealize (priv->at_context);
+ }
+}
+
+void
gtk_widget_root (GtkWidget *widget)
{
GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
@@ -2428,8 +2436,6 @@ gtk_widget_root (GtkWidget *widget)
if (priv->layout_manager)
gtk_layout_manager_set_root (priv->layout_manager, priv->root);
- gtk_widget_realize_at_context (widget);
-
GTK_WIDGET_GET_CLASS (widget)->root (widget);
if (!GTK_IS_ROOT (widget))
@@ -2454,12 +2460,6 @@ gtk_widget_unroot (GtkWidget *widget)
GTK_WIDGET_GET_CLASS (widget)->unroot (widget);
- if (priv->at_context != NULL)
- {
- gtk_at_context_set_display (priv->at_context, gdk_display_get_default ());
- gtk_at_context_unrealize (priv->at_context);
- }
-
if (priv->context)
gtk_style_context_set_display (priv->context, gdk_display_get_default ());
diff --git a/gtk/gtkwidgetprivate.h b/gtk/gtkwidgetprivate.h
index eb6959fe7c..9848d4038f 100644
--- a/gtk/gtkwidgetprivate.h
+++ b/gtk/gtkwidgetprivate.h
@@ -373,6 +373,9 @@ gboolean gtk_widget_focus_self (GtkWidget *widget,
void gtk_widget_update_orientation (GtkWidget *widget,
GtkOrientation orientation);
+void gtk_widget_realize_at_context (GtkWidget *widget);
+void gtk_widget_unrealize_at_context (GtkWidget *widget);
+
/* inline getters */
static inline GtkWidget *
diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c
index d704f497b1..06835dc99c 100644
--- a/gtk/gtkwindow.c
+++ b/gtk/gtkwindow.c
@@ -3806,6 +3806,8 @@ gtk_window_map (GtkWidget *widget)
if (priv->application)
gtk_application_handle_window_map (priv->application, window);
+
+ gtk_widget_realize_at_context (widget);
}
static void
@@ -3818,6 +3820,8 @@ gtk_window_unmap (GtkWidget *widget)
GTK_WIDGET_CLASS (gtk_window_parent_class)->unmap (widget);
gdk_surface_hide (priv->surface);
+ gtk_widget_unrealize_at_context (widget);
+
if (priv->title_box != NULL)
gtk_widget_unmap (priv->title_box);