From ed7619ec1667e0113bc454e1e09aa26c3f57be5e Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Tue, 10 Nov 2020 14:21:32 +0000 Subject: [PATCH] a11y: Clone GtkATContext in GtkModelButton The hypothetical widget that needs to clone ATContext instances because it needs to control the accessible role post-construction is really GtkModelButton. Fixes: #3342 --- gtk/gtkmodelbutton.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/gtk/gtkmodelbutton.c b/gtk/gtkmodelbutton.c index f5dc05286a..6bcf11eb9b 100644 --- a/gtk/gtkmodelbutton.c +++ b/gtk/gtkmodelbutton.c @@ -303,7 +303,8 @@ gtk_model_button_actionable_iface_init (GtkActionableInterface *iface) } static GtkATContext * -create_at_context (GtkModelButton *button) +create_at_context (GtkModelButton *button, + GtkATContext *old_context) { GdkDisplay *display = _gtk_widget_get_display (GTK_WIDGET (button)); GtkAccessibleRole role; @@ -323,6 +324,9 @@ create_at_context (GtkModelButton *button) break; } + if (old_context != NULL) + return gtk_at_context_clone (old_context, role, GTK_ACCESSIBLE (button), display); + return gtk_at_context_create (role, GTK_ACCESSIBLE (button), display); } @@ -332,7 +336,7 @@ gtk_model_button_get_at_context (GtkAccessible *accessible) GtkModelButton *button = GTK_MODEL_BUTTON (accessible); if (button->at_context == NULL) - button->at_context = create_at_context (button); + button->at_context = create_at_context (button, NULL); return button->at_context; } @@ -596,12 +600,18 @@ update_accessible_properties (GtkModelButton *button) else gtk_accessible_reset_state (GTK_ACCESSIBLE (button), GTK_ACCESSIBLE_STATE_CHECKED); + + gtk_accessible_update_relation (GTK_ACCESSIBLE (button), + GTK_ACCESSIBLE_RELATION_LABELLED_BY, button->label, NULL, + -1); } static void gtk_model_button_set_role (GtkModelButton *self, GtkButtonRole role) { + GtkATContext *old_context; + if (role == self->role) return; @@ -621,7 +631,10 @@ gtk_model_button_set_role (GtkModelButton *self, update_node_name (self); gtk_model_button_update_state (self); - g_set_object (&self->at_context, create_at_context (self)); + /* Replace the old context, if any, with a new context */ + old_context = g_steal_pointer (&self->at_context); + self->at_context = create_at_context (self, old_context); + g_clear_object (&old_context); update_accessible_properties (self);