[gtk/ebassi/new-a11y: 74/87] Add accessible properties to GtkAccessible



commit 2837a479ce0e52f60106b41ae10126da06f66a9e
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/gtkaccessiblevalue.c        | 162 +++++++++++++++++++++++++++++++++++++---
 gtk/gtkaccessiblevalueprivate.h |   4 +
 gtk/gtkatcontext.c              |  83 ++++++++++++++++----
 gtk/gtkatcontextprivate.h       |  69 ++++++++++++-----
 gtk/gtktestatcontext.c          |  21 ++++--
 7 files changed, 354 insertions(+), 61 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/gtkaccessiblevalue.c b/gtk/gtkaccessiblevalue.c
index 2fd6f76742..9394738c8e 100644
--- a/gtk/gtkaccessiblevalue.c
+++ b/gtk/gtkaccessiblevalue.c
@@ -44,6 +44,7 @@
 
 #include "gtkaccessiblevalueprivate.h"
 
+#include "gtkaccessible.h"
 #include "gtkenums.h"
 
 G_DEFINE_QUARK (gtk-accessible-value-error-quark, gtk_accessible_value_error)
@@ -368,6 +369,92 @@ gtk_string_accessible_value_get (const GtkAccessibleValue *value)
   return self->value;
 }
 
+typedef struct {
+  GtkAccessibleValue parent;
+
+  GtkAccessible *ref;
+} GtkReferenceAccessibleValue;
+
+static void
+remove_weak_ref (gpointer  data,
+                 GObject  *old_reference)
+{
+  GtkReferenceAccessibleValue *self = data;
+
+  self->ref = NULL;
+}
+
+static void
+gtk_reference_accessible_value_finalize (GtkAccessibleValue *value)
+{
+  GtkReferenceAccessibleValue *self = (GtkReferenceAccessibleValue *) value;
+
+  if (self->ref != NULL)
+    g_object_weak_unref (G_OBJECT (self->ref), remove_weak_ref, self);
+}
+
+static gboolean
+gtk_reference_accessible_value_equal (const GtkAccessibleValue *value_a,
+                                      const GtkAccessibleValue *value_b)
+{
+  const GtkReferenceAccessibleValue *self_a = (GtkReferenceAccessibleValue *) value_a;
+  const GtkReferenceAccessibleValue *self_b = (GtkReferenceAccessibleValue *) value_b;
+
+  return self_a->ref == self_b->ref;
+}
+
+static void
+gtk_reference_accessible_value_print (const GtkAccessibleValue *value,
+                                      GString                  *buffer)
+{
+  const GtkReferenceAccessibleValue *self = (GtkReferenceAccessibleValue *) value;
+
+  if (self->ref != NULL)
+    {
+      g_string_append_printf (buffer, "%s<%p>",
+                              G_OBJECT_TYPE_NAME (self->ref),
+                              self->ref);
+    }
+  else
+    {
+      g_string_append (buffer, "<null>");
+    }
+}
+
+static const GtkAccessibleValueClass GTK_REFERENCE_ACCESSIBLE_VALUE = {
+  .type_name = "GtkReferenceAccessibleValue",
+  .instance_size = sizeof (GtkReferenceAccessibleValue),
+  .finalize = gtk_reference_accessible_value_finalize,
+  .equal = gtk_reference_accessible_value_equal,
+  .print = gtk_reference_accessible_value_print,
+};
+
+GtkAccessibleValue *
+gtk_reference_accessible_value_new (GtkAccessible *ref)
+{
+  g_return_val_if_fail (GTK_IS_ACCESSIBLE (ref), NULL);
+
+  GtkAccessibleValue *res = gtk_accessible_value_alloc (&GTK_REFERENCE_ACCESSIBLE_VALUE);
+
+  GtkReferenceAccessibleValue *self = (GtkReferenceAccessibleValue *) res;
+
+  self->ref = ref;
+  g_object_weak_ref (G_OBJECT (self->ref), remove_weak_ref, self);
+
+  return res;
+}
+
+GtkAccessible *
+gtk_reference_accessible_value_get (const GtkAccessibleValue *value)
+{
+  GtkReferenceAccessibleValue *self = (GtkReferenceAccessibleValue *) value;
+
+  g_return_val_if_fail (value != NULL, 0);
+  g_return_val_if_fail (value->value_class == &GTK_REFERENCE_ACCESSIBLE_VALUE, 0);
+
+  return self->ref;
+}
+
 /* }}} */
 
 /* {{{ Collection API */
