From 38fd66dc0477dace51fd181458166429566d1e98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Tyrychtr?= Date: Thu, 7 Mar 2024 11:39:51 +0100 Subject: [PATCH 1/8] a11y: Support setting the accessible help text This adds support for setting a string used to describe the operation of a control, if there's something special about it. This is mapped to the HelpText property in the AT-SPI2 backend, and has equivalent in others. --- gtk/a11y/gtkatspicontext.c | 17 +++++++++++++++++ gtk/gtkaccessiblevalue.c | 6 ++++++ gtk/gtkatcontext.c | 1 + gtk/gtkatcontextprivate.h | 3 ++- gtk/gtkenums.h | 6 +++++- 5 files changed, 31 insertions(+), 2 deletions(-) diff --git a/gtk/a11y/gtkatspicontext.c b/gtk/a11y/gtkatspicontext.c index b6557148b4..06e0290193 100644 --- a/gtk/a11y/gtkatspicontext.c +++ b/gtk/a11y/gtkatspicontext.c @@ -720,6 +720,16 @@ handle_accessible_get_property (GDBusConnection *connection, res = get_parent_context_ref (accessible); else if (g_strcmp0 (property_name, "ChildCount") == 0) res = g_variant_new_int32 (gtk_at_spi_context_get_child_count (self)); + else if (g_strcmp0 (property_name, "HelpText")) + { + if (gtk_at_context_has_accessible_property (GTK_AT_CONTEXT (self), GTK_ACCESSIBLE_PROPERTY_HELP_TEXT)) + { + GtkAccessibleValue *value = gtk_at_context_get_accessible_property (GTK_AT_CONTEXT (self), GTK_ACCESSIBLE_PROPERTY_HELP_TEXT); + res = g_variant_new_string (gtk_string_accessible_value_get (value)); + } + else + res = g_variant_new_string (""); + } else g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, "Unknown property '%s'", property_name); @@ -1167,6 +1177,13 @@ gtk_at_spi_context_state_change (GtkATContext *ctx, "accessible-value", g_variant_new_double (gtk_number_accessible_value_get (value))); } + if (changed_properties & GTK_ACCESSIBLE_PROPERTY_CHANGE_HELP_TEXT) + { + value = gtk_accessible_attribute_set_get_value (properties, GTK_ACCESSIBLE_PROPERTY_HELP_TEXT); + emit_property_changed (self, + "accessible-help-text", + g_variant_new_string (gtk_string_accessible_value_get (value))); + } } static void diff --git a/gtk/gtkaccessiblevalue.c b/gtk/gtkaccessiblevalue.c index 06e2bd8389..638f536f71 100644 --- a/gtk/gtkaccessiblevalue.c +++ b/gtk/gtkaccessiblevalue.c @@ -808,6 +808,11 @@ static const GtkAccessibleCollect collect_props[] = { .ctype = GTK_ACCESSIBLE_COLLECT_STRING, .name = "valuetext" }, + [GTK_ACCESSIBLE_PROPERTY_HELP_TEXT] = { + .value = GTK_ACCESSIBLE_PROPERTY_HELP_TEXT, + .ctype = GTK_ACCESSIBLE_COLLECT_STRING, + .name = "helptext" + }, }; /* § 6.6.4 Relationship Attributes */ @@ -1692,6 +1697,7 @@ gtk_accessible_value_get_default_for_property (GtkAccessibleProperty property) case GTK_ACCESSIBLE_PROPERTY_PLACEHOLDER: case GTK_ACCESSIBLE_PROPERTY_ROLE_DESCRIPTION: case GTK_ACCESSIBLE_PROPERTY_VALUE_TEXT: + case GTK_ACCESSIBLE_PROPERTY_HELP_TEXT: return gtk_undefined_accessible_value_new (); /* Token properties */ diff --git a/gtk/gtkatcontext.c b/gtk/gtkatcontext.c index d4e542c6d3..52730640e7 100644 --- a/gtk/gtkatcontext.c +++ b/gtk/gtkatcontext.c @@ -328,6 +328,7 @@ static const char *property_attrs[] = { [GTK_ACCESSIBLE_PROPERTY_VALUE_MIN] = "valuemin", [GTK_ACCESSIBLE_PROPERTY_VALUE_NOW] = "valuenow", [GTK_ACCESSIBLE_PROPERTY_VALUE_TEXT] = "valuetext", + [GTK_ACCESSIBLE_PROPERTY_HELP_TEXT] = "helptext", }; /*< private > diff --git a/gtk/gtkatcontextprivate.h b/gtk/gtkatcontextprivate.h index 189ce02335..d2e5a19eb5 100644 --- a/gtk/gtkatcontextprivate.h +++ b/gtk/gtkatcontextprivate.h @@ -47,7 +47,8 @@ typedef enum { 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 + GTK_ACCESSIBLE_PROPERTY_CHANGE_VALUE_TEXT = 1 << GTK_ACCESSIBLE_PROPERTY_VALUE_TEXT, + GTK_ACCESSIBLE_PROPERTY_CHANGE_HELP_TEXT = 1 << GTK_ACCESSIBLE_PROPERTY_HELP_TEXT, } GtkAccessiblePropertyChange; typedef enum { diff --git a/gtk/gtkenums.h b/gtk/gtkenums.h index 01a9aaec9a..74a8adc7f3 100644 --- a/gtk/gtkenums.h +++ b/gtk/gtkenums.h @@ -1629,6 +1629,9 @@ typedef enum { * Value type: double * @GTK_ACCESSIBLE_PROPERTY_VALUE_TEXT: Defines the human readable text alternative * of aria-valuenow for a range widget. Value type: string + * @GTK_ACCESSIBLE_PROPERTY_HELP_TEXT: Defines a string value that provides a + * description of non-standard keyboard interactions of the current element. Value type: string + * Since: 4.14 * * The possible accessible properties of a [iface@Accessible]. */ @@ -1651,7 +1654,8 @@ typedef enum { GTK_ACCESSIBLE_PROPERTY_VALUE_MAX, GTK_ACCESSIBLE_PROPERTY_VALUE_MIN, GTK_ACCESSIBLE_PROPERTY_VALUE_NOW, - GTK_ACCESSIBLE_PROPERTY_VALUE_TEXT + GTK_ACCESSIBLE_PROPERTY_VALUE_TEXT, + GTK_ACCESSIBLE_PROPERTY_HELP_TEXT } GtkAccessibleProperty; /** From 9bf23d80a1cdb9ac31a03277041f6863326ebc18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Tyrychtr?= Date: Thu, 7 Mar 2024 13:43:39 +0100 Subject: [PATCH 2/8] Test the new property and fix oversights found by the test --- gtk/gtkaccessiblevalue.c | 10 +++++----- gtk/gtkatcontext.c | 2 +- testsuite/a11y/accessible.c | 1 + 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/gtk/gtkaccessiblevalue.c b/gtk/gtkaccessiblevalue.c index 638f536f71..14e0b7ca0f 100644 --- a/gtk/gtkaccessiblevalue.c +++ b/gtk/gtkaccessiblevalue.c @@ -1667,7 +1667,7 @@ gtk_accessible_value_get_default_for_property (GtkAccessibleProperty property) { const GtkAccessibleCollect *cstate = &collect_props[property]; - g_return_val_if_fail (property <= GTK_ACCESSIBLE_PROPERTY_VALUE_TEXT, NULL); + g_return_val_if_fail (property <= GTK_ACCESSIBLE_PROPERTY_HELP_TEXT, NULL); switch (cstate->value) { @@ -1738,7 +1738,7 @@ gtk_accessible_value_collect_for_property (GtkAccessibleProperty property, { const GtkAccessibleCollect *cstate = &collect_props[property]; - g_return_val_if_fail (property <= GTK_ACCESSIBLE_PROPERTY_VALUE_TEXT, NULL); + g_return_val_if_fail (property <= GTK_ACCESSIBLE_PROPERTY_HELP_TEXT, NULL); return gtk_accessible_value_collect_valist (cstate, error, args); } @@ -1766,7 +1766,7 @@ gtk_accessible_value_collect_for_property_value (GtkAccessibleProperty propert { const GtkAccessibleCollect *cstate = &collect_props[property]; - g_return_val_if_fail (property <= GTK_ACCESSIBLE_PROPERTY_VALUE_TEXT, NULL); + g_return_val_if_fail (property <= GTK_ACCESSIBLE_PROPERTY_HELP_TEXT, NULL); return gtk_accessible_value_collect_value (cstate, value, error); } @@ -1779,7 +1779,7 @@ gtk_accessible_value_parse_for_property (GtkAccessibleProperty property, { const GtkAccessibleCollect *cstate = &collect_props[property]; - g_return_val_if_fail (property <= GTK_ACCESSIBLE_PROPERTY_VALUE_TEXT, NULL); + g_return_val_if_fail (property <= GTK_ACCESSIBLE_PROPERTY_HELP_TEXT, NULL); return gtk_accessible_value_parse (cstate, str, len, error); } @@ -1800,7 +1800,7 @@ gtk_accessible_property_init_value (GtkAccessibleProperty property, { const GtkAccessibleCollect *cstate = &collect_props[property]; - g_return_if_fail (property <= GTK_ACCESSIBLE_PROPERTY_VALUE_TEXT); + g_return_if_fail (property <= GTK_ACCESSIBLE_PROPERTY_HELP_TEXT); gtk_accessible_attribute_init_value (cstate, value); } diff --git a/gtk/gtkatcontext.c b/gtk/gtkatcontext.c index 52730640e7..21d54487e0 100644 --- a/gtk/gtkatcontext.c +++ b/gtk/gtkatcontext.c @@ -343,7 +343,7 @@ const char * gtk_accessible_property_get_attribute_name (GtkAccessibleProperty property) { g_return_val_if_fail (property >= GTK_ACCESSIBLE_PROPERTY_AUTOCOMPLETE && - property <= GTK_ACCESSIBLE_PROPERTY_VALUE_TEXT, + property <= GTK_ACCESSIBLE_PROPERTY_HELP_TEXT, ""); return property_attrs[property]; diff --git a/testsuite/a11y/accessible.c b/testsuite/a11y/accessible.c index 695221d565..b6580ca5e9 100644 --- a/testsuite/a11y/accessible.c +++ b/testsuite/a11y/accessible.c @@ -649,6 +649,7 @@ main (int argc, char *argv[]) g_test_add_data_func ("/a11y/property/value-min", GUINT_TO_POINTER (GTK_ACCESSIBLE_PROPERTY_VALUE_MIN), test_number_property); g_test_add_data_func ("/a11y/property/value-now", GUINT_TO_POINTER (GTK_ACCESSIBLE_PROPERTY_VALUE_NOW), test_number_property); g_test_add_data_func ("/a11y/property/value-text", GUINT_TO_POINTER (GTK_ACCESSIBLE_PROPERTY_VALUE_TEXT), test_string_property); + g_test_add_data_func ("/a11y/property/help-text", GUINT_TO_POINTER (GTK_ACCESSIBLE_PROPERTY_HELP_TEXT), test_string_property); g_test_add_func ("/a11y/property/update-multiple", test_update_multiple_properties); From bd43a9e86813f2f12ec233a325a9d3671fc8ea90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Tyrychtr?= Date: Thu, 7 Mar 2024 13:54:58 +0100 Subject: [PATCH 3/8] Document the new property --- docs/reference/gtk/section-accessibility.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/reference/gtk/section-accessibility.md b/docs/reference/gtk/section-accessibility.md index 03dcfba690..347d8cd42c 100644 --- a/docs/reference/gtk/section-accessibility.md +++ b/docs/reference/gtk/section-accessibility.md @@ -155,6 +155,7 @@ Each property name is part of the `GtkAccessibleProperty` enumeration. | %GTK_ACCESSIBLE_PROPERTY_VALUE_MIN | “aria-valuemin” | double | | %GTK_ACCESSIBLE_PROPERTY_VALUE_NOW | “aria-valuenow” | double | | %GTK_ACCESSIBLE_PROPERTY_VALUE_TEXT | “aria-valuetext” | translatable string | +| %GTK_ACCESSIBLE_PROPERTY_HELP_TEXT | N/A | translatable string | #### List of accessible relations @@ -216,6 +217,8 @@ are accessible as part of the development process. The GTK Inspector shows the accessible attributes of each widget, and also provides an overlay that can highlight accessibility issues. +If you support some non-standard keyboard interactions for a widget, you **should** set an appropriate `GTK_ACCESSIBLE_HELP_TEXT` to help discoverability of the behavior. + It is possible to set accessible attributes in UI files as well: ```xml From 0dcc21b6053ac58a10f1df54ec2eafa7d647d61c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Tyrychtr?= Date: Thu, 4 Apr 2024 14:03:35 +0200 Subject: [PATCH 4/8] 4.14 did not cut it --- gtk/gtkenums.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gtk/gtkenums.h b/gtk/gtkenums.h index 74a8adc7f3..81c5e0ac6d 100644 --- a/gtk/gtkenums.h +++ b/gtk/gtkenums.h @@ -1631,7 +1631,7 @@ typedef enum { * of aria-valuenow for a range widget. Value type: string * @GTK_ACCESSIBLE_PROPERTY_HELP_TEXT: Defines a string value that provides a * description of non-standard keyboard interactions of the current element. Value type: string - * Since: 4.14 + * Since: 4.16 * * The possible accessible properties of a [iface@Accessible]. */ From 7b145f72dc37e631d6c72b714580b2ffada829bb Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Fri, 5 Apr 2024 11:38:13 +0000 Subject: [PATCH 5/8] Apply review feedback fixes --- docs/reference/gtk/section-accessibility.md | 4 +++- gtk/a11y/gtkatspicontext.c | 8 +++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/docs/reference/gtk/section-accessibility.md b/docs/reference/gtk/section-accessibility.md index 347d8cd42c..83268ebdd2 100644 --- a/docs/reference/gtk/section-accessibility.md +++ b/docs/reference/gtk/section-accessibility.md @@ -217,7 +217,9 @@ are accessible as part of the development process. The GTK Inspector shows the accessible attributes of each widget, and also provides an overlay that can highlight accessibility issues. -If you support some non-standard keyboard interactions for a widget, you **should** set an appropriate `GTK_ACCESSIBLE_HELP_TEXT` to help discoverability of the behavior. +If you support some non-standard keyboard interactions for a widget, you +**should** set an appropriate `GTK_ACCESSIBLE_PROPERTY_HELP_TEXT` to help +discoverability of the behavior. It is possible to set accessible attributes in UI files as well: ```xml diff --git a/gtk/a11y/gtkatspicontext.c b/gtk/a11y/gtkatspicontext.c index 06e0290193..c5b05cbe4c 100644 --- a/gtk/a11y/gtkatspicontext.c +++ b/gtk/a11y/gtkatspicontext.c @@ -1183,7 +1183,13 @@ gtk_at_spi_context_state_change (GtkATContext *ctx, emit_property_changed (self, "accessible-help-text", g_variant_new_string (gtk_string_accessible_value_get (value))); - } + if (changed_properties & GTK_ACCESSIBLE_PROPERTY_CHANGE_HELP_TEXT) + { + value = gtk_accessible_attribute_set_get_value (properties, GTK_ACCESSIBLE_PROPERTY_HELP_TEXT); + emit_property_changed (self, + "accessible-help-text", + g_variant_new_string (gtk_string_accessible_value_get (value))); + } } static void From 91ff8bf33656a2dce1f761fb026cec60f9df93aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Tyrychtr?= Date: Fri, 5 Apr 2024 13:51:19 +0200 Subject: [PATCH 6/8] The new member needs a separate docblock --- gtk/gtkenums.h | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/gtk/gtkenums.h b/gtk/gtkenums.h index 81c5e0ac6d..b17b7c70bf 100644 --- a/gtk/gtkenums.h +++ b/gtk/gtkenums.h @@ -1629,12 +1629,18 @@ typedef enum { * Value type: double * @GTK_ACCESSIBLE_PROPERTY_VALUE_TEXT: Defines the human readable text alternative * of aria-valuenow for a range widget. Value type: string - * @GTK_ACCESSIBLE_PROPERTY_HELP_TEXT: Defines a string value that provides a - * description of non-standard keyboard interactions of the current element. Value type: string - * Since: 4.16 * * The possible accessible properties of a [iface@Accessible]. */ + +/** + * GTK_ACCESSIBLE_PROPERTY_HELP_TEXT: + * + * Defines a string value that provides a description of non-standard keyboard + * interactions of the current element. Value type: string + * + * Since: 4.16 + */ typedef enum { GTK_ACCESSIBLE_PROPERTY_AUTOCOMPLETE, GTK_ACCESSIBLE_PROPERTY_DESCRIPTION, From b0450d4b1bbb448fd44a12bfb1c6682500c6d4ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Tyrychtr?= Date: Tue, 23 Apr 2024 11:40:46 +0200 Subject: [PATCH 7/8] Do not perform a changed help-text check twice --- gtk/a11y/gtkatspicontext.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/gtk/a11y/gtkatspicontext.c b/gtk/a11y/gtkatspicontext.c index c5b05cbe4c..8babfdb364 100644 --- a/gtk/a11y/gtkatspicontext.c +++ b/gtk/a11y/gtkatspicontext.c @@ -1177,12 +1177,6 @@ gtk_at_spi_context_state_change (GtkATContext *ctx, "accessible-value", g_variant_new_double (gtk_number_accessible_value_get (value))); } - if (changed_properties & GTK_ACCESSIBLE_PROPERTY_CHANGE_HELP_TEXT) - { - value = gtk_accessible_attribute_set_get_value (properties, GTK_ACCESSIBLE_PROPERTY_HELP_TEXT); - emit_property_changed (self, - "accessible-help-text", - g_variant_new_string (gtk_string_accessible_value_get (value))); if (changed_properties & GTK_ACCESSIBLE_PROPERTY_CHANGE_HELP_TEXT) { value = gtk_accessible_attribute_set_get_value (properties, GTK_ACCESSIBLE_PROPERTY_HELP_TEXT); From f537a55b711a44afedc7c7c52ef2dea49671c4e2 Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Wed, 24 Apr 2024 11:48:52 +0100 Subject: [PATCH 8/8] Coding style fixes --- gtk/a11y/gtkatspicontext.c | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/gtk/a11y/gtkatspicontext.c b/gtk/a11y/gtkatspicontext.c index 8babfdb364..02d9a42282 100644 --- a/gtk/a11y/gtkatspicontext.c +++ b/gtk/a11y/gtkatspicontext.c @@ -721,15 +721,15 @@ handle_accessible_get_property (GDBusConnection *connection, else if (g_strcmp0 (property_name, "ChildCount") == 0) res = g_variant_new_int32 (gtk_at_spi_context_get_child_count (self)); else if (g_strcmp0 (property_name, "HelpText")) - { - if (gtk_at_context_has_accessible_property (GTK_AT_CONTEXT (self), GTK_ACCESSIBLE_PROPERTY_HELP_TEXT)) - { - GtkAccessibleValue *value = gtk_at_context_get_accessible_property (GTK_AT_CONTEXT (self), GTK_ACCESSIBLE_PROPERTY_HELP_TEXT); - res = g_variant_new_string (gtk_string_accessible_value_get (value)); - } - else - res = g_variant_new_string (""); - } + { + if (gtk_at_context_has_accessible_property (GTK_AT_CONTEXT (self), GTK_ACCESSIBLE_PROPERTY_HELP_TEXT)) + { + GtkAccessibleValue *value = gtk_at_context_get_accessible_property (GTK_AT_CONTEXT (self), GTK_ACCESSIBLE_PROPERTY_HELP_TEXT); + res = g_variant_new_string (gtk_string_accessible_value_get (value)); + } + else + res = g_variant_new_string (""); + } else g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, "Unknown property '%s'", property_name); @@ -1164,7 +1164,7 @@ gtk_at_spi_context_state_change (GtkATContext *ctx, } if (changed_properties & GTK_ACCESSIBLE_PROPERTY_CHANGE_DESCRIPTION) - { + { char *label = gtk_at_context_get_description (GTK_AT_CONTEXT (self)); GVariant *v = g_variant_new_take_string (label); emit_property_changed (self, "accessible-description", v); @@ -1177,13 +1177,14 @@ gtk_at_spi_context_state_change (GtkATContext *ctx, "accessible-value", g_variant_new_double (gtk_number_accessible_value_get (value))); } - if (changed_properties & GTK_ACCESSIBLE_PROPERTY_CHANGE_HELP_TEXT) - { - value = gtk_accessible_attribute_set_get_value (properties, GTK_ACCESSIBLE_PROPERTY_HELP_TEXT); - emit_property_changed (self, - "accessible-help-text", - g_variant_new_string (gtk_string_accessible_value_get (value))); - } + + if (changed_properties & GTK_ACCESSIBLE_PROPERTY_CHANGE_HELP_TEXT) + { + value = gtk_accessible_attribute_set_get_value (properties, GTK_ACCESSIBLE_PROPERTY_HELP_TEXT); + emit_property_changed (self, + "accessible-help-text", + g_variant_new_string (gtk_string_accessible_value_get (value))); + } } static void