From 9517d3d13518489f647dccc6a870f04a8b028a0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Tyrychtr?= Date: Tue, 7 Mar 2023 11:20:53 +0100 Subject: [PATCH] a11y: Add GTK_ACCESSIBLE_STATE_VISITED 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 | 1 + gtk/a11y/gtkatspicontext.c | 19 +++++++++++++++++++ gtk/gtkaccessiblevalue.c | 14 ++++++++++---- gtk/gtkatcontext.c | 1 + gtk/gtkatcontextprivate.h | 3 ++- gtk/gtkenums.h | 5 ++++- 6 files changed, 37 insertions(+), 6 deletions(-) diff --git a/docs/reference/gtk/section-accessibility.md b/docs/reference/gtk/section-accessibility.md index 37c1f33388..71ccd417ee 100644 --- a/docs/reference/gtk/section-accessibility.md +++ b/docs/reference/gtk/section-accessibility.md @@ -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 diff --git a/gtk/a11y/gtkatspicontext.c b/gtk/a11y/gtkatspicontext.c index dca263902e..a3a8eacefc 100644 --- a/gtk/a11y/gtkatspicontext.c +++ b/gtk/a11y/gtkatspicontext.c @@ -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; diff --git a/gtk/gtkaccessiblevalue.c b/gtk/gtkaccessiblevalue.c index 6a9534bd8e..e5d7cc29da 100644 --- a/gtk/gtkaccessiblevalue.c +++ b/gtk/gtkaccessiblevalue.c @@ -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); } diff --git a/gtk/gtkatcontext.c b/gtk/gtkatcontext.c index 2ae924cc92..7db5c95fe7 100644 --- a/gtk/gtkatcontext.c +++ b/gtk/gtkatcontext.c @@ -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 > diff --git a/gtk/gtkatcontextprivate.h b/gtk/gtkatcontextprivate.h index e7ea717243..d9489fa3c9 100644 --- a/gtk/gtkatcontextprivate.h +++ b/gtk/gtkatcontextprivate.h @@ -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 diff --git a/gtk/gtkenums.h b/gtk/gtkenums.h index 679c75e447..af2f3689ca 100644 --- a/gtk/gtkenums.h +++ b/gtk/gtkenums.h @@ -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; /**