a11y: Add GTK_ACCESSIBLE_STATE_VISITED
authorLukáš Tyrychtr <ltyrycht@redhat.com>
Tue, 7 Mar 2023 10:20:53 +0000 (11:20 +0100)
committerLukáš Tyrychtr <ltyrycht@redhat.com>
Wed, 8 Mar 2023 08:24:08 +0000 (09:24 +0100)
This state is used for visited link-like widgets.
It has no ARIA equivalent, e. g. can not be set programmatically, but it
exists in the browser environment as well.

docs/reference/gtk/section-accessibility.md
gtk/a11y/gtkatspicontext.c
gtk/gtkaccessiblevalue.c
gtk/gtkatcontext.c
gtk/gtkatcontextprivate.h
gtk/gtkenums.h

index 37c1f3338805764f0d43da438095cc328e258f86..71ccd417eede2172ab537d697f8062dcf6d3b3d8 100644 (file)
@@ -128,6 +128,7 @@ Each state name is part of the `GtkAccessibleState` enumeration.
 | %GTK_ACCESSIBLE_STATE_INVALID | “aria-invalid” | `GtkAccessibleInvalidState` | Set when a widget is showing an error |
 | %GTK_ACCESSIBLE_STATE_PRESSED | “aria-pressed” | `GtkAccessibleTristate` | Indicates the current state of a [class@Gtk.ToggleButton] |
 | %GTK_ACCESSIBLE_STATE_SELECTED | “aria-selected” | boolean or undefined | Set when a widget is selected |
+| %GTK_ACCESSIBLE_STATE_VISITED | N/A | boolean or undefined | Set when a link-like widget is visited |
 
 #### List of accessible properties
 
index dca263902eee242d6b81c1be9c9d658e911735e1..a3a8eacefc4015c472a304514a7065ec3632c1d6 100644 (file)
@@ -282,6 +282,16 @@ collect_states (GtkAtSpiContext    *self,
         }
     }
 
