st/widget: Adapt to upstreamed accessible state tracking

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/3510>
This commit is contained in:
Bilal Elmoussaoui 2024-10-17 11:43:02 +02:00 committed by Sebastian Wick
parent 44b84e458a
commit 1471733dfd
2 changed files with 18 additions and 145 deletions

View File

@ -75,8 +75,6 @@ struct _StWidgetPrivate
gulong texture_file_changed_id;
guint update_child_styles_id;
AtkStateSet *local_state_set;
ClutterActor *label_actor;
StWidget *last_visible_child;
@ -322,7 +320,6 @@ st_widget_finalize (GObject *gobject)
g_free (priv->style_class);
g_free (priv->pseudo_class);
g_object_unref (priv->local_state_set);
g_free (priv->inline_style);
for (i = 0; i < G_N_ELEMENTS (priv->paint_states); i++)
@ -1607,7 +1604,6 @@ st_widget_init (StWidget *actor)
priv = st_widget_get_instance_private (actor);
priv->transition_animation = NULL;
priv->local_state_set = atk_state_set_new ();
/* connect style changed */
g_signal_connect (actor, "notify::name", G_CALLBACK (st_widget_name_notify), NULL);
@ -1893,7 +1889,6 @@ st_widget_set_can_focus (StWidget *widget,
gboolean can_focus)
{
StWidgetPrivate *priv;
AtkObject *accessible;
g_return_if_fail (ST_IS_WIDGET (widget));
@ -1902,13 +1897,14 @@ st_widget_set_can_focus (StWidget *widget,
if (priv->can_focus != can_focus)
{
priv->can_focus = can_focus;
accessible = clutter_actor_get_accessible (CLUTTER_ACTOR (widget));
g_object_notify_by_pspec (G_OBJECT (widget), props[PROP_CAN_FOCUS]);
if (accessible)
atk_object_notify_state_change (accessible,
ATK_STATE_FOCUSABLE,
priv->can_focus);
if (can_focus)
clutter_actor_add_accessible_state (CLUTTER_ACTOR (widget),
ATK_STATE_FOCUSABLE);
else
clutter_actor_remove_accessible_state (CLUTTER_ACTOR (widget),
ATK_STATE_FOCUSABLE);
}
}
@ -2386,73 +2382,6 @@ st_widget_set_label_actor (StWidget *widget,
}
}
static void
notify_accessible_state_change (StWidget *widget,
AtkStateType state,
gboolean value)
{
AtkObject *accessible =
clutter_actor_get_accessible (CLUTTER_ACTOR (widget));
if (accessible != NULL)
atk_object_notify_state_change (accessible, state, value);
}
/**
* st_widget_add_accessible_state:
* @widget: A #StWidget
* @state: #AtkStateType state to add
*
* This method adds @state as one of the accessible states for
* @widget. The list of states of a widget describes the current state
* of user interface element @widget and is provided so that assistive
* technologies know how to present @widget to the user.
*
* Usually you will have no need to add accessible states for an
* object, as the accessible object can extract most of the states
* from the object itself (ie: a #StButton knows when it is pressed).
* This method is only required when one cannot extract the
* information automatically from the object itself (i.e.: a generic
* container used as a toggle menu item will not automatically include
* the toggled state).
*
*/
void
st_widget_add_accessible_state (StWidget *widget,
AtkStateType state)
{
StWidgetPrivate *priv;
g_return_if_fail (ST_IS_WIDGET (widget));
priv = st_widget_get_instance_private (widget);
if (atk_state_set_add_state (priv->local_state_set, state))
notify_accessible_state_change (widget, state, TRUE);
}
/**
* st_widget_remove_accessible_state:
* @widget: A #StWidget
* @state: #AtkState state to remove
*
* This method removes @state as on of the accessible states for
* @widget. See st_widget_add_accessible_state() for more information.
*
*/
void
st_widget_remove_accessible_state (StWidget *widget,
AtkStateType state)
{
StWidgetPrivate *priv;
g_return_if_fail (ST_IS_WIDGET (widget));
priv = st_widget_get_instance_private (widget);
if (atk_state_set_remove_state (priv->local_state_set, state))
notify_accessible_state_change (widget, state, FALSE);
}
/******************************************************************************/
/*************************** ACCESSIBILITY SUPPORT ****************************/
@ -2463,7 +2392,6 @@ st_widget_remove_accessible_state (StWidget *widget,
static void st_widget_accessible_dispose (GObject *gobject);
/* AtkObject */
static AtkStateSet *st_widget_accessible_ref_state_set (AtkObject *obj);
static void st_widget_accessible_initialize (AtkObject *obj,
gpointer data);
@ -2489,7 +2417,6 @@ st_widget_accessible_class_init (StWidgetAccessibleClass *klass)
gobject_class->dispose = st_widget_accessible_dispose;
atk_class->ref_state_set = st_widget_accessible_ref_state_set;
atk_class->initialize = st_widget_accessible_initialize;
}
@ -2524,61 +2451,6 @@ st_widget_accessible_initialize (AtkObject *obj,
check_labels (ST_WIDGET (data));
}
static AtkStateSet *
st_widget_accessible_ref_state_set (AtkObject *obj)
{
AtkStateSet *result = NULL;
AtkStateSet *aux_set = NULL;
ClutterActor *actor = NULL;
StWidget *widget = NULL;
StWidgetPrivate *widget_priv;
StWidgetAccessible *self = NULL;
StWidgetAccessiblePrivate *priv;
result = ATK_OBJECT_CLASS (st_widget_accessible_parent_class)->ref_state_set (obj);
actor = CLUTTER_ACTOR (atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (obj)));
if (actor == NULL) /* State is defunct */
return result;
widget = ST_WIDGET (actor);
self = ST_WIDGET_ACCESSIBLE (obj);
priv = st_widget_accessible_get_instance_private (self);
widget_priv = st_widget_get_instance_private (widget);
/* priv->selected should be properly updated on the
* ATK_STATE_SELECTED notification callbacks
*/
if (priv->selected)
atk_state_set_add_state (result, ATK_STATE_SELECTED);
if (priv->checked)
atk_state_set_add_state (result, ATK_STATE_CHECKED);
/* On clutter there isn't any tip to know if a actor is focusable or
* not, anyone can receive the key_focus. For this reason
* cally_actor sets any actor as FOCUSABLE. This is not the case on
* St, where we have can_focus. But this means that we need to
* remove the state FOCUSABLE if it is not focusable
*/
if (st_widget_get_can_focus (widget))
atk_state_set_add_state (result, ATK_STATE_FOCUSABLE);
else
atk_state_set_remove_state (result, ATK_STATE_FOCUSABLE);
/* We add the states added externally if required */
if (!atk_state_set_is_empty (widget_priv->local_state_set))
{
aux_set = atk_state_set_or_sets (result, widget_priv->local_state_set);
g_object_unref (result); /* previous result will not be used */
result = aux_set;
}
return result;
}
/*
* In some cases the only way to check some states are checking the
* pseudo-class. Like if the object is selected (see bug 637830) or if
@ -2614,9 +2486,12 @@ check_pseudo_class (StWidget *widget)
if (found != priv->selected)
{
priv->selected = found;
atk_object_notify_state_change (accessible,
ATK_STATE_SELECTED,
found);
if (priv->selected)
clutter_actor_add_accessible_state (CLUTTER_ACTOR (widget),
ATK_STATE_SELECTED);
else
clutter_actor_remove_accessible_state (CLUTTER_ACTOR (widget),
ATK_STATE_SELECTED);
}
found = st_widget_has_style_pseudo_class (widget,
@ -2624,9 +2499,12 @@ check_pseudo_class (StWidget *widget)
if (found != priv->checked)
{
priv->checked = found;
atk_object_notify_state_change (accessible,
ATK_STATE_CHECKED,
found);
if (priv->checked)
clutter_actor_add_accessible_state (CLUTTER_ACTOR (widget),
ATK_STATE_CHECKED);
else
clutter_actor_remove_accessible_state (CLUTTER_ACTOR (widget),
ATK_STATE_CHECKED);
}
}

View File

@ -147,9 +147,4 @@ void st_widget_paint_background (StWidget *
/* debug methods */
char *st_describe_actor (ClutterActor *actor);
/* accessibility methods */
void st_widget_add_accessible_state (StWidget *widget,
AtkStateType state);
void st_widget_remove_accessible_state (StWidget *widget,
AtkStateType state);
G_END_DECLS