From 8301272b8e591cc8b1814d61ddd8e5fbb333a1bb Mon Sep 17 00:00:00 2001 From: Bilal Elmoussaoui Date: Fri, 2 Aug 2024 15:41:34 +0200 Subject: [PATCH] clutter/actor: Add a get_accessible_type vfunc Allows to avoid using the factories which simplifies the whole thing and allows external type to create their own accessible types. Copied from StWidget Part-of: --- clutter/clutter/cally/cally-actor.c | 24 ------ clutter/clutter/cally/cally-actor.h | 4 - clutter/clutter/cally/cally-clone.c | 29 +------ clutter/clutter/cally/cally-clone.h | 3 - clutter/clutter/cally/cally-factory.h | 108 -------------------------- clutter/clutter/cally/cally-stage.c | 25 ------ clutter/clutter/cally/cally-stage.h | 3 - clutter/clutter/cally/cally-text.c | 25 ------ clutter/clutter/cally/cally-text.h | 3 - clutter/clutter/cally/cally.c | 13 ---- clutter/clutter/cally/cally.h | 1 - clutter/clutter/clutter-actor.c | 76 +++++++++++++++++- clutter/clutter/clutter-actor.h | 7 +- clutter/clutter/clutter-clone.c | 4 +- clutter/clutter/clutter-stage.c | 2 + clutter/clutter/clutter-text.c | 2 + clutter/clutter/meson.build | 1 - 17 files changed, 88 insertions(+), 242 deletions(-) delete mode 100644 clutter/clutter/cally/cally-factory.h diff --git a/clutter/clutter/cally/cally-actor.c b/clutter/clutter/cally/cally-actor.c index 9b9d5221c..c11df1a53 100644 --- a/clutter/clutter/cally/cally-actor.c +++ b/clutter/clutter/cally/cally-actor.c @@ -122,30 +122,6 @@ G_DEFINE_TYPE_WITH_CODE (CallyActor, G_IMPLEMENT_INTERFACE (ATK_TYPE_COMPONENT, cally_actor_component_interface_init)); -/** - * cally_actor_new: - * @actor: a #ClutterActor - * - * Creates a new #CallyActor for the given @actor - * - * Return value: the newly created #AtkObject - */ -AtkObject * -cally_actor_new (ClutterActor *actor) -{ - gpointer object; - AtkObject *atk_object; - - g_return_val_if_fail (CLUTTER_IS_ACTOR (actor), NULL); - - object = g_object_new (CALLY_TYPE_ACTOR, NULL); - - atk_object = ATK_OBJECT (object); - atk_object_initialize (atk_object, actor); - - return atk_object; -} - static void cally_actor_initialize (AtkObject *obj, gpointer data) diff --git a/clutter/clutter/cally/cally-actor.h b/clutter/clutter/cally/cally-actor.h index 7fa75f7d3..dadb052a7 100644 --- a/clutter/clutter/cally/cally-actor.h +++ b/clutter/clutter/cally/cally-actor.h @@ -53,8 +53,4 @@ struct _CallyActorClass AtkGObjectAccessibleClass parent_class; }; -CLUTTER_EXPORT -AtkObject* cally_actor_new (ClutterActor *actor); - - G_END_DECLS diff --git a/clutter/clutter/cally/cally-clone.c b/clutter/clutter/cally/cally-clone.c index 382b99cb7..83ea2f1d8 100644 --- a/clutter/clutter/cally/cally-clone.c +++ b/clutter/clutter/cally/cally-clone.c @@ -20,7 +20,7 @@ /** * CallyClone: - * + * * Implementation of the ATK interfaces for a #ClutterClone * * #CallyClone implements the required ATK interfaces of [class@Clutter.Clone] @@ -53,7 +53,7 @@ * * Taking into account that: * - * - ClutterClone doesn't re-emit mirrored signals from the source + * - ClutterClone doesn't re-emit mirrored signals from the source * I think that likely the answer would be "yes, it is just a * mirrored image, not a real full clone". * @@ -92,31 +92,6 @@ cally_clone_init (CallyClone *clone) /* nothing to do yet */ } -/** - * cally_clone_new: - * @actor: a #ClutterActor - * - * Creates a new #CallyClone for the given @actor. @actor must be a - * [class@Clutter.Clone]. - * - * Return value: the newly created #AtkObject - */ -AtkObject* -cally_clone_new (ClutterActor *actor) -{ - GObject *object = NULL; - AtkObject *accessible = NULL; - - g_return_val_if_fail (CLUTTER_IS_CLONE (actor), NULL); - - object = g_object_new (CALLY_TYPE_CLONE, NULL); - - accessible = ATK_OBJECT (object); - atk_object_initialize (accessible, actor); - - return accessible; -} - static void cally_clone_real_initialize (AtkObject *obj, gpointer data) diff --git a/clutter/clutter/cally/cally-clone.h b/clutter/clutter/cally/cally-clone.h index 26c32fb13..15eb03dd2 100644 --- a/clutter/clutter/cally/cally-clone.h +++ b/clutter/clutter/cally/cally-clone.h @@ -47,7 +47,4 @@ struct _CallyCloneClass CallyActorClass parent_class; }; -CLUTTER_EXPORT -AtkObject *cally_clone_new (ClutterActor *actor); - G_END_DECLS diff --git a/clutter/clutter/cally/cally-factory.h b/clutter/clutter/cally/cally-factory.h deleted file mode 100644 index 2007bdb78..000000000 --- a/clutter/clutter/cally/cally-factory.h +++ /dev/null @@ -1,108 +0,0 @@ -/* CALLY - The Clutter Accessibility Implementation Library - * - * Copyright (C) 2008 Igalia, S.L. - * - * Author: Alejandro PiƱeiro Iglesias - * - * Based on gailfactory.h from GAIL - * Copyright 2001, 2002, 2003 Sun Microsystems Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see . - */ - -#pragma once - -#include -#include - -/** - * CALLY_ACCESSIBLE_FACTORY: - * @type: GType of the accessible which is created by the factory - * @type_as_function: prefix of the accessible object methods - * @opt_create_accessible: method to instantiate the accessibility object - * - * Defines a new #AtkObjectFactory factory to create accessible - * objects of a specific GType. It defines the factory GType and also - * overrides the proper #AtkObjectFactory methods. - * - * It assumes that the accessibility object provides a - * @opt_create_accessible method in order to create the accessibility - * object. It returns a @type GType object. - */ -#define CALLY_ACCESSIBLE_FACTORY(type, type_as_function, opt_create_accessible) \ - \ -static GType \ -type_as_function ## _factory_get_accessible_type (void) \ -{ \ - return type; \ -} \ - \ -static AtkObject* \ -type_as_function ## _factory_create_accessible (GObject *obj) \ -{ \ - ClutterActor *actor; \ - AtkObject *accessible; \ - \ - g_return_val_if_fail (CLUTTER_ACTOR (obj), NULL); \ - \ - actor = CLUTTER_ACTOR (obj); \ - \ - accessible = opt_create_accessible (actor); \ - \ - return accessible; \ -} \ - \ -static void \ -type_as_function ## _factory_class_init (AtkObjectFactoryClass *klass) \ -{ \ - klass->create_accessible = type_as_function ## _factory_create_accessible; \ - klass->get_accessible_type = type_as_function ## _factory_get_accessible_type;\ -} \ - \ -static GType \ -type_as_function ## _factory_get_type (void) \ -{ \ - static GType t = 0; \ - \ - if (!t) \ - { \ - char *name; \ - static const GTypeInfo tinfo = \ - { \ - sizeof (AtkObjectFactoryClass), \ - NULL, NULL, (GClassInitFunc) type_as_function ## _factory_class_init, \ - NULL, NULL, sizeof (AtkObjectFactory), 0, NULL, NULL \ - }; \ - \ - name = g_strconcat (g_type_name (type), "Factory", NULL); \ - t = g_type_register_static ( \ - ATK_TYPE_OBJECT_FACTORY, name, &tinfo, 0); \ - g_free (name); \ - } \ - \ - return t; \ -} - -/** - * CALLY_ACTOR_SET_FACTORY: - * @widget_type: GType of the clutter actor - * @type_as_function: prefix of the accessible object methods - * - * Sets the #AtkObjectFactory to be used in order to instantiate - * accessibility objects for the actor which GType is @widget_type. - */ -#define CALLY_ACTOR_SET_FACTORY(widget_type, type_as_function) \ - atk_registry_set_factory_type (atk_get_default_registry (), \ - widget_type, \ - type_as_function ## _factory_get_type ()) diff --git a/clutter/clutter/cally/cally-stage.c b/clutter/clutter/cally/cally-stage.c index f61b8fbff..d734451cf 100644 --- a/clutter/clutter/cally/cally-stage.c +++ b/clutter/clutter/cally/cally-stage.c @@ -66,31 +66,6 @@ cally_stage_init (CallyStage *cally_stage) { } -/** - * cally_stage_new: - * @actor: a #ClutterActor - * - * Creates a new #CallyStage for the given @actor. @actor should be a - * [class@Clutter.Stage]. - * - * Return value: the newly created #AtkObject - */ -AtkObject* -cally_stage_new (ClutterActor *actor) -{ - GObject *object = NULL; - AtkObject *accessible = NULL; - - g_return_val_if_fail (CLUTTER_IS_STAGE (actor), NULL); - - object = g_object_new (CALLY_TYPE_STAGE, NULL); - - accessible = ATK_OBJECT (object); - atk_object_initialize (accessible, actor); - - return accessible; -} - static void cally_stage_real_initialize (AtkObject *obj, gpointer data) diff --git a/clutter/clutter/cally/cally-stage.h b/clutter/clutter/cally/cally-stage.h index c45288289..cf3d9914e 100644 --- a/clutter/clutter/cally/cally-stage.h +++ b/clutter/clutter/cally/cally-stage.h @@ -47,7 +47,4 @@ struct _CallyStageClass CallyActorClass parent_class; }; -CLUTTER_EXPORT -AtkObject *cally_stage_new (ClutterActor *actor); - G_END_DECLS diff --git a/clutter/clutter/cally/cally-text.c b/clutter/clutter/cally/cally-text.c index 2fd73cf4f..de9e246e7 100644 --- a/clutter/clutter/cally/cally-text.c +++ b/clutter/clutter/cally/cally-text.c @@ -281,31 +281,6 @@ cally_text_finalize (GObject *obj) G_OBJECT_CLASS (cally_text_parent_class)->finalize (obj); } -/** - * cally_text_new: - * @actor: a #ClutterActor - * - * Creates a new #CallyText for the given @actor. @actor must be a - * [class@Clutter.Text]. - * - * Return value: the newly created #AtkObject - */ -AtkObject* -cally_text_new (ClutterActor *actor) -{ - GObject *object = NULL; - AtkObject *accessible = NULL; - - g_return_val_if_fail (CLUTTER_IS_TEXT (actor), NULL); - - object = g_object_new (CALLY_TYPE_TEXT, NULL); - - accessible = ATK_OBJECT (object); - atk_object_initialize (accessible, actor); - - return accessible; -} - /* atkobject.h */ static void diff --git a/clutter/clutter/cally/cally-text.h b/clutter/clutter/cally/cally-text.h index 47c108e04..eeceacfa2 100644 --- a/clutter/clutter/cally/cally-text.h +++ b/clutter/clutter/cally/cally-text.h @@ -47,7 +47,4 @@ struct _CallyTextClass CallyActorClass parent_class; }; -CLUTTER_EXPORT -AtkObject* cally_text_new (ClutterActor *actor); - G_END_DECLS diff --git a/clutter/clutter/cally/cally.c b/clutter/clutter/cally/cally.c index 4b6194988..86315fc73 100644 --- a/clutter/clutter/cally/cally.c +++ b/clutter/clutter/cally/cally.c @@ -26,7 +26,6 @@ #include "cally/cally-text.h" #include "cally/cally-clone.h" -#include "cally/cally-factory.h" #include "cally/cally-util.h" #include "clutter/clutter.h" @@ -34,12 +33,6 @@ #include "clutter/clutter-debug.h" #include "clutter/clutter-private.h" -/* factories initialization*/ -CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_ACTOR, cally_actor, cally_actor_new) -CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_STAGE, cally_stage, cally_stage_new) -CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_TEXT, cally_text, cally_text_new) -CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_CLONE, cally_clone, cally_clone_new) - /** * cally_accessibility_init: * @@ -51,12 +44,6 @@ CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_CLONE, cally_clone, cally_clone_new) gboolean cally_accessibility_init (void) { - /* setting the factories */ - CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_ACTOR, cally_actor); - CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_STAGE, cally_stage); - CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_TEXT, cally_text); - CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_CLONE, cally_clone); - /* Initialize the CallyUtility class */ _cally_util_override_atk_util (); diff --git a/clutter/clutter/cally/cally.h b/clutter/clutter/cally/cally.h index e12c966c9..4b95b5c38 100644 --- a/clutter/clutter/cally/cally.h +++ b/clutter/clutter/cally/cally.h @@ -24,7 +24,6 @@ #include "cally/cally-actor.h" #include "cally/cally-clone.h" -#include "cally/cally-factory.h" #include "cally/cally-main.h" #include "cally/cally-root.h" #include "cally/cally-stage.h" diff --git a/clutter/clutter/clutter-actor.c b/clutter/clutter/clutter-actor.c index dd18dcd40..01b561210 100644 --- a/clutter/clutter/clutter-actor.c +++ b/clutter/clutter/clutter-actor.c @@ -485,6 +485,7 @@ #include "cogl/cogl.h" +#include "cally/cally-actor.h" #include "clutter/clutter-actor-private.h" #include "clutter/clutter-action.h" @@ -5437,10 +5438,28 @@ clutter_actor_get_accessible (ClutterActor *self) static AtkObject * clutter_actor_real_get_accessible (ClutterActor *actor) { - if (actor->priv->accessible == NULL) - actor->priv->accessible = atk_gobject_accessible_for_object (G_OBJECT (actor)); + ClutterActorPrivate *priv = actor->priv; + if (priv->accessible == NULL) + { + priv->accessible = + g_object_new (CLUTTER_ACTOR_GET_CLASS (actor)->get_accessible_type (), + NULL); - return actor->priv->accessible; + atk_object_initialize (priv->accessible, actor); + /* AtkGObjectAccessible, which ClutterActorAccessible derives from, clears + * the back reference to the object in a weak notify for the object; + * weak-ref notification, which occurs during g_object_real_dispose(), + * is then the optimal time to clear the forward reference. We + * can't clear the reference in dispose() before chaining up, since + * clutter_actor_dispose() causes notifications to be sent out, which + * will result in a new accessible object being created. + */ + g_object_add_weak_pointer (G_OBJECT (actor), + (gpointer *)&priv->accessible); + + } + + return priv->accessible; } static AtkObject * @@ -5650,6 +5669,7 @@ clutter_actor_class_init (ClutterActorClass *klass) klass->queue_relayout = clutter_actor_real_queue_relayout; klass->apply_transform = clutter_actor_real_apply_transform; klass->get_accessible = clutter_actor_real_get_accessible; + klass->get_accessible_type = cally_actor_get_type; klass->get_paint_volume = clutter_actor_real_get_paint_volume; klass->has_overlaps = clutter_actor_real_has_overlaps; klass->calculate_resource_scale = clutter_actor_real_calculate_resource_scale; @@ -18415,6 +18435,56 @@ clutter_actor_has_accessible (ClutterActor *actor) return TRUE; } +/** + * clutter_actor_set_accessible: + * @self: A #ClutterActor + * @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. + * + * NULL is a valid value for @accessible. That contemplates the + * hypothetical case of not needing anymore a custom accessible object + * for the widget. Next call of [method@Clutter.Actor.get_accessible] would + * create and return a default accessible. + * + * It assumes that the call to atk_object_initialize that bound the + * gobject with the custom accessible object was already called, so + * not a responsibility of this method. + */ +void +clutter_actor_set_accessible (ClutterActor *self, + AtkObject *accessible) +{ + ClutterActorPrivate *priv; + + g_return_if_fail (CLUTTER_IS_ACTOR (self)); + g_return_if_fail (accessible == NULL || ATK_IS_GOBJECT_ACCESSIBLE (accessible)); + + priv = self->priv; + if (priv->accessible != accessible) + { + if (priv->accessible) + { + g_object_remove_weak_pointer (G_OBJECT (self), + (gpointer *)&priv->accessible); + g_object_unref (priv->accessible); + priv->accessible = NULL; + } + + if (accessible) + { + priv->accessible = g_object_ref (accessible); + /* See note in clutter_actor_get_accessible() */ + g_object_add_weak_pointer (G_OBJECT (self), + (gpointer *)&priv->accessible); + } + else + priv->accessible = NULL; + } +} + void clutter_actor_queue_immediate_relayout (ClutterActor *self) { diff --git a/clutter/clutter/clutter-actor.h b/clutter/clutter/clutter-actor.h index 35ae33c37..5e693e406 100644 --- a/clutter/clutter/clutter-actor.h +++ b/clutter/clutter/clutter-actor.h @@ -137,6 +137,8 @@ struct _ClutterActor * @queue_relayout: class handler for [signal@Clutter.Actor::queue-relayout] * @get_accessible: virtual function, returns the accessible object that * describes the actor to an assistive technology. + * @get_accessible_type: returns the type of the accessible object that + * describes the actor to an assistive technology. * @get_paint_volume: virtual function, for sub-classes to define their * #ClutterPaintVolume * @has_overlaps: virtual function for @@ -215,6 +217,7 @@ struct _ClutterActorClass /* accessibility support */ AtkObject * (* get_accessible) (ClutterActor *self); + GType (* get_accessible_type) (void); gboolean (* get_paint_volume) (ClutterActor *actor, ClutterPaintVolume *volume); @@ -309,7 +312,9 @@ CLUTTER_EXPORT AtkObject * clutter_actor_get_accessible (ClutterActor *self); CLUTTER_EXPORT gboolean clutter_actor_has_accessible (ClutterActor *self); - +CLUTTER_EXPORT +void clutter_actor_set_accessible (ClutterActor *self, + AtkObject *accessible); CLUTTER_EXPORT gboolean clutter_actor_is_visible (ClutterActor *self); CLUTTER_EXPORT diff --git a/clutter/clutter/clutter-clone.c b/clutter/clutter/clutter-clone.c index d230eef45..be409fca8 100644 --- a/clutter/clutter/clutter-clone.c +++ b/clutter/clutter/clutter-clone.c @@ -23,7 +23,7 @@ /** * ClutterClone: - * + * * An actor that displays a clone of a source actor * * #ClutterClone is a [class@Clutter.Actor] which draws with the paint @@ -37,6 +37,7 @@ #include "config.h" +#include "cally/cally-clone.h" #include "clutter/clutter-actor-private.h" #include "clutter/clutter-clone.h" #include "clutter/clutter-debug.h" @@ -342,6 +343,7 @@ clutter_clone_class_init (ClutterCloneClass *klass) ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass); actor_class->paint = clutter_clone_paint; + actor_class->get_accessible_type = cally_clone_get_type; actor_class->get_paint_volume = clutter_clone_get_paint_volume; actor_class->get_preferred_width = clutter_clone_get_preferred_width; actor_class->get_preferred_height = clutter_clone_get_preferred_height; diff --git a/clutter/clutter/clutter-stage.c b/clutter/clutter/clutter-stage.c index d75159f37..69acf8c96 100644 --- a/clutter/clutter/clutter-stage.c +++ b/clutter/clutter/clutter-stage.c @@ -41,6 +41,7 @@ #include "clutter/clutter-stage.h" +#include "cally/cally-stage.h" #include "clutter/clutter-action-private.h" #include "clutter/clutter-actor-private.h" #include "clutter/clutter-backend-private.h" @@ -1342,6 +1343,7 @@ clutter_stage_class_init (ClutterStageClass *klass) gobject_class->finalize = clutter_stage_finalize; actor_class->allocate = clutter_stage_allocate; + actor_class->get_accessible_type = cally_stage_get_type; actor_class->get_preferred_width = clutter_stage_get_preferred_width; actor_class->get_preferred_height = clutter_stage_get_preferred_height; actor_class->get_paint_volume = clutter_stage_get_paint_volume; diff --git a/clutter/clutter/clutter-text.c b/clutter/clutter/clutter-text.c index bd3c6e230..18311f108 100644 --- a/clutter/clutter/clutter-text.c +++ b/clutter/clutter/clutter-text.c @@ -46,6 +46,7 @@ #include "clutter/clutter-text.h" +#include "cally/cally-text.h" #include "clutter/clutter-actor-private.h" #include "clutter/clutter-animatable.h" #include "clutter/clutter-backend-private.h" @@ -3846,6 +3847,7 @@ clutter_text_class_init (ClutterTextClass *klass) gobject_class->finalize = clutter_text_finalize; actor_class->paint = clutter_text_paint; + actor_class->get_accessible_type = cally_text_get_type; actor_class->get_paint_volume = clutter_text_get_paint_volume; actor_class->get_preferred_width = clutter_text_get_preferred_width; actor_class->get_preferred_height = clutter_text_get_preferred_height; diff --git a/clutter/clutter/meson.build b/clutter/clutter/meson.build index 0875c6973..b1d87c75a 100644 --- a/clutter/clutter/meson.build +++ b/clutter/clutter/meson.build @@ -216,7 +216,6 @@ clutter_backend_private_headers = [] cally_headers = [ 'cally/cally-actor.h', 'cally/cally-clone.h', - 'cally/cally-factory.h', 'cally/cally.h', 'cally/cally-main.h', 'cally/cally-root.h',