[gtk/ebassi/new-a11y: 14/14] Add accessible properties to GtkAccessible
- From: Emmanuele Bassi <ebassi src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/ebassi/new-a11y: 14/14] Add accessible properties to GtkAccessible
- Date: Mon, 13 Jul 2020 14:55:44 +0000 (UTC)
commit c03f5ed0da8ad240040c625344715d2a4051e9ce
Author: Emmanuele Bassi <ebassi gnome org>
Date: Mon Jul 13 15:51:39 2020 +0100
Add accessible properties to GtkAccessible
We propagate the accessible state and properties to each ATContext in
the same virtual function, since they are functionally similar.
gtk/gtkaccessible.c | 60 +++++++++++++++++++++++++++++++---
gtk/gtkaccessible.h | 16 +++++----
gtk/gtkatcontext.c | 83 +++++++++++++++++++++++++++++++++++++++--------
gtk/gtkatcontextprivate.h | 69 +++++++++++++++++++++++++++++----------
gtk/gtktestatcontext.c | 21 ++++++++----
5 files changed, 200 insertions(+), 49 deletions(-)
---
diff --git a/gtk/gtkaccessible.c b/gtk/gtkaccessible.c
index 47bebc7543..0d6e2bd717 100644
--- a/gtk/gtkaccessible.c
+++ b/gtk/gtkaccessible.c
@@ -116,7 +116,7 @@ gtk_accessible_get_accessible_role (GtkAccessible *self)
* state change must be communicated to assistive technologies.
*/
void
-gtk_accessible_update_state (GtkAccessible *self,
+gtk_accessible_update_state (GtkAccessible *self,
GtkAccessibleState first_state,
...)
{
@@ -141,13 +141,13 @@ gtk_accessible_update_state (GtkAccessible *self,
if (value == NULL)
goto out;
- gtk_at_context_set_state (context, state, value);
+ gtk_at_context_set_accessible_state (context, state, value);
gtk_accessible_value_unref (value);
state = va_arg (args, int);
}
- gtk_at_context_update_state (context);
+ gtk_at_context_update (context);
out:
va_end (args);
@@ -185,7 +185,57 @@ gtk_accessible_update_state_value (GtkAccessible *self,
if (real_value == NULL)
return;
- gtk_at_context_set_state (context, state, real_value);
+ gtk_at_context_set_accessible_state (context, state, real_value);
gtk_accessible_value_unref (real_value);
- gtk_at_context_update_state (context);
+ gtk_at_context_update (context);
+}
+
+/**
+ * gtk_accessible_update_property:
+ * @self: a #GtkAccessible
+ * @first_property: the first #GtkAccessibleProperty
+ * @...: a list of property and value pairs, terminated by -1
+ *
+ * Updates a list of accessible properties.
+ *
+ * This function should be called by #GtkWidget types whenever an accessible
+ * property change must be communicated to assistive technologies.
+ */
+void
+gtk_accessible_update_property (GtkAccessible *self,
+ GtkAccessibleProperty first_property,
+ ...)
+{
+ GtkAccessibleProperty property;
+ GtkATContext *context;
+ va_list args;
+
+ g_return_if_fail (GTK_IS_ACCESSIBLE (self));
+
+ context = gtk_accessible_get_at_context (self);
+ if (context == NULL)
+ return;
+
+ va_start (args, first_property);
+
+ property = first_property;
+
+ while (property != -1)
+ {
+ GtkAccessibleValue *value = gtk_accessible_value_collect_for_property (property, &args);
+
+ /* gtk_accessible_value_collect_for_property() will warn for us */
+ if (value == NULL)
+ goto out;
+
+ gtk_at_context_set_accessible_property (context, property, value);
+ gtk_accessible_value_unref (value);
+
+ property = va_arg (args, int);
+ }
+
+ gtk_at_context_update (context);
+
+out:
+ va_end (args);
}
diff --git a/gtk/gtkaccessible.h b/gtk/gtkaccessible.h
index 5b943f89a2..f95ba930d2 100644
--- a/gtk/gtkaccessible.h
+++ b/gtk/gtkaccessible.h
@@ -32,15 +32,19 @@ GDK_AVAILABLE_IN_ALL
G_DECLARE_INTERFACE (GtkAccessible, gtk_accessible, GTK, ACCESSIBLE, GObject)
GDK_AVAILABLE_IN_ALL
-GtkAccessibleRole gtk_accessible_get_accessible_role (GtkAccessible *self);
+GtkAccessibleRole gtk_accessible_get_accessible_role (GtkAccessible *self);
GDK_AVAILABLE_IN_ALL
-void gtk_accessible_update_state (GtkAccessible *self,
- GtkAccessibleState first_state,
+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_property (GtkAccessible *self,
+ GtkAccessibleProperty first_property,
+ ...);
+GDK_AVAILABLE_IN_ALL
+void gtk_accessible_update_state_value (GtkAccessible *self,
+ GtkAccessibleState state,
+ const GValue *value);
G_END_DECLS
diff --git a/gtk/gtkatcontext.c b/gtk/gtkatcontext.c
index 5627160b40..4fe0b8176f 100644
--- a/gtk/gtkatcontext.c
+++ b/gtk/gtkatcontext.c
@@ -57,6 +57,7 @@ gtk_at_context_finalize (GObject *gobject)
GtkATContext *self = GTK_AT_CONTEXT (gobject);
gtk_accessible_state_set_unref (self->states);
+ gtk_accessible_property_set_unref (self->properties);
G_OBJECT_CLASS (gtk_at_context_parent_class)->finalize (gobject);
}
@@ -108,9 +109,11 @@ gtk_at_context_get_property (GObject *gobject,
}
static void
-gtk_at_context_real_state_change (GtkATContext *self,
- GtkAccessibleStateChange change,
- GtkAccessibleStateSet *states)
+gtk_at_context_real_state_change (GtkATContext *self,
+ GtkAccessibleStateChange changed_states,
+ GtkAccessiblePropertyChange changed_properies,
+ GtkAccessibleStateSet *states,
+ GtkAccessiblePropertySet *properties)
{
}
@@ -166,6 +169,7 @@ gtk_at_context_init (GtkATContext *self)
self->accessible_role = GTK_ACCESSIBLE_ROLE_WIDGET;
self->states = gtk_accessible_state_set_new ();
+ self->properties = gtk_accessible_property_set_new ();
}
/**
@@ -252,34 +256,87 @@ gtk_at_context_create (GtkAccessibleRole accessible_role,
}
/*< private >
- * gtk_at_context_update_state:
+ * gtk_at_context_update:
* @self: a #GtkATContext
*
* Notifies the AT connected to this #GtkATContext that the accessible
- * state has changed.
+ * state and its properties have changed.
*/
void
-gtk_at_context_update_state (GtkATContext *self)
+gtk_at_context_update (GtkATContext *self)
{
g_return_if_fail (GTK_IS_AT_CONTEXT (self));
- GtkAccessibleStateChange change = 0;
+ GtkAccessibleStateChange changed_states = 0;
+ GtkAccessiblePropertyChange changed_properties = 0;
for (int i = 0; i < GTK_ACCESSIBLE_STATE_SELECTED; i++)
{
if (gtk_accessible_state_set_contains (self->states, i))
- change |= (1 << i);
+ changed_states |= (1 << i);
}
- GTK_AT_CONTEXT_GET_CLASS (self)->state_change (self, change, self->states);
+ for (int i = 0; i < GTK_ACCESSIBLE_PROPERTY_VALUE_TEXT; i++)
+ {
+ if (gtk_accessible_property_set_contains (self->properties, i))
+ changed_properties |= (1 << i);
+ }
+
+ GTK_AT_CONTEXT_GET_CLASS (self)->state_change (self,
+ changed_states,
+ changed_properties,
+ self->states,
+ self->properties);
}
+/*< private >
+ * gtk_at_context_set_state:
+ * @self: a #GtkATContext
+ * @state: a #GtkAccessibleState
+ * @value: (nullable): #GtkAccessibleValue
+ *
+ * Sets the @value for the given @state of a #GtkATContext.
+ *
+ * If @value is %NULL, the state is unset.
+ *
+ * This function will accumulate state changes until gtk_at_context_update_state()
+ * is called.
+ */
+void
+gtk_at_context_set_accessible_state (GtkATContext *self,
+ GtkAccessibleState state,
+ GtkAccessibleValue *value)
+{
+ g_return_if_fail (GTK_IS_AT_CONTEXT (self));
+
+ if (value != NULL)
+ gtk_accessible_state_set_add (self->states, state, value);
+ else
+ gtk_accessible_state_set_remove (self->states, state);
+}
+
+/*< private >
+ * gtk_at_context_set_accessible_property:
+ * @self: a #GtkATContext
+ * @property: a #GtkAccessibleProperty
+ * @value: (nullable): #GtkAccessibleValue
+ *
+ * Sets the @value for the given @property of a #GtkATContext.
+ *
+ * If @value is %NULL, the property is unset.
+ *
+ * This function will accumulate property changes until gtk_at_context_update_state()
+ * is called.
+ */
void
-gtk_at_context_set_state (GtkATContext *self,
- GtkAccessibleState state,
- GtkAccessibleValue *value)
+gtk_at_context_set_accessible_property (GtkATContext *self,
+ GtkAccessibleProperty property,
+ GtkAccessibleValue *value)
{
g_return_if_fail (GTK_IS_AT_CONTEXT (self));
- gtk_accessible_state_set_add (self->states, state, value);
+ if (value != NULL)
+ gtk_accessible_property_set_add (self->properties, property, value);
+ else
+ gtk_accessible_property_set_remove (self->properties, property);
}
diff --git a/gtk/gtkatcontextprivate.h b/gtk/gtkatcontextprivate.h
index 8ee334ca86..4df4d26bb5 100644
--- a/gtk/gtkatcontextprivate.h
+++ b/gtk/gtkatcontextprivate.h
@@ -23,21 +23,48 @@
#include "gtkatcontext.h"
#include "gtkaccessiblestatesetprivate.h"
+#include "gtkaccessiblepropertysetprivate.h"
G_BEGIN_DECLS
typedef enum {
- GTK_ACCESSIBLE_STATE_CHANGE_BUSY = 1 << GTK_ACCESSIBLE_STATE_BUSY,
- GTK_ACCESSIBLE_STATE_CHANGE_CHECKED = 1 << GTK_ACCESSIBLE_STATE_CHECKED,
- GTK_ACCESSIBLE_STATE_CHANGE_DISABLED = 1 << GTK_ACCESSIBLE_STATE_DISABLED,
- GTK_ACCESSIBLE_STATE_CHANGE_EXPANDED = 1 << GTK_ACCESSIBLE_STATE_EXPANDED,
- GTK_ACCESSIBLE_STATE_CHANGE_GRABBED = 1 << GTK_ACCESSIBLE_STATE_GRABBED,
- GTK_ACCESSIBLE_STATE_CHANGE_HIDDEN = 1 << GTK_ACCESSIBLE_STATE_HIDDEN,
- GTK_ACCESSIBLE_STATE_CHANGE_INVALID = 1 << GTK_ACCESSIBLE_STATE_INVALID,
- GTK_ACCESSIBLE_STATE_CHANGE_PRESSED = 1 << GTK_ACCESSIBLE_STATE_PRESSED,
- GTK_ACCESSIBLE_STATE_CHANGE_SELECTED = 1 << GTK_ACCESSIBLE_STATE_SELECTED
+ GTK_ACCESSIBLE_STATE_CHANGE_BUSY = 1 << GTK_ACCESSIBLE_STATE_BUSY,
+ GTK_ACCESSIBLE_STATE_CHANGE_CHECKED = 1 << GTK_ACCESSIBLE_STATE_CHECKED,
+ GTK_ACCESSIBLE_STATE_CHANGE_DISABLED = 1 << GTK_ACCESSIBLE_STATE_DISABLED,
+ GTK_ACCESSIBLE_STATE_CHANGE_EXPANDED = 1 << GTK_ACCESSIBLE_STATE_EXPANDED,
+ GTK_ACCESSIBLE_STATE_CHANGE_GRABBED = 1 << GTK_ACCESSIBLE_STATE_GRABBED,
+ GTK_ACCESSIBLE_STATE_CHANGE_HIDDEN = 1 << GTK_ACCESSIBLE_STATE_HIDDEN,
+ GTK_ACCESSIBLE_STATE_CHANGE_INVALID = 1 << GTK_ACCESSIBLE_STATE_INVALID,
+ GTK_ACCESSIBLE_STATE_CHANGE_PRESSED = 1 << GTK_ACCESSIBLE_STATE_PRESSED,
+ GTK_ACCESSIBLE_STATE_CHANGE_SELECTED = 1 << GTK_ACCESSIBLE_STATE_SELECTED
} GtkAccessibleStateChange;
+typedef enum {
+ GTK_ACCESSIBLE_PROPERTY_CHANGE_ACTIVE_DESCENDANT = 1 << GTK_ACCESSIBLE_PROPERTY_ACTIVE_DESCENDANT,
+ GTK_ACCESSIBLE_PROPERTY_CHANGE_AUTOCOMPLETE = 1 << GTK_ACCESSIBLE_PROPERTY_AUTOCOMPLETE,
+ GTK_ACCESSIBLE_PROPERTY_CHANGE_CONTROLS = 1 << GTK_ACCESSIBLE_PROPERTY_CONTROLS,
+ GTK_ACCESSIBLE_PROPERTY_CHANGE_DESCRIBED_BY = 1 << GTK_ACCESSIBLE_PROPERTY_DESCRIBED_BY,
+ GTK_ACCESSIBLE_PROPERTY_CHANGE_FLOW_TO = 1 << GTK_ACCESSIBLE_PROPERTY_FLOW_TO,
+ GTK_ACCESSIBLE_PROPERTY_CHANGE_HAS_POPUP = 1 << GTK_ACCESSIBLE_PROPERTY_HAS_POPUP,
+ GTK_ACCESSIBLE_PROPERTY_CHANGE_LABEL = 1 << GTK_ACCESSIBLE_PROPERTY_LABEL,
+ GTK_ACCESSIBLE_PROPERTY_CHANGE_LABELLED_BY = 1 << GTK_ACCESSIBLE_PROPERTY_LABELLED_BY,
+ GTK_ACCESSIBLE_PROPERTY_CHANGE_LEVEL = 1 << GTK_ACCESSIBLE_PROPERTY_LEVEL,
+ GTK_ACCESSIBLE_PROPERTY_CHANGE_MULTI_LINE = 1 << GTK_ACCESSIBLE_PROPERTY_MULTI_LINE,
+ GTK_ACCESSIBLE_PROPERTY_CHANGE_MULTI_SELECTABLE = 1 << GTK_ACCESSIBLE_PROPERTY_MULTI_SELECTABLE,
+ GTK_ACCESSIBLE_PROPERTY_CHANGE_ORIENTATION = 1 << GTK_ACCESSIBLE_PROPERTY_ORIENTATION,
+ GTK_ACCESSIBLE_PROPERTY_CHANGE_OWNS = 1 << GTK_ACCESSIBLE_PROPERTY_OWNS,
+ GTK_ACCESSIBLE_PROPERTY_CHANGE_POS_IN_SET = 1 << GTK_ACCESSIBLE_PROPERTY_POS_IN_SET,
+ GTK_ACCESSIBLE_PROPERTY_CHANGE_READ_ONLY = 1 << GTK_ACCESSIBLE_PROPERTY_READ_ONLY,
+ GTK_ACCESSIBLE_PROPERTY_CHANGE_RELEVANT = 1 << GTK_ACCESSIBLE_PROPERTY_RELEVANT,
+ GTK_ACCESSIBLE_PROPERTY_CHANGE_REQUIRED = 1 << GTK_ACCESSIBLE_PROPERTY_REQUIRED,
+ GTK_ACCESSIBLE_PROPERTY_CHANGE_SET_SIZE = 1 << GTK_ACCESSIBLE_PROPERTY_SET_SIZE,
+ GTK_ACCESSIBLE_PROPERTY_CHANGE_SORT = 1 << GTK_ACCESSIBLE_PROPERTY_SORT,
+ GTK_ACCESSIBLE_PROPERTY_CHANGE_VALUE_MAX = 1 << GTK_ACCESSIBLE_PROPERTY_VALUE_MAX,
+ GTK_ACCESSIBLE_PROPERTY_CHANGE_VALUE_MIN = 1 << GTK_ACCESSIBLE_PROPERTY_VALUE_MIN,
+ GTK_ACCESSIBLE_PROPERTY_CHANGE_VALUE_NOW = 1 << GTK_ACCESSIBLE_PROPERTY_VALUE_NOW,
+ GTK_ACCESSIBLE_PROPERTY_CHANGE_VALUE_TEXT = 1 << GTK_ACCESSIBLE_PROPERTY_VALUE_TEXT
+} GtkAccessiblePropertyChange;
+
struct _GtkATContext
{
GObject parent_instance;
@@ -46,24 +73,30 @@ struct _GtkATContext
GtkAccessible *accessible;
GtkAccessibleStateSet *states;
+ GtkAccessiblePropertySet *properties;
};
struct _GtkATContextClass
{
GObjectClass parent_class;
- void (* state_change) (GtkATContext *self,
- GtkAccessibleStateChange changed,
- GtkAccessibleStateSet *states);
+ void (* state_change) (GtkATContext *self,
+ GtkAccessibleStateChange changed_states,
+ GtkAccessiblePropertyChange changed_properties,
+ GtkAccessibleStateSet *states,
+ GtkAccessiblePropertySet *properties);
};
-GtkATContext * gtk_at_context_create (GtkAccessibleRole accessible_role,
- GtkAccessible *accessible);
+GtkATContext * gtk_at_context_create (GtkAccessibleRole accessible_role,
+ GtkAccessible *accessible);
-void gtk_at_context_update_state (GtkATContext *self);
+void gtk_at_context_update (GtkATContext *self);
-void gtk_at_context_set_state (GtkATContext *self,
- GtkAccessibleState state,
- GtkAccessibleValue *value);
+void gtk_at_context_set_accessible_state (GtkATContext *self,
+ GtkAccessibleState state,
+ GtkAccessibleValue *value);
+void gtk_at_context_set_accessible_property (GtkATContext *self,
+ GtkAccessibleProperty property,
+ GtkAccessibleValue *value);
G_END_DECLS
diff --git a/gtk/gtktestatcontext.c b/gtk/gtktestatcontext.c
index 8324d44375..f89e354451 100644
--- a/gtk/gtktestatcontext.c
+++ b/gtk/gtktestatcontext.c
@@ -33,20 +33,27 @@ struct _GtkTestATContext
G_DEFINE_TYPE (GtkTestATContext, gtk_test_at_context, GTK_TYPE_AT_CONTEXT)
static void
-gtk_test_at_context_state_change (GtkATContext *self,
- GtkAccessibleStateChange change,
- GtkAccessibleStateSet *states)
+gtk_test_at_context_state_change (GtkATContext *self,
+ GtkAccessibleStateChange changed_states,
+ GtkAccessiblePropertyChange changed_properties,
+ GtkAccessibleStateSet *states,
+ GtkAccessiblePropertySet *properties)
{
GtkAccessible *accessible = gtk_at_context_get_accessible (self);
GtkAccessibleRole role = gtk_at_context_get_accessible_role (self);
- char *state = gtk_accessible_state_set_to_string (states);
+ char *states_str = gtk_accessible_state_set_to_string (states);
+ char *properties_str = gtk_accessible_property_set_to_string (properties);
- g_print ("Accessible state changed for accessible ā%sā, with role %d: %s\n",
+ g_print ("*** Accessible state changed for accessible ā%sā, with role %d:\n"
+ "*** states = %s\n"
+ "*** properties = %s\n",
G_OBJECT_TYPE_NAME (accessible),
role,
- state);
+ states_str,
+ properties_str);
- g_free (state);
+ g_free (states_str);
+ g_free (properties_str);
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]