[gtk/ebassi/new-a11y: 42/71] Allow setting the accessible role at construction
- From: Emmanuele Bassi <ebassi src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/ebassi/new-a11y: 42/71] Allow setting the accessible role at construction
- Date: Wed, 22 Jul 2020 12:25:18 +0000 (UTC)
commit 1accdd8469bbe38730b9082a4b29e95d2a055a90
Author: Emmanuele Bassi <ebassi gnome org>
Date: Mon Jul 13 15:20:19 2020 +0100
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.
gtk/gtkaccessible.c | 40 +++++++++++++++++++++++++++++++
gtk/gtkaccessible.h | 15 +++++++-----
gtk/gtkwidget.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++---
gtk/gtkwidget.h | 2 ++
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)
{
@@ -64,6 +84,26 @@ gtk_accessible_get_at_context (GtkAccessible *self)
return GTK_ACCESSIBLE_GET_IFACE (self)->get_at_context (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
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 99039210a4..3d189002f6 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 a897237860..08b9bf2de2 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 f0df306bde..d417edc77c 100644
--- a/gtk/gtkwidgetprivate.h
+++ b/gtk/gtkwidgetprivate.h
@@ -191,7 +191,8 @@ struct _GtkWidgetPrivate
char *tooltip_markup;
char *tooltip_text;
- /* Accessible context */
+ /* Accessibility */
+ GtkAccessibleRole accessible_role;
GtkATContext *at_context;
};
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]