+  if (gtk_at_context_has_accessible_state (ctx, GTK_ACCESSIBLE_STATE_VISITED))
+    {
+      value = gtk_at_context_get_accessible_state (ctx, GTK_ACCESSIBLE_STATE_VISITED);
+      if (value->value_class->type == GTK_ACCESSIBLE_VALUE_TYPE_BOOLEAN)
+        {
+          if (gtk_boolean_accessible_value_get (value))
+            set_atspi_state (&states, ATSPI_STATE_VISITED);
+        }
+    }
+
   if (gtk_at_context_has_accessible_property (ctx, GTK_ACCESSIBLE_PROPERTY_REQUIRED))
     {
       value = gtk_at_context_get_accessible_property (ctx, GTK_ACCESSIBLE_PROPERTY_REQUIRED);
@@ -1048,6 +1058,15 @@ gtk_at_spi_context_state_change (GtkATContext                *ctx,
         emit_state_changed (self, "selectable", FALSE);
     }
 
+  if (changed_states & GTK_ACCESSIBLE_STATE_CHANGE_VISITED)
+    {
+      value = gtk_accessible_attribute_set_get_value (states, GTK_ACCESSIBLE_STATE_VISITED);
+      if (value->value_class->type == GTK_ACCESSIBLE_VALUE_TYPE_BOOLEAN)
+        {
+          emit_state_changed (self, "visited",gtk_boolean_accessible_value_get (value));
+        }
+    }
+
   if (changed_properties & GTK_ACCESSIBLE_PROPERTY_CHANGE_READ_ONLY)
     {
       gboolean readonly;
index 6a9534bd8e60c20eaae469bfc29c6b93a23edb58..e5d7cc29daaa977d5cc287fe5c28c075ea75e28d 100644 (file)
@@ -688,6 +688,11 @@ static const GtkAccessibleCollect collect_states[] = {
     .ctype = GTK_ACCESSIBLE_COLLECT_BOOLEAN | GTK_ACCESSIBLE_COLLECT_UNDEFINED,
     .name = "selected"
   },
+  [GTK_ACCESSIBLE_STATE_VISITED] = {
+    .value = GTK_ACCESSIBLE_STATE_VISITED,
+    .ctype = GTK_ACCESSIBLE_COLLECT_BOOLEAN|GTK_ACCESSIBLE_COLLECT_UNDEFINED,
+    .name = "visited"
+  }
 };
 
 /* § 6.6.1 Widget attributes */
@@ -927,7 +932,7 @@ gtk_accessible_value_get_default_for_state (GtkAccessibleState state)
 {
   const GtkAccessibleCollect *cstate = &collect_states[state];
 
-  g_return_val_if_fail (state <= GTK_ACCESSIBLE_STATE_SELECTED, NULL);
+  g_return_val_if_fail (state <= GTK_ACCESSIBLE_STATE_VISITED, NULL);
 
   switch (cstate->value)
     {
@@ -940,6 +945,7 @@ gtk_accessible_value_get_default_for_state (GtkAccessibleState state)
     case GTK_ACCESSIBLE_STATE_EXPANDED:
     case GTK_ACCESSIBLE_STATE_PRESSED:
     case GTK_ACCESSIBLE_STATE_SELECTED:
+    case GTK_ACCESSIBLE_STATE_VISITED:
       return gtk_undefined_accessible_value_new ();
 
     case GTK_ACCESSIBLE_STATE_INVALID:
@@ -1564,7 +1570,7 @@ gtk_accessible_value_collect_for_state (GtkAccessibleState   state,
 {
   const GtkAccessibleCollect *cstate = &collect_states[state];
 
-  g_return_val_if_fail (state <= GTK_ACCESSIBLE_STATE_SELECTED, NULL);
+  g_return_val_if_fail (state <= GTK_ACCESSIBLE_STATE_VISITED, NULL);
 
   return gtk_accessible_value_collect_valist (cstate, error, args);
 }
@@ -1592,7 +1598,7 @@ gtk_accessible_value_collect_for_state_value (GtkAccessibleState   state,
 {
   const GtkAccessibleCollect *cstate = &collect_states[state];
 
-  g_return_val_if_fail (state <= GTK_ACCESSIBLE_STATE_SELECTED, NULL);
+  g_return_val_if_fail (state <= GTK_ACCESSIBLE_STATE_VISITED, NULL);
 
   return gtk_accessible_value_collect_value (cstate, value, error);
 }
@@ -1605,7 +1611,7 @@ gtk_accessible_value_parse_for_state (GtkAccessibleState   state,
 {
   const GtkAccessibleCollect *cstate = &collect_states[state];
 
-  g_return_val_if_fail (state <= GTK_ACCESSIBLE_STATE_SELECTED, NULL);
+  g_return_val_if_fail (state <= GTK_ACCESSIBLE_STATE_VISITED, NULL);
 
   return gtk_accessible_value_parse (cstate, str, len, error);
 }
index 2ae924cc92dea11eec48255b13e49beb709b190a..7db5c95fe7ea6454bbefd04d44351c6228645b0c 100644 (file)
@@ -366,6 +366,7 @@ static const char *state_attrs[] = {
   [GTK_ACCESSIBLE_STATE_INVALID]        = "invalid",
   [GTK_ACCESSIBLE_STATE_PRESSED]        = "pressed",
   [GTK_ACCESSIBLE_STATE_SELECTED]       = "selected",
+  [GTK_ACCESSIBLE_STATE_VISITED] = "visited",
 };
 
 /*< private >
index e7ea71724376f0ce902c1f5a127c2c324ef4b5b1..d9489fa3c93107376f97c2ee8178f3e567d3e5c9 100644 (file)
@@ -78,7 +78,8 @@ typedef enum {
   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_SELECTED = 1 << GTK_ACCESSIBLE_STATE_SELECTED,
+  GTK_ACCESSIBLE_STATE_CHANGE_VISITED = 1 << GTK_ACCESSIBLE_STATE_VISITED
 } GtkAccessibleStateChange;
 
 struct _GtkATContext
index 679c75e44785f5ebd742043f2b09aa1fde6ad6dc..af2f3689cae70adc71bc90f54d500c220c7a2196 100644 (file)
@@ -1420,6 +1420,8 @@ typedef enum {
  *   enumeration
  * @GTK_ACCESSIBLE_STATE_SELECTED: A “selected” state; set when a widget
  *   is selected. Value type: boolean or undefined
+ * @GTK_ACCESSIBLE_STATE_VISITED: Indicates that a widget with the
+ * GTK_ACCESSIBLE_ROLE_LINK has been visited. Value type: boolean. Since: 4.12
  *
  * The possible accessible states of a [iface@Accessible].
  */
@@ -1431,7 +1433,8 @@ typedef enum {
   GTK_ACCESSIBLE_STATE_HIDDEN,
   GTK_ACCESSIBLE_STATE_INVALID,
   GTK_ACCESSIBLE_STATE_PRESSED,
-  GTK_ACCESSIBLE_STATE_SELECTED
+  GTK_ACCESSIBLE_STATE_SELECTED,
+  GTK_ACCESSIBLE_STATE_VISITED
 } GtkAccessibleState;
 
 /**