1
0
Fork 0

clutter/actor: Move few accessible bits from StWidget

As they are better fit in ClutterActor
The accessible_role is intentionally put in the public fields
as ClutterActorAccessible needs access to that without going
in recursion

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3917>
This commit is contained in:
Bilal Elmoussaoui 2024-08-02 19:37:11 +02:00 committed by Marge Bot
parent f5c2b6949d
commit db05ef9c63
3 changed files with 225 additions and 6 deletions

View file

@ -27,7 +27,7 @@
*
* Implementation of the ATK interfaces for [class@Clutter.Actor]
*
* #ClutterAccessible implements the required ATK interfaces of [class@Clutter.Actor]
* #ClutterActorAccessible implements the required ATK interfaces of [class@Clutter.Actor]
* exposing the common elements on each actor (position, extents, etc).
*/
@ -57,7 +57,7 @@
* buttons. So in this environment, it doesn't make sense to keep
* adding them as default.
*
* Anyway, current implementation of AtkAction is done at ClutterAccessible
* Anyway, current implementation of AtkAction is done at ClutterActorAccessible
* providing methods to add and remove actions. This is based on the
* one used at gailcell, and proposed as a change on #AtkAction
* interface:
@ -70,6 +70,7 @@
#include <math.h>
#include <atk/atk.h>
#include <glib.h>
#include "clutter/clutter-actor-private.h"
@ -161,6 +162,45 @@ clutter_actor_accessible_initialize (AtkObject *obj,
interface would be a panel */
}
/* AtkObject */
static const gchar *
clutter_actor_accessible_get_name (AtkObject *obj)
{
const gchar* name = NULL;
ClutterActor *actor;
g_return_val_if_fail (CLUTTER_IS_ACTOR_ACCESSIBLE (obj), NULL);
actor = CLUTTER_ACTOR_FROM_ACCESSIBLE (obj);
if (actor)
name = clutter_actor_get_accessible_name (actor);
if (!name)
name = ATK_OBJECT_CLASS (clutter_actor_accessible_parent_class)->get_name (obj);
return name;
}
static AtkRole
clutter_actor_accessible_get_role (AtkObject *obj)
{
ClutterActor *actor = NULL;
AtkRole role = ATK_ROLE_INVALID;
g_return_val_if_fail (CLUTTER_IS_ACTOR_ACCESSIBLE (obj), role);
actor = CLUTTER_ACTOR_FROM_ACCESSIBLE (obj);
if (actor == NULL)
return role;
role = actor->accessible_role;
if (role == ATK_ROLE_INVALID)
role = ATK_OBJECT_CLASS (clutter_actor_accessible_parent_class)->get_role (obj);
return role;
}
static void
clutter_actor_accessible_class_init (ClutterActorAccessibleClass *klass)
{
@ -171,6 +211,8 @@ clutter_actor_accessible_class_init (ClutterActorAccessibleClass *klass)
gobject_class->finalize = clutter_actor_accessible_finalize;
/* AtkObject */
class->get_role = clutter_actor_accessible_get_role;
class->get_name = clutter_actor_accessible_get_name;
class->get_parent = clutter_actor_accessible_get_parent;
class->get_index_in_parent = clutter_actor_accessible_get_index_in_parent;
class->ref_state_set = clutter_actor_accessible_ref_state_set;
@ -204,8 +246,6 @@ clutter_actor_accessible_finalize (GObject *obj)
G_OBJECT_CLASS (clutter_actor_accessible_parent_class)->finalize (obj);
}
/* AtkObject */
static AtkObject *
clutter_actor_accessible_get_parent (AtkObject *obj)
{

View file

@ -515,6 +515,7 @@
#include "clutter/clutter-stage-view-private.h"
#include "clutter/clutter-timeline.h"
#include "clutter/clutter-transition.h"
#include "glib-object.h"
static const CoglColor transparent = { 0x00, 0x00, 0x00, 0x00 };
@ -547,6 +548,7 @@ struct _ClutterActorPrivate
/* Accessibility */
AtkObject *accessible;
gchar *accessible_name;
/* request mode */
ClutterRequestMode request_mode;
@ -853,6 +855,10 @@ enum
PROP_COLOR_STATE,
/* Accessible */
PROP_ACCESSIBLE_ROLE,
PROP_ACCESSIBLE_NAME,
PROP_LAST
};
@ -4843,6 +4849,14 @@ clutter_actor_set_property (GObject *object,
clutter_actor_set_color_state_internal (actor, g_value_get_object (value));
break;
case PROP_ACCESSIBLE_ROLE:
clutter_actor_set_accessible_role (actor, g_value_get_enum (value));
break;
case PROP_ACCESSIBLE_NAME:
clutter_actor_set_accessible_name (actor, g_value_get_string (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -5300,6 +5314,14 @@ clutter_actor_get_property (GObject *object,
g_value_set_object (value, priv->color_state);
break;
case PROP_ACCESSIBLE_ROLE:
g_value_set_enum (value, clutter_actor_get_accessible_role (actor));
break;
case PROP_ACCESSIBLE_NAME:
g_value_set_string (value, priv->accessible_name);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -5345,6 +5367,8 @@ clutter_actor_dispose (GObject *object)
g_clear_signal_handler (&priv->resolution_changed_id, backend);
g_clear_signal_handler (&priv->font_changed_id, backend);
g_clear_pointer (&priv->accessible_name, g_free);
g_clear_object (&priv->pango_context);
g_clear_object (&priv->actions);
g_clear_object (&priv->color_state);
@ -6843,6 +6867,27 @@ clutter_actor_class_init (ClutterActorClass *klass)
G_PARAM_STATIC_STRINGS |
G_PARAM_EXPLICIT_NOTIFY);
/**
* ClutterActor:accessible-role:
*
* The accessible role of this object
*/
obj_props[PROP_ACCESSIBLE_ROLE] =
g_param_spec_enum ("accessible-role", NULL, NULL,
ATK_TYPE_ROLE,
ATK_ROLE_INVALID,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_EXPLICIT_NOTIFY);
/**
* ClutterActor:accessible-name:
*
* Object instance's name for assistive technology access.
*/
obj_props[PROP_ACCESSIBLE_NAME] =
g_param_spec_string ("accessible-name", NULL, NULL,
NULL,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_EXPLICIT_NOTIFY);
g_object_class_install_properties (object_class, PROP_LAST, obj_props);
/**
@ -18440,8 +18485,7 @@ clutter_actor_has_accessible (ClutterActor *actor)
* @accessible: an accessible
*
* This method allows to set a customly created accessible object to
* this widget. For example if you define a new subclass of
* #StWidgetAccessible at the javascript code.
* this widget
*
* NULL is a valid value for @accessible. That contemplates the
* hypothetical case of not needing anymore a custom accessible object
@ -18687,3 +18731,127 @@ clutter_actor_class_get_layout_manager_type (ClutterActorClass *actor_class)
return actor_class->layout_manager_type;
}
/**
* clutter_actor_set_accessible_name:
* @self: widget to set the accessible name for
* @name: (nullable): a character string to be set as the accessible name
*
* This method sets @name as the accessible name for @self.
*
* Usually you will have no need to set the accessible name for an
* object, as usually there is a label for most of the interface
* elements.
*/
void
clutter_actor_set_accessible_name (ClutterActor *self,
const gchar *name)
{
ClutterActorPrivate *priv;
AtkObject *accessible;
g_return_if_fail (CLUTTER_IS_ACTOR (self));
priv = self->priv;
if (g_strcmp0 (name, priv->accessible_name) == 0)
return;
if (priv->accessible_name != NULL)
g_free (priv->accessible_name);
accessible = clutter_actor_get_accessible (self);
priv->accessible_name = g_strdup (name);
if (accessible)
g_object_notify (G_OBJECT (accessible), "accessible-name");
g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_ACCESSIBLE_NAME]);
}
/**
* clutter_actor_get_accessible_name:
* @self: widget to get the accessible name for
*
* Gets the accessible name for this widget. See
* clutter_actor_set_accessible_name() for more information.
*
* Returns: a character string representing the accessible name
* of the widget.
*/
const gchar *
clutter_actor_get_accessible_name (ClutterActor *actor)
{
g_return_val_if_fail (CLUTTER_IS_ACTOR (actor), NULL);
return actor->priv->accessible_name;
}
/**
* clutter_actor_set_accessible_role:
* @self: widget to set the accessible role for
* @role: The role to use
*
* This method sets @role as the accessible role for @self. This
* role describes what kind of user interface element @self is and
* is provided so that assistive technologies know how to present
* @self to the user.
*
* Usually you will have no need to set the accessible role for an
* object, as this information is extracted from the context of the
* object (ie: a #StButton has by default a push button role). This
* method is only required when you need to redefine the role
* currently associated with the widget, for instance if it is being
* used in an unusual way (ie: a #StButton used as a togglebutton), or
* if a generic object is used directly (ie: a container as a menu
* item).
*
* If @role is #ATK_ROLE_INVALID, the role will not be changed
* and the accessible's default role will be used instead.
*/
void
clutter_actor_set_accessible_role (ClutterActor *self,
AtkRole role)
{
AtkObject *accessible;
g_return_if_fail (CLUTTER_IS_ACTOR (self));
if (self->accessible_role == role)
return;
accessible = clutter_actor_get_accessible (self);
self->accessible_role = role;
if (accessible)
g_object_notify (G_OBJECT (accessible), "accessible-role");
g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_ACCESSIBLE_ROLE]);
}
/**
* clutter_actor_get_accessible_role:
* @self: widget to get the accessible role for
*
* Gets the #AtkRole for this widget. See
* clutter_actor_set_accessible_role() for more information.
*
* Returns: accessible #AtkRole for this widget
*/
AtkRole
clutter_actor_get_accessible_role (ClutterActor *self)
{
AtkRole role = ATK_ROLE_INVALID;
AtkObject *accessible;
g_return_val_if_fail (CLUTTER_IS_ACTOR (self), role);
accessible = clutter_actor_get_accessible (self);
if (self->accessible_role != ATK_ROLE_INVALID)
role = self->accessible_role;
else if (accessible != NULL)
role = atk_object_get_role (accessible);
return role;
}

View file

@ -64,6 +64,7 @@ struct _ClutterActor
/*< public >*/
guint32 flags;
AtkRole accessible_role;
/*< private >*/
guint32 private_flags;
@ -309,6 +310,16 @@ void clutter_actor_set_name
CLUTTER_EXPORT
const gchar * clutter_actor_get_name (ClutterActor *self);
CLUTTER_EXPORT
void clutter_actor_set_accessible_role (ClutterActor *self,
AtkRole role);
CLUTTER_EXPORT
AtkRole clutter_actor_get_accessible_role (ClutterActor *self);
CLUTTER_EXPORT
void clutter_actor_set_accessible_name (ClutterActor *self,
const gchar *name);
CLUTTER_EXPORT
const gchar * clutter_actor_get_accessible_name (ClutterActor *self);
CLUTTER_EXPORT
AtkObject * clutter_actor_get_accessible (ClutterActor *self);
CLUTTER_EXPORT
gboolean clutter_actor_has_accessible (ClutterActor *self);