From df8d28f5fead251b725cf4cfe7d6da7cc429eb21 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Mon, 19 Jun 2023 21:05:51 -0400 Subject: [PATCH] listitem: Add accessible-label and -description Add properties to GtkListItem to set the accessible label and description of the listitem widget. This is important, since orca will read these if the listitem widget ends up with the focus. --- gtk/gtklistitem.c | 136 +++++++++++++++++++++++++++++++++++++++ gtk/gtklistitem.h | 12 ++++ gtk/gtklistitemprivate.h | 3 + gtk/gtklistitemwidget.c | 5 ++ 4 files changed, 156 insertions(+) diff --git a/gtk/gtklistitem.c b/gtk/gtklistitem.c index 267b9ea6c5..a06a43a28d 100644 --- a/gtk/gtklistitem.c +++ b/gtk/gtklistitem.c @@ -22,6 +22,7 @@ #include "gtklistitemprivate.h" #include "gtkcolumnviewcell.h" +#include "gtkaccessible.h" /** * GtkListItem: @@ -45,6 +46,8 @@ enum { PROP_0, + PROP_ACCESSIBLE_DESCRIPTION, + PROP_ACCESSIBLE_LABEL, PROP_ACTIVATABLE, PROP_CHILD, PROP_FOCUSABLE, @@ -68,6 +71,9 @@ gtk_list_item_dispose (GObject *object) g_assert (self->owner == NULL); /* would hold a reference */ g_clear_object (&self->child); + g_clear_pointer (&self->accessible_description, g_free); + g_clear_pointer (&self->accessible_label, g_free); + G_OBJECT_CLASS (gtk_list_item_parent_class)->dispose (object); } @@ -81,6 +87,14 @@ gtk_list_item_get_property (GObject *object, switch (property_id) { + case PROP_ACCESSIBLE_DESCRIPTION: + g_value_set_string (value, self->accessible_description); + break; + + case PROP_ACCESSIBLE_LABEL: + g_value_set_string (value, self->accessible_label); + break; + case PROP_ACTIVATABLE: g_value_set_boolean (value, self->activatable); break; @@ -132,6 +146,14 @@ gtk_list_item_set_property (GObject *object, switch (property_id) { + case PROP_ACCESSIBLE_DESCRIPTION: + gtk_list_item_set_accessible_description (self, g_value_get_string (value)); + break; + + case PROP_ACCESSIBLE_LABEL: + gtk_list_item_set_accessible_label (self, g_value_get_string (value)); + break; + case PROP_ACTIVATABLE: gtk_list_item_set_activatable (self, g_value_get_boolean (value)); break; @@ -163,6 +185,30 @@ gtk_list_item_class_init (GtkListItemClass *klass) gobject_class->get_property = gtk_list_item_get_property; gobject_class->set_property = gtk_list_item_set_property; + /** + * GtkListItem:accessible-description: (attributes org.gtk.Property.get=gtk_list_item_get_accessible_description org.gtk.Property.set=gtk_list_item_set_accessible_description) + * + * The accessible description to set on the list item. + * + * Since: 4.12 + */ + properties[PROP_ACCESSIBLE_DESCRIPTION] = + g_param_spec_string ("accessible-description", NULL, NULL, + NULL, + G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); + + /** + * GtkListItem:accessible-label: (attributes org.gtk.Property.get=gtk_list_item_get_accessible_label org.gtk.Property.set=gtk_list_item_set_accessible_label) + * + * The accessible label to set on the list item. + * + * Since: 4.12 + */ + properties[PROP_ACCESSIBLE_LABEL] = + g_param_spec_string ("accessible-label", NULL, NULL, + NULL, + G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); + /** * GtkListItem:activatable: (attributes org.gtk.Property.get=gtk_list_item_get_activatable org.gtk.Property.set=gtk_list_item_set_activatable) * @@ -562,3 +608,93 @@ gtk_list_item_set_focusable (GtkListItem *self, g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_FOCUSABLE]); } + +/** + * gtk_list_item_set_accessible_description: + * @self: a `GtkListItem` + * @description: the description + * + * Sets the accessible description for the list item, + * which may be used by e.g. screen readers. + * + * Since: 4.12 + */ +void +gtk_list_item_set_accessible_description (GtkListItem *self, + const char *description) +{ + g_return_if_fail (GTK_IS_LIST_ITEM (self)); + + if (!g_set_str (&self->accessible_description, description)) + return; + + if (self->owner) + gtk_accessible_update_property (GTK_ACCESSIBLE (self->owner), + GTK_ACCESSIBLE_PROPERTY_DESCRIPTION, self->accessible_description, + -1); + + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ACCESSIBLE_DESCRIPTION]); +} + +/** + * gtk_list_item_get_accessible_description: + * @self: a `GtkListItem` + * + * Gets the accessible description of @self. + * + * Returns: the accessible description + * + * Since: 4.12 + */ +const char * +gtk_list_item_get_accessible_description (GtkListItem *self) +{ + g_return_val_if_fail (GTK_IS_LIST_ITEM (self), NULL); + + return self->accessible_description; +} + +/** + * gtk_list_item_set_accessible_label: + * @self: a `GtkListItem` + * @label: the label + * + * Sets the accessible label for the list item, + * which may be used by e.g. screen readers. + * + * Since: 4.12 + */ +void +gtk_list_item_set_accessible_label (GtkListItem *self, + const char *label) +{ + g_return_if_fail (GTK_IS_LIST_ITEM (self)); + + if (!g_set_str (&self->accessible_label, label)) + return; + + if (self->owner) + gtk_accessible_update_property (GTK_ACCESSIBLE (self->owner), + GTK_ACCESSIBLE_PROPERTY_LABEL, self->accessible_label, + -1); + + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ACCESSIBLE_LABEL]); +} + +/** + * gtk_list_item_get_accessible_label: + * @self: a `GtkListItem` + * + * Gets the accessible label of @self. + * + * Returns: the accessible label + * + * Since: 4.12 + */ +const char * +gtk_list_item_get_accessible_label (GtkListItem *self) +{ + g_return_val_if_fail (GTK_IS_LIST_ITEM (self), NULL); + + return self->accessible_label; +} diff --git a/gtk/gtklistitem.h b/gtk/gtklistitem.h index 9c5fb844e1..5ce8d8e5d1 100644 --- a/gtk/gtklistitem.h +++ b/gtk/gtklistitem.h @@ -59,5 +59,17 @@ void gtk_list_item_set_child (GtkListItem GDK_AVAILABLE_IN_ALL GtkWidget * gtk_list_item_get_child (GtkListItem *self); +GDK_AVAILABLE_IN_4_12 +void gtk_list_item_set_accessible_description (GtkListItem *self, + const char *description); +GDK_AVAILABLE_IN_4_12 +const char * gtk_list_item_get_accessible_description (GtkListItem *self); + +GDK_AVAILABLE_IN_4_12 +void gtk_list_item_set_accessible_label (GtkListItem *self, + const char *label); +GDK_AVAILABLE_IN_4_12 +const char * gtk_list_item_get_accessible_label (GtkListItem *self); + G_END_DECLS diff --git a/gtk/gtklistitemprivate.h b/gtk/gtklistitemprivate.h index 60e122bc10..91900472aa 100644 --- a/gtk/gtklistitemprivate.h +++ b/gtk/gtklistitemprivate.h @@ -35,6 +35,9 @@ struct _GtkListItem GtkWidget *child; + char *accessible_label; + char *accessible_description; + guint activatable : 1; guint selectable : 1; guint focusable : 1; diff --git a/gtk/gtklistitemwidget.c b/gtk/gtklistitemwidget.c index b5fac6f7b8..8c92de5e79 100644 --- a/gtk/gtklistitemwidget.c +++ b/gtk/gtklistitemwidget.c @@ -120,6 +120,11 @@ gtk_list_item_widget_setup_object (GtkListFactoryWidget *fw, gtk_list_factory_widget_set_selectable (fw, list_item->selectable); gtk_widget_set_focusable (GTK_WIDGET (self), list_item->focusable); + gtk_accessible_update_property (GTK_ACCESSIBLE (self), + GTK_ACCESSIBLE_PROPERTY_LABEL, list_item->accessible_label, + GTK_ACCESSIBLE_PROPERTY_DESCRIPTION, list_item->accessible_description, + -1); + gtk_list_item_do_notify (list_item, gtk_list_item_base_get_item (GTK_LIST_ITEM_BASE (self)) != NULL, gtk_list_item_base_get_position (GTK_LIST_ITEM_BASE (self)) != GTK_INVALID_LIST_POSITION, -- 2.30.2