diff options
author | Emmanuele Bassi <ebassi@gnome.org> | 2020-07-13 15:20:19 +0100 |
---|---|---|
committer | Emmanuele Bassi <ebassi@gnome.org> | 2020-07-26 20:31:15 +0100 |
commit | 572861be27e54a5a56257fdef6a4824a766e3cc0 (patch) | |
tree | 0d0c3a24e295eae94186e10669a5ca8a7f439335 | |
parent | 5a173df3da13c383179c3c193496b87d8019b061 (diff) | |
download | gtk+-572861be27e54a5a56257fdef6a4824a766e3cc0.tar.gz |
Allow setting the accessible role at construction
Some widgets have different accessible roles depending on some
parameter, so we cannot set the role at class init time. For those
widgets, we add an "accessible-role" property to GtkAccessible, and we
allow setting it (only) at construction time.
-rw-r--r-- | gtk/gtkaccessible.c | 40 | ||||
-rw-r--r-- | gtk/gtkaccessible.h | 15 | ||||
-rw-r--r-- | gtk/gtkwidget.c | 64 | ||||
-rw-r--r-- | gtk/gtkwidget.h | 2 | ||||
-rw-r--r-- | gtk/gtkwidgetprivate.h | 3 |
5 files changed, 114 insertions, 10 deletions
diff --git a/gtk/gtkaccessible.c b/gtk/gtkaccessible.c index c6e576c329..47bebc7543 100644 --- a/gtk/gtkaccessible.c +++ b/gtk/gtkaccessible.c @@ -46,6 +46,7 @@ #include "gtkatcontextprivate.h" #include "gtkenums.h" +#include "gtktypebuiltins.h" #include <stdarg.h> @@ -54,8 +55,27 @@ G_DEFINE_INTERFACE (GtkAccessible, gtk_accessible, G_TYPE_OBJECT) static void gtk_accessible_default_init (GtkAccessibleInterface *iface) { + GParamSpec *pspec = + g_param_spec_enum ("accessible-role", + "Accessible Role", + "The role of the accessible object", + GTK_TYPE_ACCESSIBLE_ROLE, + GTK_ACCESSIBLE_ROLE_WIDGET, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + + g_object_interface_install_property (iface, pspec); } +/*< private > + * gtk_accessible_get_at_context: + * @self: a #GtkAccessible + * + * Retrieves the #GtkATContext for the given #GtkAccessible. + * + * Returns: (transfer none): the #GtkATContext + */ GtkATContext * gtk_accessible_get_at_context (GtkAccessible *self) { @@ -65,6 +85,26 @@ gtk_accessible_get_at_context (GtkAccessible *self) } /** + * gtk_accessible_get_accessible_role: + * @self: a #GtkAccessible + * + * Retrieves the #GtkAccessibleRole for the given #GtkAccessible. + * + * Returns: a #GtkAccessibleRole + */ +GtkAccessibleRole +gtk_accessible_get_accessible_role (GtkAccessible *self) +{ + g_return_val_if_fail (GTK_IS_ACCESSIBLE (self), GTK_ACCESSIBLE_ROLE_WIDGET); + + GtkATContext *context = gtk_accessible_get_at_context (self); + if (context == NULL) + return GTK_ACCESSIBLE_ROLE_WIDGET; + + return gtk_at_context_get_accessible_role (context); +} + +/** * gtk_accessible_update_state: * @self: a #GtkAccessible * @first_state: the first #GtkAccessibleState diff --git a/gtk/gtkaccessible.h b/gtk/gtkaccessible.h index 9fe16616e5..5b943f89a2 100644 --- a/gtk/gtkaccessible.h +++ b/gtk/gtkaccessible.h @@ -32,12 +32,15 @@ GDK_AVAILABLE_IN_ALL G_DECLARE_INTERFACE (GtkAccessible, gtk_accessible, GTK, ACCESSIBLE, GObject) GDK_AVAILABLE_IN_ALL -void gtk_accessible_update_state (GtkAccessible *self, - GtkAccessibleState first_state, - ...); +GtkAccessibleRole gtk_accessible_get_accessible_role (GtkAccessible *self); + +GDK_AVAILABLE_IN_ALL +void gtk_accessible_update_state (GtkAccessible *self, + GtkAccessibleState first_state, + ...); GDK_AVAILABLE_IN_ALL -void gtk_accessible_update_state_value (GtkAccessible *self, - GtkAccessibleState state, - const GValue *value); +void gtk_accessible_update_state_value (GtkAccessible *self, + GtkAccessibleState state, + const GValue *value); G_END_DECLS diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c index 08ad5bdbce..49121957e5 100644 --- a/gtk/gtkwidget.c +++ b/gtk/gtkwidget.c @@ -512,7 +512,10 @@ enum { PROP_CSS_NAME, PROP_CSS_CLASSES, PROP_LAYOUT_MANAGER, - NUM_PROPERTIES + NUM_PROPERTIES, + + /* GtkAccessible */ + PROP_ACCESSIBLE_ROLE }; static GParamSpec *widget_props[NUM_PROPERTIES] = { NULL, }; @@ -1335,6 +1338,8 @@ gtk_widget_class_init (GtkWidgetClass *klass) g_object_class_install_properties (gobject_class, NUM_PROPERTIES, widget_props); + g_object_class_override_property (gobject_class, PROP_ACCESSIBLE_ROLE, "accessible-role"); + /** * GtkWidget::destroy: * @object: the object which received the signal @@ -1715,6 +1720,9 @@ gtk_widget_set_property (GObject *object, case PROP_LAYOUT_MANAGER: gtk_widget_set_layout_manager (widget, g_value_dup_object (value)); break; + case PROP_ACCESSIBLE_ROLE: + priv->accessible_role = g_value_get_enum (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -1845,6 +1853,16 @@ gtk_widget_get_property (GObject *object, case PROP_LAYOUT_MANAGER: g_value_set_object (value, gtk_widget_get_layout_manager (widget)); break; + case PROP_ACCESSIBLE_ROLE: + { + GtkAccessibleRole role = priv->accessible_role; + + if (priv->accessible_role == GTK_ACCESSIBLE_ROLE_WIDGET) + role = gtk_widget_class_get_accessible_role (GTK_WIDGET_GET_CLASS (widget)); + + g_value_set_enum (value, role); + } + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -2258,6 +2276,8 @@ gtk_widget_init (GTypeInstance *instance, gpointer g_class) priv->halign = GTK_ALIGN_FILL; priv->valign = GTK_ALIGN_FILL; + priv->accessible_role = GTK_ACCESSIBLE_ROLE_WIDGET; + priv->width_request = -1; priv->height_request = -1; @@ -8076,9 +8096,23 @@ gtk_widget_accessible_get_at_context (GtkAccessible *accessible) { GtkWidgetClass *widget_class = GTK_WIDGET_GET_CLASS (self); GtkWidgetClassPrivate *class_priv = widget_class->priv; + GtkAccessibleRole role; - priv->at_context = - gtk_at_context_create (class_priv->accessible_role, accessible); + /* Widgets have two options to set the accessible role: either they + * define it in their class_init() function, and the role applies to + * all instances; or an instance is created with the :accessible-role + * property (from GtkAccessible) set to anything other than the default + * GTK_ACCESSIBLE_ROLE_WIDGET value. + * + * In either case, the accessible role cannot be set post-construction. + */ + if (priv->accessible_role != GTK_ACCESSIBLE_ROLE_WIDGET) + role = priv->accessible_role; + else + role = class_priv->accessible_role; + + priv->at_context = gtk_at_context_create (role, accessible); + priv->accessible_role = role; } return priv->at_context; @@ -12139,3 +12173,27 @@ gtk_widget_class_set_accessible_role (GtkWidgetClass *widget_class, priv = widget_class->priv; priv->accessible_role = accessible_role; } + +/** + * gtk_widget_class_get_accessible_role: + * @widget_class: a #GtkWidgetClass + * + * Retrieves the accessible role used by the given #GtkWidget class. + * + * Different accessible roles have different states, and are rendered + * differently by assistive technologies. + * + * See also: gtk_accessible_get_accessible_role() + * + * Returns: the accessible role for the widget class + */ +GtkAccessibleRole +gtk_widget_class_get_accessible_role (GtkWidgetClass *widget_class) +{ + GtkWidgetClassPrivate *priv; + + g_return_val_if_fail (GTK_IS_WIDGET_CLASS (widget_class), GTK_ACCESSIBLE_ROLE_WIDGET); + + priv = widget_class->priv; + return priv->accessible_role; +} diff --git a/gtk/gtkwidget.h b/gtk/gtkwidget.h index fb4d13d5c7..e3ead82e2f 100644 --- a/gtk/gtkwidget.h +++ b/gtk/gtkwidget.h @@ -980,6 +980,8 @@ void gtk_widget_action_set_enabled (GtkWidget *widget, GDK_AVAILABLE_IN_ALL void gtk_widget_class_set_accessible_role (GtkWidgetClass *widget_class, GtkAccessibleRole accessible_role); +GDK_AVAILABLE_IN_ALL +GtkAccessibleRole gtk_widget_class_get_accessible_role (GtkWidgetClass *widget_class); G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkWidget, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkRequisition, gtk_requisition_free) diff --git a/gtk/gtkwidgetprivate.h b/gtk/gtkwidgetprivate.h index 60e53705c0..b5af950cf4 100644 --- a/gtk/gtkwidgetprivate.h +++ b/gtk/gtkwidgetprivate.h @@ -193,7 +193,8 @@ struct _GtkWidgetPrivate char *tooltip_markup; char *tooltip_text; - /* Accessible context */ + /* Accessibility */ + GtkAccessibleRole accessible_role; GtkATContext *at_context; }; |