From 737854aa0d203de7bdab2b282a51691c9056dadc Mon Sep 17 00:00:00 2001 From: Federico Mena Quintero Date: Tue, 26 Apr 2022 13:43:19 -0500 Subject: [PATCH 1/4] Don't cast GtkWrapMode to the incompatible enum PangoWrapMode The enum values are not compatible, and moreover, there is an extra GTK_WRAP_NONE that PangoWrapMode doesn't have - thus, pango_wrap_mode_to_string() will assert. As far as I can tell, Orca does not read the wrap-mode key in the dictionary for text attributes, anyway. Fixes: #4869 --- gtk/a11y/gtkatspipango.c | 1 + gtk/a11y/gtkatspitextbuffer.c | 25 +++++++++++++++++++++++-- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/gtk/a11y/gtkatspipango.c b/gtk/a11y/gtkatspipango.c index 4db6a1a64b..b353027cc4 100644 --- a/gtk/a11y/gtkatspipango.c +++ b/gtk/a11y/gtkatspipango.c @@ -113,6 +113,7 @@ pango_underline_to_string (PangoUnderline value) const char * pango_wrap_mode_to_string (PangoWrapMode mode) { + /* Keep these in sync with gtk_wrap_mode_to_string() */ switch (mode) { case PANGO_WRAP_WORD: diff --git a/gtk/a11y/gtkatspitextbuffer.c b/gtk/a11y/gtkatspitextbuffer.c index 61e240fb0d..40fd05fa1f 100644 --- a/gtk/a11y/gtkatspitextbuffer.c +++ b/gtk/a11y/gtkatspitextbuffer.c @@ -55,6 +55,27 @@ gtk_text_direction_to_string (GtkTextDirection direction) } } +static const char * +gtk_wrap_mode_to_string (GtkWrapMode wrap_mode) +{ + /* Keep these in sync with pango_wrap_mode_to_string(); note that + * here we have an extra case for NONE. + */ + switch (wrap_mode) + { + case GTK_WRAP_NONE: + return "none"; + case GTK_WRAP_CHAR: + return "char"; + case GTK_WRAP_WORD: + return "word"; + case GTK_WRAP_WORD_CHAR: + return "word-char"; + default: + g_assert_not_reached (); + } +} + void gtk_text_view_add_default_attributes (GtkTextView *view, GVariantBuilder *builder) @@ -75,7 +96,7 @@ gtk_text_view_add_default_attributes (GtkTextView *view, g_variant_builder_add (builder, "{ss}", "direction", gtk_text_direction_to_string (text_attrs->direction)); g_variant_builder_add (builder, "{ss}", "wrap-mode", - pango_wrap_mode_to_string ((PangoWrapMode)text_attrs->wrap_mode)); + gtk_wrap_mode_to_string (text_attrs->wrap_mode)); g_variant_builder_add (builder, "{ss}", "editable", text_attrs->editable ? "true" : "false"); g_variant_builder_add (builder, "{ss}", "invisible", @@ -256,7 +277,7 @@ gtk_text_buffer_get_run_attributes (GtkTextBuffer *buffer, "wrap-mode", &wrap_mode, NULL); if (val_set) - g_variant_builder_add (builder, "{ss}", "wrap-mode", pango_wrap_mode_to_string ((PangoWrapMode)wrap_mode)); + g_variant_builder_add (builder, "{ss}", "wrap-mode", gtk_wrap_mode_to_string (wrap_mode)); temp_tags = temp_tags->next; } val_set = FALSE; From ae06e40bcc2ea43cf4a1ae3386a552b7f4150a4a Mon Sep 17 00:00:00 2001 From: Federico Mena Quintero Date: Tue, 26 Apr 2022 14:01:08 -0500 Subject: [PATCH 2/4] Put the text buffer tests in the internal_tests suite We'll start testing the internal gtk_text_buffer_get_run_attributes() soon. --- testsuite/gtk/meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testsuite/gtk/meson.build b/testsuite/gtk/meson.build index 3324664cac..fcf85ce509 100644 --- a/testsuite/gtk/meson.build +++ b/testsuite/gtk/meson.build @@ -76,7 +76,6 @@ tests = [ { 'name': 'spinbutton' }, { 'name': 'stringlist' }, { 'name': 'templates' }, - { 'name': 'textbuffer' }, { 'name': 'textiter' }, { 'name': 'theme-validate' }, { 'name': 'tooltips' }, @@ -119,6 +118,7 @@ internal_tests = [ { 'name': 'propertylookuplistmodel' }, { 'name': 'rbtree' }, { 'name': 'timsort' }, + { 'name': 'textbuffer' }, { 'name': 'texthistory' }, { 'name': 'fnmatch' }, ] From 898a2e9fcf7c6627ef17a881277733df7f5972e9 Mon Sep 17 00:00:00 2001 From: Federico Mena Quintero Date: Tue, 26 Apr 2022 14:41:34 -0500 Subject: [PATCH 3/4] textbuffer: Test the serialization of the wrap-mode attribute --- testsuite/gtk/textbuffer.c | 59 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/testsuite/gtk/textbuffer.c b/testsuite/gtk/textbuffer.c index 2dcb0b5fd7..833539cc35 100644 --- a/testsuite/gtk/textbuffer.c +++ b/testsuite/gtk/textbuffer.c @@ -22,6 +22,7 @@ #include #include "gtk/gtktexttypes.h" /* Private header, for UNKNOWN_CHAR */ +#include "gtk/a11y/gtkatspitextbufferprivate.h" /* Private header */ static void gtk_text_iter_spew (const GtkTextIter *iter, const char *desc) @@ -1818,6 +1819,63 @@ test_undo3 (void) g_object_unref (buffer); } +static void +test_serialize_wrap_mode (void) +{ + GtkTextBuffer *buffer = gtk_text_buffer_new (NULL); + struct val { + GtkWrapMode mode; + const char *name; + } values[] = { + { .mode = GTK_WRAP_NONE, .name = "none" }, + { .mode = GTK_WRAP_CHAR, .name = "char" }, + { .mode = GTK_WRAP_WORD, .name = "word" }, + { .mode = GTK_WRAP_WORD_CHAR, .name = "word-char" }, + }; + gsize i; + + /* Four lines, each with a 2-byte run (digit plus newline) */ + gtk_text_buffer_set_text (buffer, "0\n1\n2\n3\n", -1); + + for (i = 0; i < G_N_ELEMENTS (values); i++) + { + GtkTextTag *tag = gtk_text_buffer_create_tag (buffer, NULL, "wrap-mode", values[i].mode, NULL); + GtkTextIter start; + GtkTextIter end; + + gtk_text_buffer_get_iter_at_offset (buffer, &start, i * 2); + gtk_text_buffer_get_iter_at_offset (buffer, &end, (i + 1) * 2); + gtk_text_buffer_apply_tag (buffer, tag, &start, &end); + } + + /* Get the attributes for each line run as a GVariant */ + + for (i = 0; i < G_N_ELEMENTS (values); i++) + { + /* Each line has a { wrap-mode: name } run */ + GVariantBuilder expected_builder = G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE ("a{ss}")); + g_variant_builder_add (&expected_builder, "{ss}", "wrap-mode", values[i].name); + + GVariant *expected = g_variant_builder_end (&expected_builder); + + GVariantBuilder result_builder = G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE ("a{ss}")); + int run_start, run_end; + + gtk_text_buffer_get_run_attributes (buffer, &result_builder, 2 * i, &run_start, &run_end); + + GVariant *result = g_variant_builder_end (&result_builder); + + g_assert_cmpint (run_start, ==, 2 * i); + g_assert_cmpint (run_end, ==, 2 * (i + 1)); + g_assert_cmpvariant (result, expected); + + g_variant_unref (result); + g_variant_unref (expected); + } + + g_assert_finalize_object (buffer); +} + int main (int argc, char** argv) { @@ -1843,6 +1901,7 @@ main (int argc, char** argv) g_test_add_func ("/TextBuffer/Undo 1", test_undo1); g_test_add_func ("/TextBuffer/Undo 2", test_undo2); g_test_add_func ("/TextBuffer/Undo 3", test_undo3); + g_test_add_func ("/TextBuffer/Serialize wrap-mode", test_serialize_wrap_mode); return g_test_run(); } From 4ddf1b70a225d2c383145e257a084ea43fd60484 Mon Sep 17 00:00:00 2001 From: Federico Mena Quintero Date: Thu, 28 Apr 2022 09:46:20 -0500 Subject: [PATCH 4/4] Make the wrap_mode test unix-only The relevant accessibility code is not built on Windows. --- testsuite/gtk/textbuffer.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/testsuite/gtk/textbuffer.c b/testsuite/gtk/textbuffer.c index 833539cc35..d1c2997c4f 100644 --- a/testsuite/gtk/textbuffer.c +++ b/testsuite/gtk/textbuffer.c @@ -1876,6 +1876,15 @@ test_serialize_wrap_mode (void) g_assert_finalize_object (buffer); } +static void +add_unix_only_tests (void) +{ +#ifdef G_OS_UNIX + /* The atspi2 code for this is not available in Windows */ + g_test_add_func ("/TextBuffer/Serialize wrap-mode", test_serialize_wrap_mode); +#endif +} + int main (int argc, char** argv) { @@ -1901,7 +1910,8 @@ main (int argc, char** argv) g_test_add_func ("/TextBuffer/Undo 1", test_undo1); g_test_add_func ("/TextBuffer/Undo 2", test_undo2); g_test_add_func ("/TextBuffer/Undo 3", test_undo3); - g_test_add_func ("/TextBuffer/Serialize wrap-mode", test_serialize_wrap_mode); + + add_unix_only_tests (); return g_test_run(); }