From 9b1a76fbae3e26f5215ed10df04b87b20dbbfc8b Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Fri, 23 Aug 2019 18:30:42 +0200 Subject: atkplug: Add atk_plug_set_child As discussed on https://mail.gnome.org/archives/gnome-accessibility-devel/2019-August/msg00001.html In some cases, one can not use the AtkPlug type directly as accessible object for the toplevel widget of the application. For instance in the gtk case, GtkPlugAccessible can not inherit both from GtkWindowAccessible and from AtkPlug. In such a case, one can create, in addition to the standard accessible object for the toplevel widget, an AtkPlug object, and make the former the child of the latter by calling atk_plug_set_child(). --- atk/atkplug.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++- atk/atkplug.h | 6 ++-- atk/atkversion.h.in | 14 +++++++++ 3 files changed, 108 insertions(+), 3 deletions(-) (limited to 'atk') diff --git a/atk/atkplug.c b/atk/atkplug.c index ceb3e5d..ddd86ed 100644 --- a/atk/atkplug.c +++ b/atk/atkplug.c @@ -34,8 +34,57 @@ static void atk_component_interface_init (AtkComponentIface *iface); +typedef struct { + AtkObject *child; +} AtkPlugPrivate; + +static gint AtkPlug_private_offset; + G_DEFINE_TYPE_WITH_CODE (AtkPlug, atk_plug, ATK_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE (ATK_TYPE_COMPONENT, atk_component_interface_init)) + G_IMPLEMENT_INTERFACE (ATK_TYPE_COMPONENT, atk_component_interface_init) + G_ADD_PRIVATE(AtkPlug)) + +static AtkObject* +atk_plug_ref_child (AtkObject *obj, int i) +{ + AtkPlugPrivate *private = atk_plug_get_instance_private (ATK_PLUG (obj)); + AtkObject *child; + + if (i != 0) + return NULL; + + child = private->child; + + if (child == NULL) + return NULL; + + return g_object_ref (child); +} + +static int +atk_plug_get_n_children (AtkObject *obj) +{ + AtkPlugPrivate *private = atk_plug_get_instance_private (ATK_PLUG (obj)); + + if (private->child == NULL) + return 0; + + return 1; +} + +static AtkStateSet* +atk_plug_ref_state_set (AtkObject *obj) +{ + AtkPlugPrivate *private = atk_plug_get_instance_private (ATK_PLUG (obj)); + AtkObject *child; + + child = private->child; + + if (child == NULL) + return NULL; + + return atk_object_ref_state_set (child); +} static void atk_plug_init (AtkPlug* obj) @@ -49,7 +98,16 @@ atk_plug_init (AtkPlug* obj) static void atk_plug_class_init (AtkPlugClass* klass) { + AtkObjectClass *class = ATK_OBJECT_CLASS (klass); + + if (AtkPlug_private_offset != 0) + g_type_class_adjust_private_offset (klass, &AtkPlug_private_offset); + klass->get_object_id = NULL; + + class->get_n_children = atk_plug_get_n_children; + class->ref_child = atk_plug_ref_child; + class->ref_state_set = atk_plug_ref_state_set; } static void @@ -72,6 +130,37 @@ atk_plug_new (void) return g_object_new (ATK_TYPE_PLUG, NULL); } +/** + * atk_plug_set_child: + * @plug: an #AtkPlug to be set as accessible parent of @child. + * @child: an #AtkObject to be set as accessible child of @plug. + * + * Sets @child as accessible child of @plug and @plug as accessible parent of + * @child. @child can be NULL. + * + * In some cases, one can not use the AtkPlug type directly as accessible + * object for the toplevel widget of the application. For instance in the gtk + * case, GtkPlugAccessible can not inherit both from GtkWindowAccessible and + * from AtkPlug. In such a case, one can create, in addition to the standard + * accessible object for the toplevel widget, an AtkPlug object, and make the + * former the child of the latter by calling atk_plug_set_child(). + * + * Since: 2.35.0 + */ +void +atk_plug_set_child (AtkPlug *plug, AtkObject *child) +{ + AtkPlugPrivate *private = atk_plug_get_instance_private (plug); + + if (private->child) + atk_object_set_parent (private->child, NULL); + + private->child = child; + + if (child) + atk_object_set_parent (child, ATK_OBJECT(plug)); +} + /** * atk_plug_get_id: * @plug: an #AtkPlug diff --git a/atk/atkplug.h b/atk/atkplug.h index b1d83ff..ec5bc59 100644 --- a/atk/atkplug.h +++ b/atk/atkplug.h @@ -57,9 +57,11 @@ struct _AtkPlugClass }; ATK_AVAILABLE_IN_ALL -AtkObject* atk_plug_new (void); +AtkObject* atk_plug_new (void); +ATK_AVAILABLE_IN_2_36 +void atk_plug_set_child (AtkPlug *plug, AtkObject *child); ATK_AVAILABLE_IN_ALL -gchar* atk_plug_get_id (AtkPlug* plug); +gchar* atk_plug_get_id (AtkPlug* plug); G_END_DECLS diff --git a/atk/atkversion.h.in b/atk/atkversion.h.in index 36946db..78dc6e2 100644 --- a/atk/atkversion.h.in +++ b/atk/atkversion.h.in @@ -400,6 +400,20 @@ # define ATK_AVAILABLE_IN_2_30 _ATK_EXTERN #endif +#if ATK_VERSION_MIN_REQUIRED >= ATK_VERSION_2_36 +# define ATK_DEPRECATED_IN_2_36 ATK_DEPRECATED +# define ATK_DEPRECATED_IN_2_36_FOR(f) ATK_DEPRECATED_FOR(f) +#else +# define ATK_DEPRECATED_IN_2_36 _ATK_EXTERN +# define ATK_DEPRECATED_IN_2_36_FOR(f) _ATK_EXTERN +#endif + +#if ATK_VERSION_MAX_ALLOWED < ATK_VERSION_2_36 +# define ATK_AVAILABLE_IN_2_36 ATK_UNAVAILABLE(2, 36) +#else +# define ATK_AVAILABLE_IN_2_36 _ATK_EXTERN +#endif + ATK_AVAILABLE_IN_2_8 guint atk_get_major_version (void) G_GNUC_CONST; ATK_AVAILABLE_IN_2_8 -- cgit v1.2.1