@@ -379,7 +466,8 @@ typedef enum {
   GTK_ACCESSIBLE_COLLECT_TRISTATE,
   GTK_ACCESSIBLE_COLLECT_ENUM,
   GTK_ACCESSIBLE_COLLECT_NUMBER,
-  GTK_ACCESSIBLE_COLLECT_STRING
+  GTK_ACCESSIBLE_COLLECT_STRING,
+  GTK_ACCESSIBLE_COLLECT_REF
 } GtkAccessibleCollectType;
 
 typedef struct {
@@ -412,7 +500,7 @@ static const GtkAccessibleCollect collect_props[] = {
   { GTK_ACCESSIBLE_PROPERTY_FLOW_TO,           GTK_ACCESSIBLE_COLLECT_STRING,  "flowto",           
(GCallback) gtk_string_accessible_value_new },
   { GTK_ACCESSIBLE_PROPERTY_HAS_POPUP,         GTK_ACCESSIBLE_COLLECT_BOOLEAN, "haspopup",         
(GCallback) gtk_boolean_accessible_value_new },
   { GTK_ACCESSIBLE_PROPERTY_LABEL,             GTK_ACCESSIBLE_COLLECT_STRING,  "label",            
(GCallback) gtk_string_accessible_value_new },
-  { GTK_ACCESSIBLE_PROPERTY_LABELLED_BY,       GTK_ACCESSIBLE_COLLECT_STRING,  "labelledby",       
(GCallback) gtk_string_accessible_value_new },
+  { GTK_ACCESSIBLE_PROPERTY_LABELLED_BY,       GTK_ACCESSIBLE_COLLECT_REF   ,  "labelledby",       
(GCallback) gtk_reference_accessible_value_new },
   { GTK_ACCESSIBLE_PROPERTY_LEVEL,             GTK_ACCESSIBLE_COLLECT_INT,     "level",            
(GCallback) gtk_int_accessible_value_new },
   { GTK_ACCESSIBLE_PROPERTY_MULTI_LINE,        GTK_ACCESSIBLE_COLLECT_BOOLEAN, "multiline",        
(GCallback) gtk_boolean_accessible_value_new },
   { GTK_ACCESSIBLE_PROPERTY_MULTI_SELECTABLE,  GTK_ACCESSIBLE_COLLECT_BOOLEAN, "multiselectable",  
(GCallback) gtk_boolean_accessible_value_new },
@@ -436,6 +524,7 @@ typedef GtkAccessibleValue * (* GtkAccessibleValueTristateCtor) (int value);
 typedef GtkAccessibleValue * (* GtkAccessibleValueEnumCtor)     (int value);
 typedef GtkAccessibleValue * (* GtkAccessibleValueNumberCtor)   (double value);
 typedef GtkAccessibleValue * (* GtkAccessibleValueStringCtor)   (const char *value);
+typedef GtkAccessibleValue * (* GtkAccessibleValueRefCtor)      (gpointer value);
 
 /*< private >
  * gtk_accessible_value_get_default_for_state:
@@ -574,6 +663,17 @@ gtk_accessible_value_collect_for_state (GtkAccessibleState  state,
       }
       break;
 
+    case GTK_ACCESSIBLE_COLLECT_REF:
+      {
+        GtkAccessibleValueStringCtor ctor =
+          (GtkAccessibleValueStringCtor) cstate->ctor;
+
+        gpointer value = va_arg (*args, gpointer);
+
+        res = (* ctor) (value);
+      }
+      break;
+
     case GTK_ACCESSIBLE_COLLECT_INVALID:
     default:
       g_critical ("Unknown type for accessible state “%s”", cstate->name);
@@ -671,6 +771,17 @@ gtk_accessible_value_collect_for_state_value (GtkAccessibleState  state,
       }
       break;
 
+    case GTK_ACCESSIBLE_COLLECT_REF:
+      {
+        GtkAccessibleValueStringCtor ctor =
+          (GtkAccessibleValueStringCtor) cstate->ctor;
+
+        gpointer value_ = g_value_get_object (value);
+
+        res = (* ctor) (value_);
+      }
+      break;
+
     case GTK_ACCESSIBLE_COLLECT_INVALID:
     default:
       g_critical ("Unknown value type for accessible state “%s”", cstate->name);
@@ -696,6 +807,7 @@ gtk_accessible_value_get_default_for_property (GtkAccessibleProperty property)
 
   switch (cstate->value)
     {
+    /* Reference properties */
     case GTK_ACCESSIBLE_PROPERTY_ACTIVE_DESCENDANT:
     case GTK_ACCESSIBLE_PROPERTY_CONTROLS:
     case GTK_ACCESSIBLE_PROPERTY_DESCRIBED_BY:
@@ -703,9 +815,9 @@ gtk_accessible_value_get_default_for_property (GtkAccessibleProperty property)
     case GTK_ACCESSIBLE_PROPERTY_LABELLED_BY:
     case GTK_ACCESSIBLE_PROPERTY_OWNS:
     case GTK_ACCESSIBLE_PROPERTY_RELEVANT:
-      g_critical ("Unsupported property “%s”", cstate->name);
       return NULL;
 
+    /* Boolean properties */
     case GTK_ACCESSIBLE_PROPERTY_HAS_POPUP:
     case GTK_ACCESSIBLE_PROPERTY_MULTI_LINE:
     case GTK_ACCESSIBLE_PROPERTY_MULTI_SELECTABLE:
@@ -713,29 +825,33 @@ gtk_accessible_value_get_default_for_property (GtkAccessibleProperty property)
     case GTK_ACCESSIBLE_PROPERTY_REQUIRED:
       return gtk_boolean_accessible_value_new (FALSE);
 
+    /* Integer properties */
     case GTK_ACCESSIBLE_PROPERTY_LEVEL:
     case GTK_ACCESSIBLE_PROPERTY_POS_IN_SET:
     case GTK_ACCESSIBLE_PROPERTY_SET_SIZE:
       return gtk_int_accessible_value_new (0);
 
-    case GTK_ACCESSIBLE_PROPERTY_AUTOCOMPLETE:
-      return gtk_autocomplete_accessible_value_new (GTK_ACCESSIBLE_AUTOCOMPLETE_NONE);
-
-    case GTK_ACCESSIBLE_PROPERTY_ORIENTATION:
-      return gtk_orientation_accessible_value_new (GTK_ORIENTATION_HORIZONTAL);
-
-    case GTK_ACCESSIBLE_PROPERTY_SORT:
-      return gtk_sort_accessible_value_new (GTK_ACCESSIBLE_SORT_NONE);
-
+    /* Number properties */
     case GTK_ACCESSIBLE_PROPERTY_VALUE_MAX:
     case GTK_ACCESSIBLE_PROPERTY_VALUE_MIN:
     case GTK_ACCESSIBLE_PROPERTY_VALUE_NOW:
       return gtk_number_accessible_value_new (0);
 
+    /* String properties */
     case GTK_ACCESSIBLE_PROPERTY_LABEL:
     case GTK_ACCESSIBLE_PROPERTY_VALUE_TEXT:
       return gtk_string_accessible_value_new ("");
 
+    /* Token properties */
+    case GTK_ACCESSIBLE_PROPERTY_AUTOCOMPLETE:
+      return gtk_autocomplete_accessible_value_new (GTK_ACCESSIBLE_AUTOCOMPLETE_NONE);
+
+    case GTK_ACCESSIBLE_PROPERTY_ORIENTATION:
+      return gtk_orientation_accessible_value_new (GTK_ORIENTATION_HORIZONTAL);
+
+    case GTK_ACCESSIBLE_PROPERTY_SORT:
+      return gtk_sort_accessible_value_new (GTK_ACCESSIBLE_SORT_NONE);
+
     default:
       g_critical ("Unknown value for accessible state “%s”", cstate->name);
       break;
@@ -830,6 +946,17 @@ gtk_accessible_value_collect_for_property (GtkAccessibleProperty  property,
       }
       break;
 
+    case GTK_ACCESSIBLE_COLLECT_REF:
+      {
+        GtkAccessibleValueStringCtor ctor =
+          (GtkAccessibleValueStringCtor) cstate->ctor;
+
+        gpointer value = va_arg (*args, gpointer);
+
+        res = (* ctor) (value);
+      }
+      break;
+
     case GTK_ACCESSIBLE_COLLECT_INVALID:
     default:
       g_critical ("Unknown type for accessible state “%s”", cstate->name);
@@ -925,6 +1052,17 @@ gtk_accessible_value_collect_for_property_value (GtkAccessibleProperty  property
       }
       break;
 
+    case GTK_ACCESSIBLE_COLLECT_REF:
+      {
+        GtkAccessibleValueStringCtor ctor =
+          (GtkAccessibleValueStringCtor) cstate->ctor;
+
+        gpointer value_ = g_value_get_object (value);
+
+        res = (* ctor) (value_);
+      }
+      break;
+
     case GTK_ACCESSIBLE_COLLECT_INVALID:
     default:
       g_critical ("Unknown value type for accessible state “%s”", cstate->name);
diff --git a/gtk/gtkaccessiblevalueprivate.h b/gtk/gtkaccessiblevalueprivate.h
index d924fa0f9f..3c007aedbe 100644
--- a/gtk/gtkaccessiblevalueprivate.h
+++ b/gtk/gtkaccessiblevalueprivate.h
@@ -22,6 +22,7 @@
 
 #include <glib-object.h>
 
+#include "gtkaccessible.h"
 #include "gtkenums.h"
 
 G_BEGIN_DECLS
@@ -135,6 +136,9 @@ double                          gtk_number_accessible_value_get         (const G
 GtkAccessibleValue *            gtk_string_accessible_value_new         (const char               *value);
 const char *                    gtk_string_accessible_value_get         (const GtkAccessibleValue *value);
 
+GtkAccessibleValue *            gtk_reference_accessible_value_new      (GtkAccessible            *value);
+GtkAccessible *                 gtk_reference_accessible_value_get      (const GtkAccessibleValue *value);
+
 /* Tri-state values */
 GtkAccessibleValue *            gtk_expanded_accessible_value_new       (int                       value);
 int                             gtk_expanded_accessible_value_get       (const GtkAccessibleValue *value);
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]