diff --git a/NEWS b/NEWS index 7f9ae2ed7d..d5c011576f 100644 --- a/NEWS +++ b/NEWS @@ -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 ========================================= diff --git a/gtk/gtkatcontext.c b/gtk/gtkatcontext.c index 42f0c2717e..4d86184644 100644 --- a/gtk/gtkatcontext.c +++ b/gtk/gtkatcontext.c @@ -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); } } diff --git a/gtk/gtkmenubutton.c b/gtk/gtkmenubutton.c index 59fb9394e5..e162470cf9 100644 --- a/gtk/gtkmenubutton.c +++ b/gtk/gtkmenubutton.c @@ -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; diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c index 4f0b1f0be9..e8225cdbbf 100644 --- a/gtk/gtkwidget.c +++ b/gtk/gtkwidget.c @@ -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); } diff --git a/testsuite/a11y/button.c b/testsuite/a11y/button.c index b32682f755..7e79dc00e8 100644 --- a/testsuite/a11y/button.c +++ b/testsuite/a11y/button.c @@ -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); diff --git a/testsuite/a11y/general.c b/testsuite/a11y/general.c index 006023919d..78c7c55a54 100644 --- a/testsuite/a11y/general.c +++ b/testsuite/a11y/general.c @@ -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 diff --git a/testsuite/a11y/names.c b/testsuite/a11y/names.c index 4a76b03420..2eba20edea 100644 --- a/testsuite/a11y/names.c +++ b/testsuite/a11y/names.c @@ -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);