a11y: Do not notify of empty state changes

If the ATContext state hasn't changed—for instance, if the accessible
attributes have been set to their default value, or have been set to the
same value—do not emit an accessible state change. State changes can be
arbitrarily expensive, so we want to ensure that they are meaningful.
This commit is contained in:
Emmanuele Bassi 2020-08-05 18:05:46 +01:00
parent 32a1cd13c8
commit 797b3bd1b1
2 changed files with 35 additions and 6 deletions

View File

@ -425,6 +425,12 @@ gtk_at_context_update (GtkATContext *self)
{
g_return_if_fail (GTK_IS_AT_CONTEXT (self));
/* There's no point in notifying of state changes if there weren't any */
if (self->updated_properties == 0 &&
self->updated_relations == 0 &&
self->updated_states == 0)
return;
GtkAccessibleStateChange changed_states =
gtk_accessible_attribute_set_get_changed (self->states);
GtkAccessiblePropertyChange changed_properties =
@ -435,6 +441,10 @@ gtk_at_context_update (GtkATContext *self)
g_signal_emit (self, obj_signals[STATE_CHANGE], 0,
changed_states, changed_properties, changed_relations,
self->states, self->properties, self->relations);
self->updated_properties = 0;
self->updated_relations = 0;
self->updated_states = 0;
}
/*< private >
@ -457,10 +467,15 @@ gtk_at_context_set_accessible_state (GtkATContext *self,
{
g_return_if_fail (GTK_IS_AT_CONTEXT (self));
gboolean res = FALSE;
if (value != NULL)
gtk_accessible_attribute_set_add (self->states, state, value);
res = gtk_accessible_attribute_set_add (self->states, state, value);
else
gtk_accessible_attribute_set_remove (self->states, state);
res = gtk_accessible_attribute_set_remove (self->states, state);
if (res)
self->updated_states |= (1 << state);
}
/*< private >
@ -519,10 +534,15 @@ gtk_at_context_set_accessible_property (GtkATContext *self,
{
g_return_if_fail (GTK_IS_AT_CONTEXT (self));
gboolean res = FALSE;
if (value != NULL)
gtk_accessible_attribute_set_add (self->properties, property, value);
res = gtk_accessible_attribute_set_add (self->properties, property, value);
else
gtk_accessible_attribute_set_remove (self->properties, property);
res = gtk_accessible_attribute_set_remove (self->properties, property);
if (res)
self->updated_properties |= (1 << property);
}
/*< private >
@ -581,10 +601,15 @@ gtk_at_context_set_accessible_relation (GtkATContext *self,
{
g_return_if_fail (GTK_IS_AT_CONTEXT (self));
gboolean res = FALSE;
if (value != NULL)
gtk_accessible_attribute_set_add (self->relations, relation, value);
res = gtk_accessible_attribute_set_add (self->relations, relation, value);
else
gtk_accessible_attribute_set_remove (self->relations, relation);
res = gtk_accessible_attribute_set_remove (self->relations, relation);
if (res)
self->updated_relations |= (1 << relation);
}
/*< private >

View File

@ -90,6 +90,10 @@ struct _GtkATContext
GtkAccessibleAttributeSet *states;
GtkAccessibleAttributeSet *properties;
GtkAccessibleAttributeSet *relations;
GtkAccessibleStateChange updated_states;
GtkAccessiblePropertyChange updated_properties;
GtkAccessibleRelationChange updated_relations;
};
struct _GtkATContextClass