Merge branch 'always-more-a11y-fixes' into 'main'

Add a comment about accessible naming

See merge request GNOME/gtk!6125
This commit is contained in:
Matthias Clasen 2023-06-20 17:13:51 +00:00
commit a9b8ad6181
7 changed files with 166 additions and 62 deletions

56
NEWS
View File

@ -1,6 +1,62 @@
Overview of Changes in 4.11.4, xx-xx-xxxx
=========================================
* GtkFileChooser:
- Default to sorting folders first
- Fix a crash when visiting recent files
* GtkTextView:
- Fix corner cases in word navigation
* GtkMenuButton:
- Normalize label layout
* GtkDropDown:
- Add support for sections
* GtkVideo:
- Make the overlay icon clickable
* GtkWindow:
- Clear the resize cursors to avoid artifacts
* Accessibility:
- Improvements all over the place: GtkButton, GtkPasswordEntry,
GtkFontChooserDialog, GtkColorChooserDialog, GtkShortcutsWindow,
GtkMenuButton, GtkAboutDialog, GtkFileChooserDialog, GtkStackSidebar,
GtkMediaControls, GtkColorDialogButton, GtkDropDown, GtkInfoBar,
GtkNotebook, GtkPrintUnixDialog, GtkModelButton
- Make name computation follow the ARIA spec more closely
- Change many containers to use `generic` instead of `group`
- Use `generic` as the default role
- Use `application` instead of `window` for windows
* X11:
- Fix regressions in GLX setup
* Windows:
- Center newly created transient windows
* Vulkan:
- Add antialising for gradients
- Do less work on clipped away nodes
- Redo image uploading
- Support different image depths and formats
* Demos:
- gtk4-demo: Improve window sizing
- gtk4-demo: Improve focus behavior
- gtk4-demo: Add many missing a11y properties
`
* Inspector:
- Show more information in the a11y tab
- Add an accessibility overlay
- Limit the width of the a11y tab
* Translation updates:
Czech
Overview of Changes in 4.11.3, 05-06-2023
=========================================

View File

@ -1010,7 +1010,12 @@ gtk_at_context_get_accessible_relation (GtkATContext *self,
/* See ARIA 5.2.8.4, 5.2.8.5 and 5.2.8.6 for the prohibited, from author
* and from content parts, and the table in
* https://www.w3.org/WAI/ARIA/apg/practices/names-and-descriptions/
* for the recommended / not recommended parts.
* for the recommended / not recommended parts. We've made a few changes
* to the recommendations:
* - We don't recommend against labelling listitems, sincd GtkListView
* will put the focus on listitems sometimes.
* - We don't recommend tab lists being labelled, since GtkNotebook does
* not have a practical way of doing that.
*/
#define NAME_FROM_AUTHOR (1 << 6)
@ -1316,7 +1321,7 @@ gtk_at_context_get_text_accumulate (GtkATContext *self,
{
if (GTK_IS_WIDGET (self->accessible))
{
gboolean has_child = FALSE;
GString *s = g_string_new ("");
for (GtkWidget *child = gtk_widget_get_first_child (GTK_WIDGET (self->accessible));
child != NULL;
@ -1325,13 +1330,17 @@ gtk_at_context_get_text_accumulate (GtkATContext *self,
GtkAccessible *rel = GTK_ACCESSIBLE (child);
GtkATContext *rel_context = gtk_accessible_get_at_context (rel);
gtk_at_context_get_text_accumulate (rel_context, nodes, res, property, relation, FALSE, TRUE);
has_child = TRUE;
gtk_at_context_get_text_accumulate (rel_context, nodes, s, property, relation, FALSE, TRUE);
}
if (has_child)
return;
if (s->len > 0)
{
g_string_append (res, s->str);
g_string_free (s, TRUE);
return;
}
g_string_free (s, TRUE);
}
}

View File

@ -689,11 +689,6 @@ gtk_menu_button_init (GtkMenuButton *self)
gtk_widget_set_sensitive (self->button, FALSE);
gtk_widget_add_css_class (GTK_WIDGET (self), "popup");
gtk_accessible_update_relation (GTK_ACCESSIBLE (self->button),
GTK_ACCESSIBLE_RELATION_LABELLED_BY, self, NULL,
GTK_ACCESSIBLE_RELATION_DESCRIBED_BY, self, NULL,
-1);
}
static GtkBuildableIface *parent_buildable_iface;
@ -1046,15 +1041,6 @@ gtk_menu_button_set_icon_name (GtkMenuButton *menu_button,
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
gtk_widget_set_halign (box, GTK_ALIGN_CENTER);
/* Because we are setting only an icon, let the inner button be labelled by us
* so the accessible label can be overridden from, for example, an UI file
* using GtkMenuButton as a child of something.
*/
gtk_accessible_update_relation (GTK_ACCESSIBLE (menu_button->button),
GTK_ACCESSIBLE_RELATION_LABELLED_BY, menu_button, NULL,
GTK_ACCESSIBLE_RELATION_DESCRIBED_BY, menu_button, NULL,
-1);
image_widget = g_object_new (GTK_TYPE_IMAGE,
"accessible-role", GTK_ACCESSIBLE_ROLE_PRESENTATION,
"icon-name", icon_name,
@ -1192,11 +1178,6 @@ gtk_menu_button_set_label (GtkMenuButton *menu_button,
gtk_button_set_child (GTK_BUTTON (menu_button->button), box);
menu_button->label_widget = label_widget;
gtk_accessible_update_relation (GTK_ACCESSIBLE (menu_button->button),
GTK_ACCESSIBLE_RELATION_LABELLED_BY, menu_button->label_widget, NULL,
GTK_ACCESSIBLE_RELATION_DESCRIBED_BY, menu_button->label_widget, NULL,
-1);
menu_button->image_widget = NULL;
menu_button->child = NULL;

View File

@ -2380,6 +2380,10 @@ gtk_widget_init (GTypeInstance *instance, gpointer g_class)
}
priv->at_context = create_at_context (widget);
gtk_accessible_update_state (GTK_ACCESSIBLE (widget),
GTK_ACCESSIBLE_STATE_HIDDEN, TRUE,
-1);
}
static void
@ -2708,10 +2712,6 @@ gtk_widget_show (GtkWidget *widget)
g_signal_emit (widget, widget_signals[SHOW], 0);
g_object_notify_by_pspec (G_OBJECT (widget), widget_props[PROP_VISIBLE]);
gtk_accessible_update_state (GTK_ACCESSIBLE (widget),
GTK_ACCESSIBLE_STATE_HIDDEN, FALSE,
-1);
gtk_widget_pop_verify_invariants (widget);
g_object_unref (widget);
}
@ -2775,10 +2775,6 @@ gtk_widget_hide (GtkWidget *widget)
g_signal_emit (widget, widget_signals[HIDE], 0);
g_object_notify_by_pspec (G_OBJECT (widget), widget_props[PROP_VISIBLE]);
gtk_accessible_update_state (GTK_ACCESSIBLE (widget),
GTK_ACCESSIBLE_STATE_HIDDEN, TRUE,
-1);
parent = gtk_widget_get_parent (widget);
if (parent)
gtk_widget_queue_resize (parent);
@ -2851,6 +2847,10 @@ gtk_widget_map (GtkWidget *widget)
gtk_widget_queue_draw (widget);
gtk_accessible_update_state (GTK_ACCESSIBLE (widget),
GTK_ACCESSIBLE_STATE_HIDDEN, FALSE,
-1);
gtk_widget_pop_verify_invariants (widget);
}
}
@ -2880,6 +2880,10 @@ gtk_widget_unmap (GtkWidget *widget)
update_cursor_on_state_change (widget);
gtk_accessible_update_state (GTK_ACCESSIBLE (widget),
GTK_ACCESSIBLE_STATE_HIDDEN, TRUE,
-1);
gtk_widget_pop_verify_invariants (widget);
g_object_unref (widget);
}

View File

@ -42,6 +42,26 @@ button_relation (void)
g_object_unref (button);
}
static void
button_state (void)
{
GtkWidget *button = gtk_button_new_with_mnemonic ("_Hello");
g_object_ref_sink (button);
gtk_test_accessible_assert_state (GTK_ACCESSIBLE (button),
GTK_ACCESSIBLE_STATE_HIDDEN, button, FALSE,
-1);
gtk_widget_set_visible (button, FALSE);
gtk_test_accessible_assert_state (GTK_ACCESSIBLE (button),
GTK_ACCESSIBLE_STATE_HIDDEN, button, TRUE,
-1);
g_object_unref (button);
}
static void
linkbutton_role (void)
{
@ -73,6 +93,7 @@ main (int argc, char *argv[])
g_test_add_func ("/a11y/button/role", button_role);
g_test_add_func ("/a11y/button/label", button_label);
g_test_add_func ("/a11y/button/relation", button_relation);
g_test_add_func ("/a11y/button/state", button_state);
g_test_add_func ("/a11y/linkbutton/role", linkbutton_role);
g_test_add_func ("/a11y/linkbutton/label", linkbutton_label);

View File

@ -8,18 +8,20 @@
static void
test_hidden (void)
{
GtkWidget *window;
GtkWidget *widget;
window = gtk_window_new ();
widget = gtk_button_new ();
g_object_ref_sink (widget);
gtk_test_accessible_assert_state (widget, GTK_ACCESSIBLE_STATE_HIDDEN, FALSE);
gtk_widget_set_visible (widget, FALSE);
gtk_window_set_child (GTK_WINDOW (window), widget);
gtk_test_accessible_assert_state (widget, GTK_ACCESSIBLE_STATE_HIDDEN, TRUE);
g_object_unref (widget);
gtk_window_present (GTK_WINDOW (window));
gtk_test_accessible_assert_state (widget, GTK_ACCESSIBLE_STATE_HIDDEN, FALSE);
gtk_window_destroy (GTK_WINDOW (window));
}
static void

View File

@ -5,7 +5,7 @@
static void
test_name_content (void)
{
GtkWidget *label1, *label2, *box, *button;
GtkWidget *window, *label1, *label2, *box, *button;
char *name;
label1 = gtk_label_new ("a");
@ -16,13 +16,10 @@ test_name_content (void)
gtk_box_append (GTK_BOX (box), label1);
gtk_box_append (GTK_BOX (box), label2);
gtk_button_set_child (GTK_BUTTON (button), box);
g_object_ref_sink (button);
/* gtk_at_context_get_name only works on realized contexts */
gtk_widget_realize_at_context (label1);
gtk_widget_realize_at_context (label2);
gtk_widget_realize_at_context (box);
gtk_widget_realize_at_context (button);
window = gtk_window_new ();
gtk_window_set_child (GTK_WINDOW (window), button);
gtk_window_present (GTK_WINDOW (window));
name = gtk_at_context_get_name (gtk_accessible_get_at_context (GTK_ACCESSIBLE (label1)));
g_assert_cmpstr (name, ==, "a");
@ -43,17 +40,20 @@ test_name_content (void)
g_assert_cmpstr (name, ==, "a");
g_free (name);
g_object_unref (button);
gtk_window_destroy (GTK_WINDOW (window));
}
static void
test_name_tooltip (void)
{
GtkWidget *image = gtk_image_new ();
GtkWidget *window, *image;
char *name;
g_object_ref_sink (image);
gtk_widget_realize_at_context (image);
image = gtk_image_new ();
window = gtk_window_new ();
gtk_window_set_child (GTK_WINDOW (window), image);
gtk_window_present (GTK_WINDOW (window));
gtk_widget_set_tooltip_text (image, "tooltip");
@ -61,16 +61,44 @@ test_name_tooltip (void)
g_assert_cmpstr (name, ==, "tooltip");
g_free (name);
g_object_unref (image);
gtk_window_destroy (GTK_WINDOW (window));
}
static void
test_name_menubutton (void)
{
GtkWidget *window, *widget;
char *name;
widget = gtk_menu_button_new ();
gtk_menu_button_set_popover (GTK_MENU_BUTTON (widget), gtk_popover_new ());
window = gtk_window_new ();
gtk_window_set_child (GTK_WINDOW (window), widget);
gtk_window_present (GTK_WINDOW (window));
gtk_widget_set_tooltip_text (widget, "tooltip");
name = gtk_at_context_get_name (gtk_accessible_get_at_context (GTK_ACCESSIBLE (widget)));
g_assert_cmpstr (name, ==, "tooltip");
g_free (name);
gtk_window_destroy (GTK_WINDOW (window));
}
static void
test_name_label (void)
{
GtkWidget *image = gtk_image_new ();
GtkWidget *window, *image;
char *name;
char *desc;
image = gtk_image_new ();
window = gtk_window_new ();
gtk_window_set_child (GTK_WINDOW (window), image);
gtk_window_present (GTK_WINDOW (window));
g_object_ref_sink (image);
gtk_widget_realize_at_context (image);
@ -89,13 +117,13 @@ test_name_label (void)
g_free (name);
g_free (desc);
g_object_unref (image);
gtk_window_destroy (GTK_WINDOW (window));
}
static void
test_name_prohibited (void)
{
GtkWidget *widget;
GtkWidget *window, *widget;
char *name;
char *desc;
@ -104,8 +132,9 @@ test_name_prohibited (void)
"label", "too late",
NULL);
g_object_ref_sink (widget);
gtk_widget_realize_at_context (widget);
window = gtk_window_new ();
gtk_window_set_child (GTK_WINDOW (window), widget);
gtk_window_present (GTK_WINDOW (window));
name = gtk_at_context_get_name (gtk_accessible_get_at_context (GTK_ACCESSIBLE (widget)));
desc = gtk_at_context_get_description (gtk_accessible_get_at_context (GTK_ACCESSIBLE (widget)));
@ -116,19 +145,20 @@ test_name_prohibited (void)
g_free (name);
g_free (desc);
g_object_unref (widget);
gtk_window_destroy (GTK_WINDOW (window));
}
static void
test_name_range (void)
{
GtkWidget *scale;
GtkWidget *window, *scale;
char *name;
scale = gtk_scale_new_with_range (GTK_ORIENTATION_HORIZONTAL, 0, 100, 10);
g_object_ref_sink (scale);
gtk_widget_realize_at_context (scale);
window = gtk_window_new ();
gtk_window_set_child (GTK_WINDOW (window), scale);
gtk_window_present (GTK_WINDOW (window));
g_assert_true (gtk_accessible_get_accessible_role (GTK_ACCESSIBLE (scale)) == GTK_ACCESSIBLE_ROLE_SLIDER);
g_assert_true (gtk_at_context_get_accessible_role (gtk_accessible_get_at_context (GTK_ACCESSIBLE (scale))) == GTK_ACCESSIBLE_ROLE_SLIDER);
@ -140,7 +170,7 @@ test_name_range (void)
g_free (name);
g_object_unref (scale);
gtk_window_destroy (GTK_WINDOW (window));
}
int
@ -150,6 +180,7 @@ main (int argc, char *argv[])
g_test_add_func ("/a11y/name/content", test_name_content);
g_test_add_func ("/a11y/name/tooltip", test_name_tooltip);
g_test_add_func ("/a11y/name/menubutton", test_name_menubutton);
g_test_add_func ("/a11y/name/label", test_name_label);
g_test_add_func ("/a11y/name/prohibited", test_name_prohibited);
g_test_add_func ("/a11y/name/range", test_name_range);