diff options
author | Matthias Clasen <mclasen@redhat.com> | 2020-11-02 11:52:13 +0000 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2020-11-02 11:52:13 +0000 |
commit | efc314196d639a6216add81b440495a556f2183e (patch) | |
tree | c39976ca1d9e65c27685a07e4a9c6dec16ca3e40 | |
parent | 924796b47866de28b4288521153398daf6339993 (diff) | |
parent | 403a70ca89d9666c4eff1554455eb4e22b120dbf (diff) | |
download | gtk+-efc314196d639a6216add81b440495a556f2183e.tar.gz |
Merge branch 'matthiasc/for-master' into 'master'
Matthiasc/for master
See merge request GNOME/gtk!2769
87 files changed, 1548 insertions, 381 deletions
@@ -9,21 +9,53 @@ Overview of Changes in master * GtkSearchEntry: - Add an icon +* GtkDropDown: + - Polish the appearance + +* GtkColorChooser: + - Accessibility improvements + +* GtkPopoverMenu: + - Add accessibility support + - Allow custom items. This adds new API: + gtk_popover_menu_add/remove_child + gtk_popover_menu_bar_add/remove_child + +* GtkTextView: + - Fix rendering and positioning of anchored children + +* Media support: + - Use cubic instead of linear volume + * Accessibility: - Implement Component for all widgets - Implement Text and EditableText for all editables - Rework accessible name/description computation - Add documentation for app and widget developers - - Initial accessibility support for menus + - Handle HIDDEN state changes by adding/removing elements + - Support setting accessibility attributes in ui files * Introspection: - Add some missing annotations +* gdk: + - Deliver events on flush + - Drop the unused GdkPoint struct from the API + * Documentation: - Use GtkApplication in all examples + - Improve and expand the widget gallery + +* Build: + - Fix the build with cups 2.2.12 + - Make cloudprint support build without warnings * OS X: - Fix various input issues + - Make GtkGLArea work (with the cairo backend) + +* Translation updates: + Polish Overview of Changes in 3.99.3 diff --git a/config.h.meson b/config.h.meson index 1968bb9cbe..549a677379 100644 --- a/config.h.meson +++ b/config.h.meson @@ -1,8 +1,9 @@ -/* config.h.in. Generated from configure.ac by autoheader. */ - /* always defined to indicate that i18n is enabled */ #define ENABLE_NLS 1 +/* Use structured logging */ +#define G_LOG_STRUCTURED 1 + /* The prefix for our gettext translation domains. */ #mesondefine GETTEXT_PACKAGE diff --git a/demos/gtk-demo/constraints.c b/demos/gtk-demo/constraints.c index 2e31f22462..2104948ad5 100644 --- a/demos/gtk-demo/constraints.c +++ b/demos/gtk-demo/constraints.c @@ -2,8 +2,15 @@ * #Keywords: GtkLayoutManager * * GtkConstraintLayout provides a layout manager that uses relations - * between widgets (also known as "constraints") to compute the position + * between widgets (also known as “constraints”) to compute the position * and size of each child. + * + * In addition to child widgets, the constraints can involve spacer + * objects (also known as “guides”). This example has a guide between + * the two buttons in the top row. + * + * Try resizing the window to see how the constraints react to update + * the layout. */ #include <glib/gi18n.h> @@ -234,15 +241,12 @@ simple_grid_init (SimpleGrid *self) self->button1 = gtk_button_new_with_label ("Child 1"); gtk_widget_set_parent (self->button1, widget); - gtk_widget_set_name (self->button1, "button1"); self->button2 = gtk_button_new_with_label ("Child 2"); gtk_widget_set_parent (self->button2, widget); - gtk_widget_set_name (self->button2, "button2"); self->button3 = gtk_button_new_with_label ("Child 3"); gtk_widget_set_parent (self->button3, widget); - gtk_widget_set_name (self->button3, "button3"); GtkLayoutManager *manager = gtk_widget_get_layout_manager (GTK_WIDGET (self)); build_constraints (self, GTK_CONSTRAINT_LAYOUT (manager)); diff --git a/demos/gtk-demo/constraints.ui b/demos/gtk-demo/constraints.ui new file mode 100644 index 0000000000..5011caf7a5 --- /dev/null +++ b/demos/gtk-demo/constraints.ui @@ -0,0 +1,105 @@ +<?xml version="1.0" encoding="UTF-8"?> +<interface> + <object class="GtkWindow" id="window1"> + <property name="title" translatable="yes">Constraints</property> + <child> + <object class="ConstraintsGrid"> + <property name="layout-manager"> + <object class="GtkConstraintLayout"> + <constraints> + <guide name="space" + min-width="10" min-height="10" + nat-width="100" nat-height="10" + max-width="200" max-height="20" + strength="strong"/> + <constraint target="button1" target-attribute="width" + relation="le" + constant="200" + strength="required"/> + <constraint target="super" target-attribute="start" + relation="eq" + source="button1" source-attribute="start" + constant="-8" + strength="required"/> + <constraint target="button1" target-attribute="width" + relation="eq" + source="button2" source-attribute="width" + strength="required"/> + <constraint target="button1" target-attribute="end" + relation="eq" + source="space" source-attribute="start" + strength="required"/> + <constraint target="space" target-attribute="end" + relation="eq" + source="button2" source-attribute="start" + strength="required"/> + <constraint target="super" target-attribute="end" + relation="eq" + source="button2" source-attribute="end" + constant="8" + strength="required"/> + <constraint target="super" target-attribute="start" + relation="eq" + source="button3" source-attribute="start" + constant="-8" + strength="required"/> + <constraint target="super" target-attribute="end" + relation="eq" + source="button3" source-attribute="end" + constant="8" + strength="required"/> + <constraint target="super" target-attribute="top" + relation="eq" + source="button1" source-attribute="top" + constant="-8" + strength="required"/> + <constraint target="super" target-attribute="top" + relation="eq" + source="button2" source-attribute="top" + constant="-8" + strength="required"/> + <constraint target="button1" target-attribute="bottom" + relation="eq" + source="button3" source-attribute="top" + constant="-12" + strength="required"/> + <constraint target="button2" target-attribute="bottom" + relation="eq" + source="button3" source-attribute="top" + constant="-12" + strength="required"/> + <constraint target="button3" target-attribute="height" + relation="eq" + source="button1" source-attribute="height" + strength="required"/> + <constraint target="button3" target-attribute="height" + relation="eq" + source="button2" source-attribute="height" + strength="required"/> + <constraint target="super" target-attribute="bottom" + relation="eq" + source="button3" source-attribute="bottom" + constant="8" + strength="required"/> + </constraints> + </object> + </property> + <child> + <object class="GtkButton" id="button1"> + <property name="label">Child 1</property> + </object> + </child> + <child> + <object class="GtkButton" id="button2"> + <property name="label">Child 2</property> + </object> + </child> + <child> + <object class="GtkButton" id="button3"> + <property name="label">Child 3</property> + </object> + </child> + </object> + </child> + </object> +</interface> diff --git a/demos/gtk-demo/constraints2.c b/demos/gtk-demo/constraints2.c index d63b369739..124a5e18ef 100644 --- a/demos/gtk-demo/constraints2.c +++ b/demos/gtk-demo/constraints2.c @@ -1,7 +1,7 @@ /* Constraints/Interactive * #Keywords: GtkConstraintLayout * - * Demonstrate how constraints can be updates during user interaction. + * This example shows how constraints can be updated during user interaction. * The vertical edge between the buttons can be dragged with the mouse. */ diff --git a/demos/gtk-demo/constraints3.c b/demos/gtk-demo/constraints3.c index 0cb9b97702..d702f75430 100644 --- a/demos/gtk-demo/constraints3.c +++ b/demos/gtk-demo/constraints3.c @@ -2,6 +2,10 @@ * * GtkConstraintLayout allows defining constraints using a * compact syntax called Visual Format Language, or VFL. + * + * A typical example of a VFL specification looks like this: + * + * H:|-[button1(==button2)]-12-[button2]-| */ #include <glib/gi18n.h> diff --git a/demos/gtk-demo/constraints4.c b/demos/gtk-demo/constraints4.c new file mode 100644 index 0000000000..4b4ca49643 --- /dev/null +++ b/demos/gtk-demo/constraints4.c @@ -0,0 +1,72 @@ +/* Constraints/Builder + * + * GtkConstraintLayouts can be created in .ui files, and constraints can be + * set up at that time as well, as this example demonstrates. It uses the + * same setup as the “Simple” constraints demo. + */ + +#include <glib/gi18n.h> +#include <gtk/gtk.h> + +G_DECLARE_FINAL_TYPE (ConstraintsGrid, constraints_grid, CONSTRAINTS, GRID, GtkWidget) + +struct _ConstraintsGrid +{ + GtkWidget parent_instance; +}; + +G_DEFINE_TYPE (ConstraintsGrid, constraints_grid, GTK_TYPE_WIDGET) + +static void +constraints_grid_init (ConstraintsGrid *grid) +{ +} + +static void +constraints_grid_dispose (GObject *object) +{ + GtkWidget *widget = GTK_WIDGET (object); + GtkWidget *child; + + while ((child = gtk_widget_get_first_child (widget))) + gtk_widget_unparent (child); + + G_OBJECT_CLASS (constraints_grid_parent_class)->dispose (object); +} + +static void +constraints_grid_class_init (ConstraintsGridClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->dispose = constraints_grid_dispose; +} + +GtkWidget * +do_constraints4 (GtkWidget *do_widget) +{ + static GtkWidget *window; + + if (!window) + { + GtkBuilder *builder; + + g_type_ensure (constraints_grid_get_type ()); + + builder = gtk_builder_new_from_resource ("/constraints4/constraints.ui"); + + window = GTK_WIDGET (gtk_builder_get_object (builder, "window1")); + gtk_window_set_display (GTK_WINDOW (window), + gtk_widget_get_display (do_widget)); + g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window); + + g_object_unref (builder); + } + + if (!gtk_widget_get_visible (window)) + gtk_widget_show (window); + else + gtk_window_destroy (GTK_WINDOW (window)); + + return window; +} diff --git a/demos/gtk-demo/demo.gresource.xml b/demos/gtk-demo/demo.gresource.xml index bcb2ebc3b5..89d88edaa3 100644 --- a/demos/gtk-demo/demo.gresource.xml +++ b/demos/gtk-demo/demo.gresource.xml @@ -18,6 +18,9 @@ <file>demoimage.c</file> <file>demoimage.h</file> </gresource> + <gresource prefix="/constraints4"> + <file>constraints.ui</file> + </gresource> <gresource prefix="/css_accordion"> <file>css_accordion.css</file> <file>reset.css</file> @@ -242,6 +245,7 @@ <file>constraints.c</file> <file>constraints2.c</file> <file>constraints3.c</file> + <file>constraints4.c</file> <file>css_accordion.c</file> <file>css_basics.c</file> <file>css_blendmodes.c</file> diff --git a/demos/gtk-demo/meson.build b/demos/gtk-demo/meson.build index 2d1efc4170..39070bb925 100644 --- a/demos/gtk-demo/meson.build +++ b/demos/gtk-demo/meson.build @@ -9,6 +9,7 @@ demos = files([ 'constraints.c', 'constraints2.c', 'constraints3.c', + 'constraints4.c', 'css_accordion.c', 'css_basics.c', 'css_blendmodes.c', diff --git a/gsk/gskrenderer.c b/gsk/gskrenderer.c index 8ec0e0d36a..dbbfd28f35 100644 --- a/gsk/gskrenderer.c +++ b/gsk/gskrenderer.c @@ -606,7 +606,11 @@ static struct { * * Creates an appropriate #GskRenderer instance for the given @surface. * - * The renderer will be realized when it is returned. + * If the `GSK_RENDERER` environment variable is set, GSK will + * try that renderer first, before trying the backend-specific + * default. The ultimate fallback is the cairo renderer. + * + * The renderer will be realized before it is returned. * * Returns: (transfer full) (nullable): a #GskRenderer */ diff --git a/gsk/meson.build b/gsk/meson.build index e71ac50c78..4ea6091a94 100644 --- a/gsk/meson.build +++ b/gsk/meson.build @@ -40,11 +40,9 @@ gsk_private_sources = files([ 'gl/gskglshaderbuilder.c', 'gl/gskglprofiler.c', 'gl/gskglglyphcache.c', - 'gl/gskglimage.c', 'gl/gskgldriver.c', 'gl/gskglrenderops.c', 'gl/gskglshadowcache.c', - 'gl/gskglnodesample.c', 'gl/gskgltextureatlas.c', 'gl/gskgliconcache.c', 'gl/opbuffer.c', diff --git a/gtk/css/gtkcsstokenizer.c b/gtk/css/gtkcsstokenizer.c index 607c4d6992..203d7f3a45 100644 --- a/gtk/css/gtkcsstokenizer.c +++ b/gtk/css/gtkcsstokenizer.c @@ -1349,7 +1349,7 @@ gtk_css_tokenizer_read_token (GtkCssTokenizer *tokenizer, tokenizer->data[3] == '-') { gtk_css_token_init (token, GTK_CSS_TOKEN_CDO); - gtk_css_tokenizer_consume (tokenizer, 3, 3); + gtk_css_tokenizer_consume (tokenizer, 4, 4); } else { diff --git a/gtk/css/meson.build b/gtk/css/meson.build index 6b24561928..501411f917 100644 --- a/gtk/css/meson.build +++ b/gtk/css/meson.build @@ -47,7 +47,6 @@ libgtk_css = static_library('gtk_css', c_args: [ '-DGTK_COMPILATION', '-DG_LOG_DOMAIN="Gtk"', - '-DG_LOG_STRUCTURED=1', ] + common_cflags, link_args: common_ldflags) diff --git a/gtk/gtkbuildable.c b/gtk/gtkbuildable.c index 659a0ff3bd..2adc747d44 100644 --- a/gtk/gtkbuildable.c +++ b/gtk/gtkbuildable.c @@ -131,35 +131,6 @@ gtk_buildable_add_child (GtkBuildable *buildable, } /*< private > - * gtk_buildable_set_buildable_property: - * @buildable: a #GtkBuildable - * @builder: a #GtkBuilder - * @name: name of property - * @value: value of property - * - * Sets the property name @name to @value on the @buildable object. - */ -void -gtk_buildable_set_buildable_property (GtkBuildable *buildable, - GtkBuilder *builder, - const char *name, - const GValue *value) -{ - GtkBuildableIface *iface; - - g_return_if_fail (GTK_IS_BUILDABLE (buildable)); - g_return_if_fail (GTK_IS_BUILDER (builder)); - g_return_if_fail (name != NULL); - g_return_if_fail (value != NULL); - - iface = GTK_BUILDABLE_GET_IFACE (buildable); - if (iface->set_buildable_property) - (* iface->set_buildable_property) (buildable, builder, name, value); - else - g_object_set_property (G_OBJECT (buildable), name, value); -} - -/*< private > * gtk_buildable_parser_finished: * @buildable: a #GtkBuildable * @builder: a #GtkBuilder diff --git a/gtk/gtkbuildableprivate.h b/gtk/gtkbuildableprivate.h index 305be21898..90d447a995 100644 --- a/gtk/gtkbuildableprivate.h +++ b/gtk/gtkbuildableprivate.h @@ -11,10 +11,6 @@ void gtk_buildable_add_child (GtkBuildable *buildable, GtkBuilder *builder, GObject *child, const char *type); -void gtk_buildable_set_buildable_property (GtkBuildable *buildable, - GtkBuilder *builder, - const char *name, - const GValue *value); GObject * gtk_buildable_construct_child (GtkBuildable *buildable, GtkBuilder *builder, const char *name); diff --git a/gtk/gtkconstraintlayout.c b/gtk/gtkconstraintlayout.c index 6b88ecf57a..e5d6037962 100644 --- a/gtk/gtkconstraintlayout.c +++ b/gtk/gtkconstraintlayout.c @@ -103,6 +103,8 @@ * The "source" and "target" attributes can be set to "super" to indicate * that the constraint target is the widget using the GtkConstraintLayout. * + * There can be "constant" and "multiplier" attributes. + * * Additionally, the "constraints" element can also contain a description * of the #GtkConstraintGuides used by the layout: * @@ -1327,6 +1329,7 @@ parse_int (const char *string, static GtkConstraint * constraint_data_to_constraint (const ConstraintData *data, GtkBuilder *builder, + GHashTable *guides, GError **error) { gpointer source, target; @@ -1350,13 +1353,30 @@ constraint_data_to_constraint (const ConstraintData *data, source = NULL; } else - source = gtk_builder_get_object (builder, data->source_name); + { + if (g_hash_table_contains (guides, data->source_name)) + source = g_hash_table_lookup (guides, data->source_name); + else + source = gtk_builder_get_object (builder, data->source_name); + + if (source == NULL) + { + g_set_error (error, GTK_BUILDER_ERROR, + GTK_BUILDER_ERROR_INVALID_VALUE, + "Unable to find source '%s' for constraint", + data->source_name); + return NULL; + } + } if (g_strcmp0 (data->target_name, "super") == 0) target = NULL; else { - target = gtk_builder_get_object (builder, data->target_name); + if (g_hash_table_contains (guides, data->target_name)) + target = g_hash_table_lookup (guides, data->target_name); + else + target = gtk_builder_get_object (builder, data->target_name); if (target == NULL) { @@ -1623,6 +1643,9 @@ gtk_constraint_layout_custom_finished (GtkBuildable *buildable, if (strcmp (element_name, "constraints") == 0) { GList *l; + GHashTable *guides; + + guides = g_hash_table_new (g_str_hash, g_str_equal); data->guides = g_list_reverse (data->guides); for (l = data->guides; l != NULL; l = l->next) @@ -1630,16 +1653,25 @@ gtk_constraint_layout_custom_finished (GtkBuildable *buildable, const GuideData *gdata = l->data; GtkConstraintGuide *g; GError *error = NULL; + const char *name; g = guide_data_to_guide (gdata, builder, &error); if (error != NULL) { - g_critical ("Unable to parse guide definition: %s", - error->message); + g_critical ("Unable to parse guide definition: %s", error->message); g_error_free (error); continue; } + name = gtk_constraint_guide_get_name (g); + if (g_hash_table_lookup (guides, name)) + { + g_critical ("Duplicate guide: %s", name); + g_object_unref (g); + continue; + } + + g_hash_table_insert (guides, (gpointer)name, g); gtk_constraint_layout_add_guide (data->layout, g); } @@ -1650,7 +1682,7 @@ gtk_constraint_layout_custom_finished (GtkBuildable *buildable, GtkConstraint *c; GError *error = NULL; - c = constraint_data_to_constraint (cdata, builder, &error); + c = constraint_data_to_constraint (cdata, builder, guides, &error); if (error != NULL) { g_critical ("Unable to parse constraint definition '%s.%s [%s] %s.%s * %g + %g': %s", @@ -1664,13 +1696,20 @@ gtk_constraint_layout_custom_finished (GtkBuildable *buildable, continue; } - gtk_constraint_layout_add_constraint (data->layout, c); + layout_add_constraint (data->layout, c); + g_hash_table_add (data->layout->constraints, c); + if (data->layout->constraints_observer) + g_list_store_append (data->layout->constraints_observer, c); } + gtk_layout_manager_layout_changed (GTK_LAYOUT_MANAGER (data->layout)); + g_list_free_full (data->constraints, constraint_data_free); g_list_free_full (data->guides, guide_data_free); g_object_unref (data->layout); g_free (data); + + g_hash_table_unref (guides); } } @@ -1828,7 +1867,10 @@ gtk_constraint_layout_add_guide (GtkConstraintLayout *layout, if (layout->guides_observer) g_list_store_append (layout->guides_observer, guide); + gtk_constraint_guide_update (guide); + gtk_layout_manager_layout_changed (GTK_LAYOUT_MANAGER (layout)); + } /** diff --git a/gtk/gtkexpression.c b/gtk/gtkexpression.c index f7c25f9c73..0974face66 100644 --- a/gtk/gtkexpression.c +++ b/gtk/gtkexpression.c @@ -1283,13 +1283,13 @@ gtk_property_expression_new (GType this_type, { GParamSpec *pspec; - if (g_type_is_a (this_type, G_TYPE_OBJECT)) + if (g_type_fundamental (this_type) == G_TYPE_OBJECT) { GObjectClass *class = g_type_class_ref (this_type); pspec = g_object_class_find_property (class, property_name); g_type_class_unref (class); } - else if (g_type_is_a (this_type, G_TYPE_INTERFACE)) + else if (g_type_fundamental (this_type) == G_TYPE_INTERFACE) { GTypeInterface *iface = g_type_default_interface_ref (this_type); pspec = g_object_interface_find_property (iface, property_name); diff --git a/gtk/gtkhsla.c b/gtk/gtkhsla.c index 9692e3e59f..ad1298df70 100644 --- a/gtk/gtkhsla.c +++ b/gtk/gtkhsla.c @@ -22,24 +22,6 @@ #include <math.h> void -_gtk_hsla_init (GtkHSLA *hsla, - float hue, - float saturation, - float lightness, - float alpha) -{ - g_return_if_fail (hsla != NULL); - - if (hue >= 0) - hsla->hue = fmod (hue, 360); - else - hsla->hue = fmod (hue, 360) + 360; - hsla->saturation = CLAMP (saturation, 0, 1); - hsla->lightness = CLAMP (lightness, 0, 1); - hsla->alpha = CLAMP (alpha, 0, 1); -} - -void _gtk_hsla_init_from_rgba (GtkHSLA *hsla, const GdkRGBA *rgba) { diff --git a/gtk/gtkhslaprivate.h b/gtk/gtkhslaprivate.h index 145daf7461..304dcfb899 100644 --- a/gtk/gtkhslaprivate.h +++ b/gtk/gtkhslaprivate.h @@ -31,11 +31,6 @@ struct _GtkHSLA { float alpha; }; -void _gtk_hsla_init (GtkHSLA *hsla, - float hue, - float saturation, - float lightness, - float alpha); void _gtk_hsla_init_from_rgba (GtkHSLA *hsla, const GdkRGBA *rgba); /* Yes, I can name that function like this! */ diff --git a/gtk/gtkrender.c b/gtk/gtkrender.c index 4abb9fbc0e..a094604d7a 100644 --- a/gtk/gtkrender.c +++ b/gtk/gtkrender.c @@ -27,7 +27,6 @@ #include "gtkcsscolorvalueprivate.h" #include "gtkcssshadowvalueprivate.h" #include "gtkcsstransformvalueprivate.h" -#include "gtkhslaprivate.h" #include "gtkrendericonprivate.h" #include "gtkstylecontextprivate.h" diff --git a/gtk/gtksettings.c b/gtk/gtksettings.c index a428de2f95..6345550a73 100644 --- a/gtk/gtksettings.c +++ b/gtk/gtksettings.c @@ -21,7 +21,6 @@ #include "gtksettingsprivate.h" #include "gtkcssproviderprivate.h" -#include "gtkhslaprivate.h" #include "gtkintl.h" #include "gtkprivate.h" #include "gtkscrolledwindow.h" diff --git a/gtk/gtkstringlist.c b/gtk/gtkstringlist.c index 5c04301c70..18474b013e 100644 --- a/gtk/gtkstringlist.c +++ b/gtk/gtkstringlist.c @@ -95,27 +95,6 @@ gtk_string_object_finalize (GObject *object) } static void -gtk_string_object_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - GtkStringObject *self = GTK_STRING_OBJECT (object); - - switch (property_id) - { - case PROP_STRING: - g_free (self->string); - self->string = g_value_dup_string (value); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void gtk_string_object_get_property (GObject *object, guint property_id, GValue *value, @@ -142,7 +121,6 @@ gtk_string_object_class_init (GtkStringObjectClass *class) GParamSpec *pspec; object_class->finalize = gtk_string_object_finalize; - object_class->set_property = gtk_string_object_set_property; object_class->get_property = gtk_string_object_get_property; pspec = g_param_spec_string ("string", "String", "String", diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c index f9bc34a969..31c0063022 100644 --- a/gtk/gtkwidget.c +++ b/gtk/gtkwidget.c @@ -1013,7 +1013,7 @@ gtk_widget_class_init (GtkWidgetClass *klass) g_param_spec_boolean ("can-target", P_("Can target"), P_("Whether the widget can receive pointer events"), - FALSE, + TRUE, GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY); /** diff --git a/gtk/tools/gtk-builder-tool-simplify.c b/gtk/tools/gtk-builder-tool-simplify.c index f2f57d8eab..d40556b0cb 100644 --- a/gtk/tools/gtk-builder-tool-simplify.c +++ b/gtk/tools/gtk-builder-tool-simplify.c @@ -212,59 +212,6 @@ needs_explicit_setting (GParamSpec *pspec, } static gboolean -keep_for_rewrite (const char *class_name, - const char *property_name, - PropKind kind) -{ - struct _Prop { - const char *class; - const char *property; - PropKind kind; - } props[] = { - { "GtkPopover", "modal", PROP_KIND_OBJECT }, - { "GtkActionBar", "pack-type", PROP_KIND_PACKING }, - { "GtkHeaderBar", "pack-type", PROP_KIND_PACKING }, - { "GtkPopoverMenu", "submenu", PROP_KIND_PACKING }, - { "GtkToolbar", "expand", PROP_KIND_PACKING }, - { "GtkToolbar", "homogeneous", PROP_KIND_PACKING }, - { "GtkPaned", "resize", PROP_KIND_PACKING }, - { "GtkPaned", "shrink", PROP_KIND_PACKING }, - { "GtkOverlay", "measure", PROP_KIND_PACKING }, - { "GtkOverlay", "clip-overlay", PROP_KIND_PACKING }, - { "GtkGrid", "column", PROP_KIND_PACKING }, - { "GtkGrid", "row", PROP_KIND_PACKING }, - { "GtkGrid", "width", PROP_KIND_PACKING }, - { "GtkGrid", "height", PROP_KIND_PACKING }, - { "GtkStack", "name", PROP_KIND_PACKING }, - { "GtkStack", "title", PROP_KIND_PACKING }, - { "GtkStack", "icon-name", PROP_KIND_PACKING }, - { "GtkStack", "needs-attention", PROP_KIND_PACKING }, - }; - gboolean found; - int k; - char *canonical_name; - - canonical_name = g_strdup (property_name); - g_strdelimit (canonical_name, "_", '-'); - - found = FALSE; - for (k = 0; k < G_N_ELEMENTS (props); k++) - { - if (strcmp (class_name, props[k].class) == 0 && - strcmp (canonical_name, props[k].property) == 0 && - kind == props[k].kind) - { - found = TRUE; - break; - } - } - - g_free (canonical_name); - - return found; -} - -static gboolean has_attribute (Element *elt, const char *name, const char *value) @@ -537,6 +484,7 @@ set_attribute_value (Element *element, const char *value) { int i; + int len; for (i = 0; element->attribute_names[i]; i++) { @@ -547,6 +495,14 @@ set_attribute_value (Element *element, return; } } + + len = g_strv_length (element->attribute_names); + element->attribute_names = g_realloc (element->attribute_names, len + 2); + element->attribute_values = g_realloc (element->attribute_values, len + 2); + element->attribute_names[len] = g_strdup (name); + element->attribute_values[len] = g_strdup (value); + element->attribute_names[len + 1] = NULL; + element->attribute_values[len + 1] = NULL; } static gboolean @@ -589,7 +545,7 @@ static gboolean property_is_boolean (Element *element, MyParserData *data) { - GParamSpec *pspec; + GParamSpec *pspec = NULL; const char *class_name; const char *property_name; int i; @@ -605,7 +561,8 @@ property_is_boolean (Element *element, property_name = (const char *)element->attribute_values[i]; } - pspec = get_property_pspec (data, class_name, property_name, kind); + if (class_name && property_name) + pspec = get_property_pspec (data, class_name, property_name, kind); if (pspec) return G_PARAM_SPEC_VALUE_TYPE (pspec) == G_TYPE_BOOLEAN; @@ -624,7 +581,7 @@ warn_missing_property (Element *element, g_printerr (_("%s:%d: %sproperty %s::%s not found\n"), data->input_filename, element->line_number, kind_str[kind], class_name, property_name); } - + static gboolean property_can_be_omitted (Element *element, MyParserData *data) @@ -656,10 +613,6 @@ property_can_be_omitted (Element *element, property_name = (const char *)element->attribute_values[i]; } - if (data->convert3to4 && - keep_for_rewrite (class_name, property_name, kind)) - return FALSE; /* keep, will be rewritten */ - if (translatable) return FALSE; @@ -1140,86 +1093,6 @@ rewrite_pack_type (Element *element, } static void -rewrite_child_prop_to_prop_child (Element *element, - MyParserData *data, - const char *child_prop, - const char *prop) -{ - Element *object = NULL; - Element *replaced = NULL; - GList *l, *ll; - - if (!g_str_equal (element->element_name, "child")) - return; - - for (l = element->children; l; l = l->next) - { - Element *elt = l->data; - - if (g_str_equal (elt->element_name, "object")) - object = elt; - - if (g_str_equal (elt->element_name, "packing")) - { - for (ll = elt->children; ll; ll = ll->next) - { - Element *elt2 = ll->data; - - if (g_str_equal (elt2->element_name, "property") && - has_attribute (elt2, "name", child_prop)) - { - replaced = elt2; - elt->children = g_list_remove (elt->children, replaced); - if (elt->children == NULL) - { - element->children = g_list_remove (element->children, elt); - free_element (elt); - } - break; - } - } - } - - if (replaced) - break; - } - - if (replaced) - { - Element *elt; - - elt = g_new0 (Element, 1); - elt->parent = element; - elt->element_name = g_strdup ("property"); - elt->attribute_names = g_new0 (char *, 2); - elt->attribute_names[0] = g_strdup ("name"); - elt->attribute_values = g_new0 (char *, 2); - elt->attribute_values[0] = g_strdup (prop); - elt->data = g_strdup (replaced->data); - - object->children = g_list_prepend (object->children, elt); - - free_element (replaced); - } -} - -static void -rewrite_child_prop_to_prop (Element *element, - MyParserData *data, - const char *child_prop, - const char *prop) -{ - GList *l; - - for (l = element->children; l; l = l->next) - { - Element *elt = l->data; - if (g_str_equal (elt->element_name, "child")) - rewrite_child_prop_to_prop_child (elt, data, child_prop, prop); - } -} - -static void rewrite_paned_child (Element *element, MyParserData *data, Element *child, @@ -1322,10 +1195,10 @@ rewrite_paned (Element *element, } if (child1) - rewrite_paned_child (element, data, child1, "child1"); + rewrite_paned_child (element, data, child1, "start-child"); if (child2) - rewrite_paned_child (element, data, child2, "child2"); + rewrite_paned_child (element, data, child2, "end-child"); } static void @@ -1389,46 +1262,6 @@ rewrite_dialog (Element *element, } static void -rewrite_layout_props (Element *element, - MyParserData *data) -{ - GList *l, *ll; - - for (l = element->children; l; l = l->next) - { - Element *child = l->data; - - if (g_str_equal (child->element_name, "child")) - { - Element *object = NULL; - Element *packing = NULL; - - for (ll = child->children; ll; ll = ll->next) - { - Element *elt2 = ll->data; - - if (g_str_equal (elt2->element_name, "object")) - object = elt2; - - if (g_str_equal (elt2->element_name, "packing")) - packing = elt2; - } - - if (object && packing) - { - child->children = g_list_remove (child->children, packing); - - g_free (packing->element_name); - packing->element_name = g_strdup ("layout"); - - packing->parent = object; - object->children = g_list_append (object->children, packing); - } - } - } -} - -static void rewrite_grid_layout_prop (Element *element, const char *attr_name, const char *old_value, @@ -1514,6 +1347,21 @@ rewrite_grid_layout (Element *element, } } +static Element * +add_element (Element *parent, + const char *element_name) +{ + Element *child; + + child = g_new0 (Element, 1); + child->parent = parent; + child->element_name = g_strdup (element_name); + child->attribute_names = g_new0 (char *, 1); + child->attribute_values = g_new0 (char *, 1); + parent->children = g_list_prepend (parent->children, child); + + return child; +} static Element * write_box_prop (Element *element, @@ -1526,16 +1374,11 @@ write_box_prop (Element *element, g_free (element->data); else { - element = g_new0 (Element, 1); - element->parent = parent; - element->element_name = g_strdup ("property"); - element->attribute_names = g_new0 (char *, 2); - element->attribute_names[0] = g_strdup ("name"); - element->attribute_values = g_new0 (char *, 2); - element->attribute_values[0] = g_strdup (name); - parent->children = g_list_prepend (parent->children, element); + element = add_element (parent, "property"); + set_attribute_value (element, "name", name); } element->data = g_strdup (value); + return element; } @@ -1747,27 +1590,16 @@ static void rewrite_radio_button (Element *element, MyParserData *data) { - int i; gboolean draw_indicator = TRUE; - const char *new_class; if (!remove_boolean_prop (element, data, "draw-indicator", &draw_indicator)) remove_boolean_prop (element, data, "draw_indicator", &draw_indicator); if (draw_indicator) - new_class = "GtkCheckButton"; + set_attribute_value (element, "class", "GtkCheckButton"); else - new_class = "GtkToggleButton"; + set_attribute_value (element, "class", "GtkToggleButton"); - for (i = 0; element->attribute_names[i]; i++) - { - if (strcmp (element->attribute_names[i], "class") == 0) - { - g_free (element->attribute_values[i]); - element->attribute_values[i] = g_strdup (new_class); - break; - } - } } static gboolean @@ -1797,15 +1629,200 @@ rewrite_scale (Element *element, !has_prop (element, data, "draw_value")) { Element *child; - child = g_new0 (Element, 1); - child->parent = element; - child->element_name = g_strdup ("property"); - child->attribute_names = g_new0 (char *, 2); - child->attribute_names[0] = g_strdup ("name"); - child->attribute_values = g_new0 (char *, 2); - child->attribute_values[0] = g_strdup ("draw-value"); + child = add_element (element, "property"); + set_attribute_value (child, "name", "draw-value"); child->data = g_strdup ("1"); - element->children = g_list_prepend (element->children, child); + } +} + +static void +rewrite_overlay (Element *element, + MyParserData *data) +{ + GList *l, *ll; + + for (l = element->children; l; l = l->next) + { + Element *child = l->data; + + if (g_str_equal (child->element_name, "child")) + { + Element *object = NULL; + Element *packing = NULL; + + for (ll = child->children; ll; ll = ll->next) + { + Element *elt2 = ll->data; + + if (g_str_equal (elt2->element_name, "object")) + object = elt2; + + if (g_str_equal (elt2->element_name, "packing")) + packing = elt2; + } + + if (object && packing) + { + child->children = g_list_remove (child->children, packing); + + for (ll = packing->children; ll; ll = ll->next) + { + Element *elt2 = ll->data; + + if (g_str_equal (elt2->element_name, "property") && + (has_attribute (elt2, "name", "pass-through") || + has_attribute (elt2, "name", "pass_through"))) + { + const char *b = canonical_boolean_value (data, elt2->data); + if (g_str_equal (b, "1")) + { + Element *new_prop; + + new_prop = add_element (object, "property"); + set_attribute_value (new_prop, "name", "can-target"); + new_prop->data = g_strdup ("0"); + } + break; + } + } + + free_element (packing); + } + } + } +} + +static void +rewrite_toolbar (Element *element, + MyParserData *data) +{ + GList *l, *ll; + Element *style = NULL; + + set_attribute_value (element, "class", "GtkBox"); + + for (l = element->children; l; l = l->next) + { + Element *child = l->data; + Element *object = NULL; + Element *packing = NULL; + + if (g_str_equal (child->element_name, "style")) + style = child; + + if (!g_str_equal (child->element_name, "child")) + continue; + + for (ll = child->children; ll; ll = ll->next) + { + Element *elt2 = ll->data; + + if (g_str_equal (elt2->element_name, "object")) + object = elt2; + + if (g_str_equal (elt2->element_name, "packing")) + packing = elt2; + } + + if (object) + { + const char *class_name; + + class_name = get_class_name (object); + + if (g_str_equal (class_name, "GtkToolButton")) + { + set_attribute_value (object, "class", "GtkButton"); + } + else if (g_str_equal (class_name, "GtkToggleToolButton") || + g_str_equal (class_name, "GtkRadioToolButton")) + { + set_attribute_value (object, "class", "GtkToggleButton"); + } + else if (g_str_equal (class_name, "GtkSeparatorToolItem")) + { + Element *prop; + + set_attribute_value (object, "class", "GtkSeparator"); + prop = add_element (object, "property"); + set_attribute_value (prop, "name", "orientation"); + prop->data = g_strdup ("vertical"); + } + } + + if (packing) + child->children = g_list_remove (child->children, packing); + } + + if (!style) + style = add_element (element, "style"); + + set_attribute_value (add_element (style, "class"), "name", "toolbar"); +} + +static void +rewrite_fixed (Element *element, + MyParserData *data) +{ + GList *l, *ll; + + for (l = element->children; l; l = l->next) + { + Element *child = l->data; + + if (g_str_equal (child->element_name, "child")) + { + Element *object = NULL; + Element *packing = NULL; + + for (ll = child->children; ll; ll = ll->next) + { + Element *elt2 = ll->data; + + if (g_str_equal (elt2->element_name, "object")) + object = elt2; + + if (g_str_equal (elt2->element_name, "packing")) + packing = elt2; + } + + if (object && packing) + { + int x = 0; + int y = 0; + Element *layout; + Element *new_prop; + GskTransform *transform; + + for (ll = packing->children; ll; ll = ll->next) + { + Element *elt2 = ll->data; + GValue value = G_VALUE_INIT; + + if (has_attribute (elt2, "name", "x")) + { + if (gtk_builder_value_from_string_type (data->builder, G_TYPE_INT, elt2->data, &value, NULL)) + x = g_value_get_int (&value); + } + else if (has_attribute (elt2, "name", "y")) + { + if (gtk_builder_value_from_string_type (data->builder, G_TYPE_INT, elt2->data, &value, NULL)) + y = g_value_get_int (&value); + } + } + + child->children = g_list_remove (child->children, packing); + free_element (packing); + + layout = add_element (object, "layout"); + new_prop = add_element (layout, "property"); + set_attribute_value (new_prop, "name", "transform"); + + transform = gsk_transform_translate (NULL, &GRAPHENE_POINT_INIT (x, y)); + new_prop->data = gsk_transform_to_string (transform); + gsk_transform_unref (transform); + } + } } } @@ -1900,16 +1917,8 @@ rewrite_element (Element *element, rewrite_pack_type (element, data); if (element_is_object_or_template (element) && - g_str_equal (get_class_name (element), "GtkPopoverMenu")) - rewrite_child_prop_to_prop (element, data, "submenu", "name"); - - if (element_is_object_or_template (element) && - g_str_equal (get_class_name (element), "GtkToolbar")) - rewrite_child_prop_to_prop (element, data, "expand", "expand-item"); - - if (element_is_object_or_template (element) && g_str_equal (get_class_name (element), "GtkToolbar")) - rewrite_child_prop_to_prop (element, data, "homogeneous", "homogeneous"); + rewrite_toolbar (element, data); if (element_is_object_or_template (element) && g_str_equal (get_class_name (element), "GtkPaned")) @@ -1921,7 +1930,7 @@ rewrite_element (Element *element, if (element_is_object_or_template (element) && g_str_equal (get_class_name (element), "GtkOverlay")) - rewrite_layout_props (element, data); + rewrite_overlay (element, data); if (element_is_object_or_template (element) && g_str_equal (get_class_name (element), "GtkGrid")) @@ -1935,7 +1944,7 @@ rewrite_element (Element *element, if (element_is_object_or_template (element) && g_str_equal (get_class_name (element), "GtkFixed")) - rewrite_layout_props (element, data); + rewrite_fixed (element, data); if (element_is_object_or_template (element) && (g_str_equal (get_class_name (element), "GtkAspectFrame") || @@ -2015,15 +2024,11 @@ add_old_default_properties (Element *element, if (!has_visible) { - Element *new_prop = g_new0 (Element, 1); - new_prop->parent = element; - new_prop->element_name = g_strdup ("property"); - new_prop->attribute_names = g_new0 (char *, 2); - new_prop->attribute_names[0] = g_strdup ("name"); - new_prop->attribute_values = g_new0 (char *, 2); - new_prop->attribute_values[0] = g_strdup ("visible"); + Element *new_prop; + + new_prop = add_element (element, "property"); + set_attribute_value (new_prop, "name", "visible"); new_prop->data = g_strdup ("0"); - element->children = g_list_prepend (element->children, new_prop); } } } @@ -2090,7 +2095,7 @@ dump_element (Element *element, g_fprintf (output, "]]>"); } else - { + { char *escaped = g_markup_escape_text (element->data, -1); g_fprintf (output, "%s", escaped); g_free (escaped); diff --git a/gtk/tools/gtk-builder-tool-validate.c b/gtk/tools/gtk-builder-tool-validate.c index 63910f9fb6..8551231730 100644 --- a/gtk/tools/gtk-builder-tool-validate.c +++ b/gtk/tools/gtk-builder-tool-validate.c @@ -139,7 +139,7 @@ validate_file (const char *filename) } else { - g_printerr ("%s: %s\n", filename, error->message); + g_printerr ("%s\n", error->message); return FALSE; } } diff --git a/gtk/tools/gtk-builder-tool.c b/gtk/tools/gtk-builder-tool.c index e07cfb6218..e45a52672d 100644 --- a/gtk/tools/gtk-builder-tool.c +++ b/gtk/tools/gtk-builder-tool.c @@ -52,11 +52,66 @@ usage (void) exit (1); } +#if !GLIB_CHECK_VERSION(2,67,0) +static gboolean +g_log_writer_default_would_drop (GLogLevelFlags level, + const char *domain) +{ + return (level & (G_LOG_LEVEL_ERROR | + G_LOG_LEVEL_CRITICAL | + G_LOG_LEVEL_WARNING)) == 0; +} +#endif + +static GLogWriterOutput +log_writer_func (GLogLevelFlags level, + const GLogField *fields, + gsize n_fields, + gpointer user_data) +{ + gsize i; + const char *domain = NULL; + const char *message = NULL; + + for (i = 0; i < n_fields; i++) + { + if (g_strcmp0 (fields[i].key, "GLIB_DOMAIN") == 0) + domain = fields[i].value; + else if (g_strcmp0 (fields[i].key, "MESSAGE") == 0) + message = fields[i].value; + } + + if (message != NULL && !g_log_writer_default_would_drop (level, domain)) + { + const char *prefix; + switch (level & G_LOG_LEVEL_MASK) + { + case G_LOG_LEVEL_ERROR: + prefix = "ERROR"; + break; + case G_LOG_LEVEL_CRITICAL: + prefix = "CRITICAL"; + break; + case G_LOG_LEVEL_WARNING: + prefix = "WARNING"; + break; + default: + prefix = "INFO"; + break; + } + g_printerr ("%s-%s: %s\n", domain, prefix, message); + } + + return G_LOG_WRITER_HANDLED; +} + int main (int argc, const char *argv[]) { g_set_prgname ("gtk-builder-tool"); + g_log_set_writer_func (log_writer_func, NULL, NULL); + gtk_init (); gtk_test_register_all_types (); diff --git a/testsuite/css/change/meson.build b/testsuite/css/change/meson.build index 83e37ae2f6..a52fc5348e 100644 --- a/testsuite/css/change/meson.build +++ b/testsuite/css/change/meson.build @@ -1,3 +1,12 @@ +changetest_env = environment() +changetest_env.set('GTK_TEST_ACCESSIBLE', '1') +changetest_env.set('GSK_RENDERER', 'cairo') +changetest_env.set('G_TEST_SRCDIR', meson.current_source_dir()) +changetest_env.set('G_TEST_BUILDDIR', meson.current_build_dir()) +changetest_env.set('GIO_USE_VFS', 'local') +changetest_env.set('GSETTINGS_BACKEND', 'memory') +changetest_env.set('G_ENABLE_DIAGNOSTIC', '0') + testexecdir = join_paths(installed_test_bindir, 'css', 'change') testdatadir = join_paths(installed_test_datadir, 'css') @@ -13,7 +22,7 @@ test_change = executable( test('change', test_change, args: [ '--tap', '-k' ], protocol: 'tap', - env: csstest_env, + env: changetest_env, suite: 'css', ) diff --git a/testsuite/css/data.c b/testsuite/css/data.c index 72533fcfb2..978be0e55e 100644 --- a/testsuite/css/data.c +++ b/testsuite/css/data.c @@ -58,6 +58,15 @@ Test tests[] = { { "charset_base64", "data:text/plain;charset=ISO-8859-5;base64,wOPh29DdILjW0ePb0OLe0g==", "text/plain", CONTENTS("Руслан Ижбулатов") }, + { "wrong_scheme", + "duda:,Hello", + NULL, NULL, 0 }, + { "missing_comma", + "data:text/plain;charset=ISO-8859-1:bla", + NULL, NULL, 0 }, + { "bad_escape", + "data:,abc%00", + NULL, NULL, -1 }, }; static void @@ -70,17 +79,25 @@ test_parse (gconstpointer data) bytes = gtk_css_data_url_parse (test->url, &mimetype, &error); - g_assert (bytes != NULL); - g_assert_no_error (error); - if (test->mimetype == NULL) - g_assert (mimetype == NULL); - else - g_assert_cmpstr (mimetype, ==, test->mimetype); - - g_assert_cmpmem (g_bytes_get_data (bytes, NULL), g_bytes_get_size (bytes), - test->contents, test->contents_len); + if (test->contents) + { + g_assert_nonnull (bytes); + g_assert_no_error (error); + if (test->mimetype == NULL) + g_assert (mimetype == NULL); + else + g_assert_cmpstr (mimetype, ==, test->mimetype); - g_bytes_unref (bytes); + g_assert_cmpmem (g_bytes_get_data (bytes, NULL), g_bytes_get_size (bytes), + test->contents, test->contents_len); + g_bytes_unref (bytes); + } + else + { + g_assert_null (bytes); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_FILENAME); + g_error_free (error); + } } int diff --git a/testsuite/css/nodes/meson.build b/testsuite/css/nodes/meson.build index 11ed48b9e5..313e06a112 100644 --- a/testsuite/css/nodes/meson.build +++ b/testsuite/css/nodes/meson.build @@ -1,3 +1,12 @@ +nodetest_env = environment() +nodetest_env.set('GTK_TEST_ACCESSIBLE', '1') +nodetest_env.set('GSK_RENDERER', 'cairo') +nodetest_env.set('G_TEST_SRCDIR', meson.current_source_dir()) +nodetest_env.set('G_TEST_BUILDDIR', meson.current_build_dir()) +nodetest_env.set('GIO_USE_VFS', 'local') +nodetest_env.set('GSETTINGS_BACKEND', 'memory') +nodetest_env.set('G_ENABLE_DIAGNOSTIC', '0') + testexecdir = join_paths(installed_test_bindir, 'css', 'nodes') testdatadir = join_paths(installed_test_datadir, 'css') @@ -9,7 +18,7 @@ test_nodes = executable('test-css-nodes', 'test-css-nodes.c', test('nodes', test_nodes, args: [ '--tap', '-k' ], protocol: 'tap', - env: csstest_env, + env: nodetest_env, suite: 'css', ) diff --git a/testsuite/css/parser/cdo-cdc.css b/testsuite/css/parser/cdo-cdc.css new file mode 100644 index 0000000000..3670c19285 --- /dev/null +++ b/testsuite/css/parser/cdo-cdc.css @@ -0,0 +1,7 @@ +<!-- + +label { + color: red; +} + +--> diff --git a/testsuite/css/parser/cdo-cdc.ref.css b/testsuite/css/parser/cdo-cdc.ref.css new file mode 100644 index 0000000000..e53c8cfd5c --- /dev/null +++ b/testsuite/css/parser/cdo-cdc.ref.css @@ -0,0 +1,3 @@ +label { + color: rgb(255,0,0); +} diff --git a/testsuite/css/parser/meson.build b/testsuite/css/parser/meson.build index 7ffd5d2644..7e501aebda 100644 --- a/testsuite/css/parser/meson.build +++ b/testsuite/css/parser/meson.build @@ -197,6 +197,8 @@ test_data = [ 'calc.ref.css', 'calc-simple.css', 'calc-simple.ref.css', + 'cdo-cdc.css', + 'cdo-cdc.ref.css', 'close-at-end-of-file.css', 'close-at-end-of-file.errors', 'close-at-end-of-file.ref.css', @@ -372,6 +374,8 @@ test_data = [ 'not-unclosed.ref.css', 'nth-child.css', 'nth-child.ref.css', + 'number-values.css', + 'number-values.ref.css', 'opacity.css', 'opacity.ref.css', 'outline-color.css', @@ -440,6 +444,18 @@ test_data = [ 'transition.ref.css', 'transition-timing-function.css', 'transition-timing-function.ref.css', + 'url-invalid1.css', + 'url-invalid1.errors', + 'url-invalid1.ref.css', + 'url-invalid2.css', + 'url-invalid2.errors', + 'url-invalid2.ref.css', + 'url-valid1.css', + 'url-valid1.ref.css', + 'url-valid2.css', + 'url-valid2.ref.css', + 'url-valid3.css', + 'url-valid3.ref.css', 'value-inherit.css', 'value-inherit.ref.css', 'value-inherit.errors', diff --git a/testsuite/css/parser/url-invalid1.css b/testsuite/css/parser/url-invalid1.css new file mode 100644 index 0000000000..903f2dc996 --- /dev/null +++ b/testsuite/css/parser/url-invalid1.css @@ -0,0 +1,4 @@ + +label { + background-image: url(resource:///org/gtk/libgtk/icons/16x16(/places/user-trash.png); +} diff --git a/testsuite/css/parser/url-invalid1.errors b/testsuite/css/parser/url-invalid1.errors new file mode 100644 index 0000000000..4fe152bf6e --- /dev/null +++ b/testsuite/css/parser/url-invalid1.errors @@ -0,0 +1 @@ +url-invalid1.css:3:21-87: error: GTK_CSS_PARSER_ERROR_SYNTAX diff --git a/testsuite/css/parser/url-invalid1.ref.css b/testsuite/css/parser/url-invalid1.ref.css new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/testsuite/css/parser/url-invalid1.ref.css diff --git a/testsuite/css/parser/url-invalid2.css b/testsuite/css/parser/url-invalid2.css new file mode 100644 index 0000000000..340d29925c --- /dev/null +++ b/testsuite/css/parser/url-invalid2.css @@ -0,0 +1,4 @@ + +label { + background-image: url(resource:///org/gtk/ libgtk/icons/16x16/places/user-trash.png); +} diff --git a/testsuite/css/parser/url-invalid2.errors b/testsuite/css/parser/url-invalid2.errors new file mode 100644 index 0000000000..7978a02772 --- /dev/null +++ b/testsuite/css/parser/url-invalid2.errors @@ -0,0 +1 @@ +url-invalid2.css:3:21-87: error: GTK_CSS_PARSER_ERROR_SYNTAX diff --git a/testsuite/css/parser/url-invalid2.ref.css b/testsuite/css/parser/url-invalid2.ref.css new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/testsuite/css/parser/url-invalid2.ref.css diff --git a/testsuite/css/parser/url-valid1.css b/testsuite/css/parser/url-valid1.css new file mode 100644 index 0000000000..c2f1984998 --- /dev/null +++ b/testsuite/css/parser/url-valid1.css @@ -0,0 +1,3 @@ +label { + background-image: url("resource:///org/gtk/libgtk/icons/16x16/places/user-trash.png"); +} diff --git a/testsuite/css/parser/url-valid1.ref.css b/testsuite/css/parser/url-valid1.ref.css new file mode 100644 index 0000000000..e0f30dafeb --- /dev/null +++ b/testsuite/css/parser/url-valid1.ref.css @@ -0,0 +1,3 @@ +label { + background-image: none /* FIXME */; +} diff --git a/testsuite/css/parser/url-valid2.css b/testsuite/css/parser/url-valid2.css new file mode 100644 index 0000000000..89f42f16cf --- /dev/null +++ b/testsuite/css/parser/url-valid2.css @@ -0,0 +1,4 @@ + +label { + background-image: url(resource:///org/gtk/libgtk/icons/16x16/places/user-trash.png); +} diff --git a/testsuite/css/parser/url-valid2.ref.css b/testsuite/css/parser/url-valid2.ref.css new file mode 100644 index 0000000000..e0f30dafeb --- /dev/null +++ b/testsuite/css/parser/url-valid2.ref.css @@ -0,0 +1,3 @@ +label { + background-image: none /* FIXME */; +} diff --git a/testsuite/css/parser/url-valid3.css b/testsuite/css/parser/url-valid3.css new file mode 100644 index 0000000000..b9add7f7a7 --- /dev/null +++ b/testsuite/css/parser/url-valid3.css @@ -0,0 +1,4 @@ + +label { + background-image: url( resource:///\6F rg/gtk/libgtk/icons/16x16/places/user-trash.png ); +} diff --git a/testsuite/css/parser/url-valid3.ref.css b/testsuite/css/parser/url-valid3.ref.css new file mode 100644 index 0000000000..e0f30dafeb --- /dev/null +++ b/testsuite/css/parser/url-valid3.ref.css @@ -0,0 +1,3 @@ +label { + background-image: none /* FIXME */; +} diff --git a/testsuite/css/style/meson.build b/testsuite/css/style/meson.build index b54adf7c68..a7af27deb3 100644 --- a/testsuite/css/style/meson.build +++ b/testsuite/css/style/meson.build @@ -1,3 +1,12 @@ +styletest_env = environment() +styletest_env.set('GTK_TEST_ACCESSIBLE', '1') +styletest_env.set('GSK_RENDERER', 'cairo') +styletest_env.set('G_TEST_SRCDIR', meson.current_source_dir()) +styletest_env.set('G_TEST_BUILDDIR', meson.current_build_dir()) +styletest_env.set('GIO_USE_VFS', 'local') +styletest_env.set('GSETTINGS_BACKEND', 'memory') +styletest_env.set('G_ENABLE_DIAGNOSTIC', '0') + testexecdir = join_paths(installed_test_bindir, 'css', 'style') testdatadir = join_paths(installed_test_datadir, 'css') @@ -19,7 +28,7 @@ test_style = executable( test('style', test_style, args: [ '--tap', '-k' ], protocol: 'tap', - env: csstest_env, + env: styletest_env, suite: 'css', ) diff --git a/testsuite/gdk/displaymanager.c b/testsuite/gdk/displaymanager.c new file mode 100644 index 0000000000..ce7c0d974f --- /dev/null +++ b/testsuite/gdk/displaymanager.c @@ -0,0 +1,55 @@ +#include <gtk/gtk.h> + +static void +test_basic (void) +{ + GdkDisplayManager *manager; + GdkDisplay *d, *d2; + GSList *list; + + manager = gdk_display_manager_get (); + g_assert_nonnull (manager); + + d = gdk_display_manager_get_default_display (manager); + g_assert_nonnull (d); + g_object_get (manager, "default-display", &d2, NULL); + g_assert_true (d == d2); + g_object_unref (d2); + + list = gdk_display_manager_list_displays (manager); + g_assert_nonnull (g_slist_find (list, d)); + g_slist_free (list); +} + +static void +test_set_default (void) +{ + GdkDisplayManager *manager; + GdkDisplay *d, *d2; + const char *name; + + manager = gdk_display_manager_get (); + g_assert_nonnull (manager); + + d = gdk_display_manager_get_default_display (manager); + name = gdk_display_get_name (d); + d2 = gdk_display_manager_open_display (manager, name); + g_object_set (manager, "default-display", d2, NULL); + + d = gdk_display_manager_get_default_display (manager); + g_assert_true (d == d2); +} + +int +main (int argc, char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + /* Open default display */ + gdk_display_open (NULL); + + g_test_add_func ("/displaymanager/basic", test_basic); + g_test_add_func ("/displaymanager/set-default", test_set_default); + + return g_test_run (); +} diff --git a/testsuite/gdk/keysyms.c b/testsuite/gdk/keysyms.c index 217b8a4600..481aafae4c 100644 --- a/testsuite/gdk/keysyms.c +++ b/testsuite/gdk/keysyms.c @@ -54,7 +54,77 @@ test_keysyms_xf86 (void) g_assert_cmpuint (gdk_keyval_from_name ("Display"), ==, GDK_KEY_Display); } -int main (int argc, char *argv[]) +#define UNICODE_KEYVAL(wc) ((wc) | 0x01000000) + +static void +test_key_case (void) +{ + struct { + guint lower; + guint upper; + } tests[] = { + { GDK_KEY_a, GDK_KEY_A }, + { GDK_KEY_agrave, GDK_KEY_Agrave }, + { GDK_KEY_thorn, GDK_KEY_Thorn }, + { GDK_KEY_oslash, GDK_KEY_Oslash }, + { GDK_KEY_aogonek, GDK_KEY_Aogonek }, + { GDK_KEY_lstroke, GDK_KEY_Lstroke }, + { GDK_KEY_scaron, GDK_KEY_Scaron }, + { GDK_KEY_zcaron, GDK_KEY_Zcaron }, + { GDK_KEY_racute, GDK_KEY_Racute }, + { GDK_KEY_hstroke, GDK_KEY_Hstroke }, + { GDK_KEY_jcircumflex, GDK_KEY_Jcircumflex }, + { GDK_KEY_cabovedot, GDK_KEY_Cabovedot }, + { GDK_KEY_rcedilla, GDK_KEY_Rcedilla }, + { GDK_KEY_eng, GDK_KEY_ENG }, + { GDK_KEY_amacron, GDK_KEY_Amacron }, + { GDK_KEY_Serbian_dje, GDK_KEY_Serbian_DJE }, + { GDK_KEY_Cyrillic_yu, GDK_KEY_Cyrillic_YU }, + { GDK_KEY_Greek_alphaaccent, GDK_KEY_Greek_ALPHAaccent }, + { GDK_KEY_Greek_omega, GDK_KEY_Greek_OMEGA }, + { GDK_KEY_Greek_sigma, GDK_KEY_Greek_SIGMA }, + + { GDK_KEY_space, GDK_KEY_space }, + { GDK_KEY_0, GDK_KEY_0 }, + { GDK_KEY_KP_0, GDK_KEY_KP_0 }, + + /* Face Savouring Delicious Food */ + { UNICODE_KEYVAL (0x1f60b), UNICODE_KEYVAL (0x1f60b) }, + }; + guint i; + + for (i = 0; i < G_N_ELEMENTS (tests); i++) + { + g_assert_true (gdk_keyval_is_lower (tests[i].lower)); + g_assert_true (gdk_keyval_is_upper (tests[i].upper)); + g_assert_cmpuint (gdk_keyval_to_upper (tests[i].lower), ==, tests[i].upper); + g_assert_cmpuint (gdk_keyval_to_lower (tests[i].upper), ==, tests[i].lower); + } +} + +static void +test_key_unicode (void) +{ + struct { + guint key; + gunichar ch; + } tests[] = { + { GDK_KEY_a, 'a' }, + { GDK_KEY_A, 'A' }, + { GDK_KEY_EuroSign, 0x20ac }, + { UNICODE_KEYVAL (0x1f60b), 0x1f60b }, + }; + guint i; + + for (i = 0; i < G_N_ELEMENTS (tests); i++) + { + g_assert_cmpuint (gdk_keyval_to_unicode (tests[i].key), ==, tests[i].ch); + g_assert_cmpuint (gdk_unicode_to_keyval (tests[i].ch), ==, tests[i].key); + } +} + +int +main (int argc, char *argv[]) { setlocale (LC_ALL, ""); @@ -64,6 +134,8 @@ int main (int argc, char *argv[]) g_test_add_func ("/keysyms/basic", test_keysyms_basic); g_test_add_func ("/keysyms/void", test_keysyms_void); g_test_add_func ("/keysyms/xf86", test_keysyms_xf86); + g_test_add_func ("/keys/case", test_key_case); + g_test_add_func ("/keys/unicode", test_key_unicode); return g_test_run (); } diff --git a/testsuite/gdk/meson.build b/testsuite/gdk/meson.build index aa93f8384d..c62c931905 100644 --- a/testsuite/gdk/meson.build +++ b/testsuite/gdk/meson.build @@ -6,12 +6,14 @@ tests = [ 'cairo', 'clipboard', 'display', + 'displaymanager', 'encoding', 'keysyms', 'memorytexture', 'rectangle', 'rgba', 'seat', + 'texture', ] foreach t : tests diff --git a/testsuite/gdk/rectangle.c b/testsuite/gdk/rectangle.c index ead270eea7..bf8f9983b3 100644 --- a/testsuite/gdk/rectangle.c +++ b/testsuite/gdk/rectangle.c @@ -1,4 +1,5 @@ #include <gtk/gtk.h> +#include <cairo-gobject.h> static void test_rectangle_equal (void) @@ -65,6 +66,47 @@ test_rectangle_union (void) g_assert_true (gdk_rectangle_equal (&f, &g)); } +/* Test that GdkRectangle works as a boxed type */ + +static void +test_rectangle_type (void) +{ + GValue value = G_VALUE_INIT; + GdkRectangle b = { 5, 5, 10, 10 }; + GdkRectangle *c; + GValue value2 = G_VALUE_INIT; + cairo_rectangle_int_t *c2; + + g_value_init (&value, GDK_TYPE_RECTANGLE); + g_value_set_boxed (&value, &b); + c = g_value_get_boxed (&value); + + g_assert_true (gdk_rectangle_equal (&b, c)); + + g_assert_true (g_value_type_transformable (GDK_TYPE_RECTANGLE, CAIRO_GOBJECT_TYPE_RECTANGLE_INT)); + g_value_init (&value2, CAIRO_GOBJECT_TYPE_RECTANGLE_INT); + g_assert_true (g_value_transform (&value, &value2)); + c2 = g_value_get_boxed (&value2); + g_assert_cmpint (c->x, ==, c2->x); + g_assert_cmpint (c->y, ==, c2->y); + g_assert_cmpint (c->width, ==, c2->width); + g_assert_cmpint (c->height, ==, c2->height); + + g_value_unset (&value); + g_value_unset (&value2); +} + +static void +test_rectangle_contains (void) +{ + GdkRectangle b = { 5, 5, 5, 5 }; + + g_assert_true (gdk_rectangle_contains_point (&b, 5, 5)); + g_assert_true (gdk_rectangle_contains_point (&b, 9, 9)); + g_assert_false (gdk_rectangle_contains_point (&b, 4, 8)); + g_assert_false (gdk_rectangle_contains_point (&b, 10, 6)); +} + int main (int argc, char *argv[]) { @@ -75,6 +117,8 @@ main (int argc, char *argv[]) g_test_add_func ("/rectangle/equal", test_rectangle_equal); g_test_add_func ("/rectangle/intersect", test_rectangle_intersect); g_test_add_func ("/rectangle/union", test_rectangle_union); + g_test_add_func ("/rectangle/type", test_rectangle_type); + g_test_add_func ("/rectangle/contains", test_rectangle_contains); return g_test_run (); } diff --git a/testsuite/gdk/seat.c b/testsuite/gdk/seat.c index bd98236132..75fd9616fd 100644 --- a/testsuite/gdk/seat.c +++ b/testsuite/gdk/seat.c @@ -38,11 +38,12 @@ test_list_seats (void) static void test_default_seat (void) { - GdkDisplay *display; + GdkDisplay *display, *d; GdkSeat *seat0; GdkSeatCapabilities caps; GdkDevice *pointer0, *keyboard0, *device; - GList *physical_devices, *l; + GList *physical_devices, *tools, *l; + GdkDeviceTool *tool; display = gdk_display_get_default (); seat0 = gdk_display_get_default_seat (display); @@ -55,9 +56,14 @@ test_default_seat (void) g_assert_true (GDK_IS_SEAT (seat0)); + g_assert_true (gdk_seat_get_display (seat0) == display); + g_object_get (seat0, "display", &d, NULL); + g_assert_true (display == d); + g_object_unref (d); + caps = gdk_seat_get_capabilities (seat0); - g_assert (caps != GDK_SEAT_CAPABILITY_NONE); + g_assert_true (caps != GDK_SEAT_CAPABILITY_NONE); pointer0 = gdk_seat_get_pointer (seat0); physical_devices = gdk_seat_get_devices (seat0, GDK_SEAT_CAPABILITY_POINTER); @@ -65,15 +71,15 @@ test_default_seat (void) if ((caps & GDK_SEAT_CAPABILITY_POINTER) != 0) { g_assert_nonnull (pointer0); - g_assert (gdk_device_get_display (pointer0) == display); - g_assert (gdk_device_get_seat (pointer0) == seat0); + g_assert_true (gdk_device_get_display (pointer0) == display); + g_assert_true (gdk_device_get_seat (pointer0) == seat0); g_assert_nonnull (physical_devices); for (l = physical_devices; l; l = l->next) { device = l->data; - g_assert (gdk_device_get_display (device) == display); - g_assert (gdk_device_get_seat (device) == seat0); + g_assert_true (gdk_device_get_display (device) == display); + g_assert_true (gdk_device_get_seat (device) == seat0); } g_list_free (physical_devices); } @@ -89,17 +95,17 @@ test_default_seat (void) if ((caps & GDK_SEAT_CAPABILITY_KEYBOARD) != 0) { g_assert_nonnull (keyboard0); - g_assert (gdk_device_get_display (keyboard0) == display); - g_assert (gdk_device_get_seat (keyboard0) == seat0); - g_assert (gdk_device_get_source (keyboard0) == GDK_SOURCE_KEYBOARD); + g_assert_true (gdk_device_get_display (keyboard0) == display); + g_assert_true (gdk_device_get_seat (keyboard0) == seat0); + g_assert_true (gdk_device_get_source (keyboard0) == GDK_SOURCE_KEYBOARD); g_assert_nonnull (physical_devices); for (l = physical_devices; l; l = l->next) { device = l->data; - g_assert (gdk_device_get_display (device) == display); - g_assert (gdk_device_get_seat (device) == seat0); - g_assert (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD); + g_assert_true (gdk_device_get_display (device) == display); + g_assert_true (gdk_device_get_seat (device) == seat0); + g_assert_true (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD); } g_list_free (physical_devices); } @@ -109,6 +115,13 @@ test_default_seat (void) g_assert_null (physical_devices); } + tools = gdk_seat_get_tools (seat0); + for (l = tools; l; l = l->next) + { + tool = l->data; + g_assert_true (GDK_IS_DEVICE_TOOL (tool)); + } + g_list_free (tools); } int diff --git a/testsuite/gdk/texture.c b/testsuite/gdk/texture.c new file mode 100644 index 0000000000..fc1f728c7c --- /dev/null +++ b/testsuite/gdk/texture.c @@ -0,0 +1,120 @@ +#include <gtk.h> + +static gboolean +compare_pixels (int width, + int height, + guchar *data1, + gsize stride1, + guchar *data2, + gsize stride2) +{ + int i; + for (i = 0; i < height; i++) + { + gconstpointer p1 = data1 + i * stride1; + gconstpointer p2 = data2 + i * stride2; + if (memcmp (p1, p2, width * 4) != 0) + return FALSE; + } + return TRUE; +} + +static void +test_texture_from_pixbuf (void) +{ + GdkPixbuf *pixbuf; + GdkTexture *texture; + GError *error = NULL; + guchar *data; + int width, height; + gsize stride; + cairo_surface_t *surface; + cairo_t *cr; + + pixbuf = gdk_pixbuf_new_from_resource ("/org/gtk/libgtk/icons/16x16/places/user-trash.png", &error); + g_assert_no_error (error); + g_assert_nonnull (pixbuf); + g_assert_true (gdk_pixbuf_get_has_alpha (pixbuf)); + + width = gdk_pixbuf_get_width (pixbuf); + height = gdk_pixbuf_get_height (pixbuf); + + texture = gdk_texture_new_for_pixbuf (pixbuf); + + g_assert_nonnull (texture); + g_assert_cmpint (gdk_texture_get_width (texture), ==, width); + g_assert_cmpint (gdk_texture_get_height (texture), ==, height); + + stride = 4 * width; + data = g_new0 (guchar, stride * height); + gdk_texture_download (texture, data, stride); + + surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height); + cr = cairo_create (surface); + gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0); + cairo_paint (cr); + cairo_destroy (cr); + + g_assert_true (compare_pixels (width, height, + data, stride, + cairo_image_surface_get_data (surface), + cairo_image_surface_get_stride (surface))); + + g_free (data); + + g_object_unref (pixbuf); + g_object_unref (texture); + cairo_surface_destroy (surface); +} + +static void +test_texture_from_resource (void) +{ + GdkTexture *texture; + int width, height; + + texture = gdk_texture_new_from_resource ("/org/gtk/libgtk/icons/16x16/places/user-trash.png"); + + g_assert_nonnull (texture); + g_object_get (texture, + "width", &width, + "height", &height, + NULL); + g_assert_cmpint (width, ==, 16); + g_assert_cmpint (height, ==, 16); + + g_object_unref (texture); +} + +static void +test_texture_save_to_png (void) +{ + GdkTexture *texture; + GError *error = NULL; + GFile *file; + GdkTexture *texture2; + + texture = gdk_texture_new_from_resource ("/org/gtk/libgtk/icons/16x16/places/user-trash.png"); + + gdk_texture_save_to_png (texture, "test.png"); + file = g_file_new_for_path ("test.png"); + texture2 = gdk_texture_new_from_file (file, &error); + g_object_unref (file); + g_assert_no_error (error); + + g_object_unref (texture); + g_object_unref (texture2); +} + +int +main (int argc, char *argv[]) +{ + /* We want to use resources from libgtk, so we need gtk initialized */ + gtk_test_init (&argc, &argv, NULL); + + g_test_add_func ("/texture/from-pixbuf", test_texture_from_pixbuf); + g_test_add_func ("/texture/from-resource", test_texture_from_resource); + g_test_add_func ("/texture/save-to-png", test_texture_save_to_png); + + return g_test_run (); +} diff --git a/testsuite/gtk/expression.c b/testsuite/gtk/expression.c index a874e562a4..cea66f3ae9 100644 --- a/testsuite/gtk/expression.c +++ b/testsuite/gtk/expression.c @@ -61,6 +61,16 @@ test_property (void) g_object_unref (filter); } +static void +test_interface_property (void) +{ + GtkExpression *expr; + + expr = gtk_property_expression_new (GTK_TYPE_ORIENTABLE, NULL, "orientation"); + g_assert_cmpstr (gtk_property_expression_get_pspec (expr)->name, ==, "orientation"); + gtk_expression_unref (expr); +} + static char * print_filter_info (GtkStringFilter *filter, const char *search, @@ -75,7 +85,7 @@ print_filter_info (GtkStringFilter *filter, } static void -test_closure (void) +test_cclosure (void) { GValue value = G_VALUE_INIT; GtkExpression *expr, *pexpr[3]; @@ -127,11 +137,34 @@ test_closure (void) g_object_unref (filter); } +static char * +make_string (void) +{ + return g_strdup ("Hello"); +} + +static void +test_closure (void) +{ + GValue value = G_VALUE_INIT; + GtkExpression *expr; + GClosure *closure; + + closure = g_cclosure_new (G_CALLBACK (make_string), NULL, NULL); + expr = gtk_closure_expression_new (G_TYPE_STRING, closure, 0, NULL); + g_assert (gtk_expression_evaluate (expr, NULL, &value)); + g_assert_cmpstr (g_value_get_string (&value), ==, "Hello"); + g_value_unset (&value); + + gtk_expression_unref (expr); +} + static void test_constant (void) { GtkExpression *expr; GValue value = G_VALUE_INIT; + const GValue *v; gboolean res; expr = gtk_constant_expression_new (G_TYPE_INT, 22); @@ -142,6 +175,9 @@ test_constant (void) g_assert_true (res); g_assert_cmpint (g_value_get_int (&value), ==, 22); + v = gtk_constant_expression_get_value (expr); + g_assert_cmpint (g_value_get_int (v), ==, 22); + gtk_expression_unref (expr); } @@ -155,6 +191,7 @@ test_object (void) GObject *obj; GValue value = G_VALUE_INIT; gboolean res; + GObject *o; obj = G_OBJECT (gtk_string_filter_new (NULL)); @@ -167,6 +204,9 @@ test_object (void) g_assert_true (g_value_get_object (&value) == obj); g_value_unset (&value); + o = gtk_object_expression_get_object (expr); + g_assert_true (o == obj); + g_clear_object (&obj); res = gtk_expression_evaluate (expr, NULL, &value); g_assert_false (res); @@ -650,6 +690,9 @@ test_binds (void) expr2 = gtk_property_expression_new (GTK_TYPE_STRING_FILTER, gtk_expression_ref (filter2_expr), "ignore-case"); + g_assert_true (gtk_property_expression_get_expression (expr2) == filter2_expr); + g_assert_cmpstr (gtk_property_expression_get_pspec (expr2)->name, ==, "ignore-case"); + gtk_expression_bind (gtk_expression_ref (expr), filter3, "search", NULL); gtk_expression_bind (gtk_expression_ref (expr2), filter3, "ignore-case", NULL); @@ -704,6 +747,28 @@ test_bind_object (void) g_object_unref (model); } +static void +test_value (void) +{ + GValue value = G_VALUE_INIT; + GtkExpression *expr; + + expr = gtk_constant_expression_new (G_TYPE_INT, 22); + + g_value_init (&value, GTK_TYPE_EXPRESSION); + gtk_value_take_expression (&value, expr); + g_assert_true (G_VALUE_TYPE (&value) == GTK_TYPE_EXPRESSION); + + expr = gtk_value_dup_expression (&value); + gtk_expression_unref (expr); + + expr = gtk_constant_expression_new (G_TYPE_INT, 23); + gtk_value_set_expression (&value, expr); + gtk_expression_unref (expr); + + g_value_unset (&value); +} + int main (int argc, char *argv[]) { @@ -711,6 +776,8 @@ main (int argc, char *argv[]) setlocale (LC_ALL, "C"); g_test_add_func ("/expression/property", test_property); + g_test_add_func ("/expression/interface-property", test_interface_property); + g_test_add_func ("/expression/cclosure", test_cclosure); g_test_add_func ("/expression/closure", test_closure); g_test_add_func ("/expression/constant", test_constant); g_test_add_func ("/expression/constant-watch-this-destroyed", test_constant_watch_this_destroyed); @@ -726,6 +793,7 @@ main (int argc, char *argv[]) g_test_add_func ("/expression/double-bind", test_double_bind); g_test_add_func ("/expression/binds", test_binds); g_test_add_func ("/expression/bind-object", test_bind_object); + g_test_add_func ("/expression/value", test_value); return g_test_run (); } diff --git a/testsuite/gtk/filter.c b/testsuite/gtk/filter.c index b16c5c4321..d6fb3fdb0e 100644 --- a/testsuite/gtk/filter.c +++ b/testsuite/gtk/filter.c @@ -219,6 +219,7 @@ test_any_simple (void) { GtkFilterListModel *model; GtkFilter *any, *filter1, *filter2; + gpointer item; any = GTK_FILTER (gtk_any_filter_new ()); filter1 = GTK_FILTER (gtk_custom_filter_new (divisible_by, GUINT_TO_POINTER (3), NULL)); @@ -233,6 +234,12 @@ test_any_simple (void) gtk_multi_filter_append (GTK_MULTI_FILTER (any), filter2); assert_model (model, "3 5 6 9 10 12 15 18 20"); + g_assert_true (g_list_model_get_item_type (G_LIST_MODEL (any)) == GTK_TYPE_FILTER); + g_assert_cmpuint (2, ==, g_list_model_get_n_items (G_LIST_MODEL (any))); + item = g_list_model_get_item (G_LIST_MODEL (any), 1); + g_assert_true (GTK_FILTER (item) == filter2); + g_object_unref (item); + gtk_multi_filter_remove (GTK_MULTI_FILTER (any), 0); assert_model (model, "5 10 15 20"); @@ -275,13 +282,15 @@ test_string_properties (void) { GtkFilterListModel *model; GtkFilter *filter; + GtkExpression *expr; - filter = GTK_FILTER (gtk_string_filter_new ( - gtk_cclosure_expression_new (G_TYPE_STRING, - NULL, - 0, NULL, - G_CALLBACK (get_spelled_out), - NULL, NULL))); + expr = gtk_cclosure_expression_new (G_TYPE_STRING, + NULL, + 0, NULL, + G_CALLBACK (get_spelled_out), + NULL, NULL); + filter = GTK_FILTER (gtk_string_filter_new (expr)); + g_assert_true (expr == gtk_string_filter_get_expression (GTK_STRING_FILTER (filter))); model = new_model (1000, filter); gtk_string_filter_set_search (GTK_STRING_FILTER (filter), "thirte"); @@ -296,12 +305,18 @@ test_string_properties (void) gtk_string_filter_set_search (GTK_STRING_FILTER (filter), "Thirteen"); assert_model (model, "13"); + gtk_string_filter_set_match_mode (GTK_STRING_FILTER (filter), GTK_STRING_FILTER_MATCH_MODE_PREFIX); + assert_model (model, "13"); + gtk_string_filter_set_match_mode (GTK_STRING_FILTER (filter), GTK_STRING_FILTER_MATCH_MODE_EXACT); assert_model (model, "13"); gtk_string_filter_set_ignore_case (GTK_STRING_FILTER (filter), TRUE); assert_model (model, "13"); + gtk_string_filter_set_match_mode (GTK_STRING_FILTER (filter), GTK_STRING_FILTER_MATCH_MODE_PREFIX); + assert_model (model, "13"); + gtk_string_filter_set_match_mode (GTK_STRING_FILTER (filter), GTK_STRING_FILTER_MATCH_MODE_SUBSTRING); assert_model (model, "13 113 213 313 413 513 613 713 813 913"); @@ -326,9 +341,11 @@ test_bool_simple (void) assert_model (model, "3 6 9 12 15 18"); gtk_bool_filter_set_invert (GTK_BOOL_FILTER (filter), TRUE); + g_assert_true (gtk_bool_filter_get_invert (GTK_BOOL_FILTER (filter))); assert_model (model, "1 2 4 5 7 8 10 11 13 14 16 17 19 20"); gtk_bool_filter_set_invert (GTK_BOOL_FILTER (filter), FALSE); + g_assert_false (gtk_bool_filter_get_invert (GTK_BOOL_FILTER (filter))); assert_model (model, "3 6 9 12 15 18"); expr = gtk_cclosure_expression_new (G_TYPE_BOOLEAN, @@ -337,6 +354,7 @@ test_bool_simple (void) G_CALLBACK (divisible_by), GUINT_TO_POINTER (5), NULL); gtk_bool_filter_set_expression (GTK_BOOL_FILTER (filter), expr); + g_assert_true (expr == gtk_bool_filter_get_expression (GTK_BOOL_FILTER (filter))); gtk_expression_unref (expr); assert_model (model, "5 10 15 20"); diff --git a/testsuite/gtk/main.c b/testsuite/gtk/main.c index 20a3c63083..d1d3e6ee1b 100644 --- a/testsuite/gtk/main.c +++ b/testsuite/gtk/main.c @@ -9,6 +9,21 @@ test_init (void) g_assert (gtk_is_initialized () == TRUE); } +static void +test_version (void) +{ + g_assert_cmpuint (gtk_get_major_version (), ==, GTK_MAJOR_VERSION); + g_assert_cmpuint (gtk_get_minor_version (), ==, GTK_MINOR_VERSION); + g_assert_cmpuint (gtk_get_micro_version (), ==, GTK_MICRO_VERSION); + g_assert_cmpuint (gtk_get_binary_age (), ==, GTK_BINARY_AGE); + g_assert_cmpuint (gtk_get_interface_age (), ==, GTK_INTERFACE_AGE); + + g_assert_null (gtk_check_version (GTK_MAJOR_VERSION, GTK_MINOR_VERSION, GTK_MICRO_VERSION)); + g_assert_nonnull (gtk_check_version (5, 0, 0)); + g_assert_nonnull (gtk_check_version (1, 0, 0)); + g_assert_nonnull (gtk_check_version (3, 1000, 10)); +} + int main (int argc, char *argv[]) { @@ -18,6 +33,7 @@ main (int argc, char *argv[]) setlocale (LC_ALL, "C"); g_test_add_func ("/main/init", test_init); + g_test_add_func ("/main/version", test_version); return g_test_run (); } diff --git a/testsuite/gtk/sorter.c b/testsuite/gtk/sorter.c index ad6d94ebbb..6822c9ad08 100644 --- a/testsuite/gtk/sorter.c +++ b/testsuite/gtk/sorter.c @@ -405,6 +405,7 @@ test_multi (void) GtkSorter *sorter1; GtkSorter *sorter2; GtkExpression *expression; + gpointer item; model = new_model (20, NULL); assert_not_model (model, "1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20"); @@ -424,6 +425,12 @@ test_multi (void) gtk_multi_sorter_append (GTK_MULTI_SORTER (sorter), sorter1); gtk_multi_sorter_append (GTK_MULTI_SORTER (sorter), sorter2); + g_assert_true (GTK_TYPE_SORTER == g_list_model_get_item_type (G_LIST_MODEL (sorter))); + g_assert_cmpuint (2, ==, g_list_model_get_n_items (G_LIST_MODEL (sorter))); + item = g_list_model_get_item (G_LIST_MODEL (sorter), 1); + g_assert_true (item == sorter2); + g_object_unref (item); + assert_model (model, "2 4 6 8 10 12 14 16 18 20 1 3 5 7 9 11 13 15 17 19"); /* This doesn't do anything */ diff --git a/testsuite/gtk/stringlist.c b/testsuite/gtk/stringlist.c index 12169be13e..63a1f6def4 100644 --- a/testsuite/gtk/stringlist.c +++ b/testsuite/gtk/stringlist.c @@ -110,12 +110,24 @@ new_model (const char **strings) } static void +test_string_object (void) +{ + GtkStringObject *so; + + so = gtk_string_object_new ("Hello"); + g_assert_cmpstr (gtk_string_object_get_string (so), ==, "Hello"); + g_object_unref (so); +} + +static void test_create_empty (void) { GtkStringList *list; list = new_model ((const char *[]){ NULL }); + g_assert_true (g_type_is_a (g_list_model_get_item_type (G_LIST_MODEL (list)), G_TYPE_OBJECT)); + assert_model (list, ""); assert_changes (list, ""); @@ -237,6 +249,7 @@ main (int argc, char *argv[]) changes_quark = g_quark_from_static_string ("What did I see? Can I believe what I saw?"); + g_test_add_func ("/stringobject/basic", test_string_object); g_test_add_func ("/stringlist/create/empty", test_create_empty); g_test_add_func ("/stringlist/create/strv", test_create_strv); g_test_add_func ("/stringlist/create/builder", test_create_builder); diff --git a/testsuite/gtk/ui/constraints.expected b/testsuite/gtk/ui/constraints.expected new file mode 100644 index 0000000000..ff43ca4091 --- /dev/null +++ b/testsuite/gtk/ui/constraints.expected @@ -0,0 +1 @@ +SUCCESS diff --git a/testsuite/gtk/ui/constraints.ui b/testsuite/gtk/ui/constraints.ui new file mode 100644 index 0000000000..9dadad61e1 --- /dev/null +++ b/testsuite/gtk/ui/constraints.ui @@ -0,0 +1,107 @@ +<?xml version="1.0" encoding="UTF-8"?> +<interface> + <object class="GtkWindow" id="window1"> + <property name="title" translatable="yes">Constraints</property> + <child> + <object class="GtkBox"> + <property name="layout-manager"> + <object class="GtkConstraintLayout"> + <constraints> + <guide name="space" + min-width="10" min-height="10" + nat-width="100" nat-height="10" + max-width="200" max-height="20" + strength="strong"/> + <constraint target="button1" target-attribute="width" + relation="le" + constant="200" + multiplier="2.5" + strength="required"/> + <constraint target="super" target-attribute="start" + relation="eq" + source="button1" source-attribute="start" + constant="-8" + multiplier="100" + strength="strong"/> + <constraint target="button1" target-attribute="width" + relation="eq" + source="button2" source-attribute="left" + strength="medium"/> + <constraint target="button1" target-attribute="end" + relation="eq" + source="space" source-attribute="right" + strength="weak"/> + <constraint target="space" target-attribute="end" + relation="eq" + source="button2" source-attribute="center-x" + strength="required"/> + <constraint target="super" target-attribute="center-y" + relation="eq" + source="button2" source-attribute="baseline" + constant="8" + strength="required"/> + <constraint target="super" target-attribute="start" + relation="eq" + source="button3" source-attribute="start" + constant="-8" + strength="required"/> + <constraint target="super" target-attribute="end" + relation="eq" + source="button3" source-attribute="end" + constant="8" + strength="required"/> + <constraint target="super" target-attribute="top" + relation="eq" + source="button1" source-attribute="top" + constant="-8" + strength="required"/> + <constraint target="super" target-attribute="top" + relation="eq" + source="button2" source-attribute="top" + constant="-8" + strength="required"/> + <constraint target="button1" target-attribute="bottom" + relation="eq" + source="button3" source-attribute="top" + constant="-12" + strength="required"/> + <constraint target="button2" target-attribute="bottom" + relation="eq" + source="button3" source-attribute="top" + constant="-12" + strength="required"/> + <constraint target="button3" target-attribute="height" + relation="eq" + source="button1" source-attribute="height" + strength="required"/> + <constraint target="button3" target-attribute="height" + relation="eq" + source="button2" source-attribute="height" + strength="required"/> + <constraint target="super" target-attribute="bottom" + relation="eq" + source="button3" source-attribute="bottom" + constant="8" + strength="required"/> + </constraints> + </object> + </property> + <child> + <object class="GtkButton" id="button1"> + <property name="label">Child 1</property> + </object> + </child> + <child> + <object class="GtkButton" id="button2"> + <property name="label">Child 2</property> + </object> + </child> + <child> + <object class="GtkButton" id="button3"> + <property name="label">Child 3</property> + </object> + </child> + </object> + </child> + </object> +</interface> diff --git a/testsuite/tools/meson.build b/testsuite/tools/meson.build index 1369ccfedc..54b9312e7a 100644 --- a/testsuite/tools/meson.build +++ b/testsuite/tools/meson.build @@ -5,7 +5,7 @@ bash = find_program('bash', required : false) if bash.found() test_env = environment() - foreach t : ['simplify', 'simplify-3to4', 'settings'] + foreach t : ['simplify', 'simplify-3to4', 'validate', 'settings'] if get_option('install-tests') configure_file(output: t, input: '@0@.in'.format(t), @@ -44,4 +44,5 @@ if get_option('install-tests') install_subdir('simplify-data', install_dir: testexecdir) install_subdir('simplify-data-3to4', install_dir: testexecdir) + install_subdir('validate-data', install_dir: testexecdir) endif diff --git a/testsuite/tools/simplify-3to4.in b/testsuite/tools/simplify-3to4.in index 31d7da0970..35b8a8272f 100755 --- a/testsuite/tools/simplify-3to4.in +++ b/testsuite/tools/simplify-3to4.in @@ -7,13 +7,14 @@ TEST_RESULT_DIR=${TEST_RESULT_DIR:-/tmp} shopt -s nullglob TESTS=( "$TEST_DATA_DIR"/*.ui ) -echo "1..${#TESTS[*]}" +echo "1..$((2 * ${#TESTS[*]}))" I=1 for t in ${TESTS[*]}; do name=$(basename $t .ui) expected="$TEST_DATA_DIR/$name.expected" result="$TEST_RESULT_DIR/$name.out" + result2="$TEST_RESULT_DIR/$name.out2" diff="$TEST_RESULT_DIR/$name.diff" ref="$TEST_RESULT_DIR/$name.ref" @@ -28,4 +29,17 @@ for t in ${TESTS[*]}; do fi I=$((I+1)) + + cp $t $result2 + $GTK_BUILDER_TOOL simplify --3to4 --replace $result2 2>/dev/null + + if diff -u "$expected" "$result2" > "$diff"; then + echo "ok $I $name (--replace)" + rm "$diff" + else + echo "not ok $I $name (--replace)" + cp "$expected" "$ref" + fi + + I=$((I+1)) done diff --git a/testsuite/tools/simplify-data-3to4/actionbar.expected b/testsuite/tools/simplify-data-3to4/actionbar.expected new file mode 100644 index 0000000000..a063c7f2b6 --- /dev/null +++ b/testsuite/tools/simplify-data-3to4/actionbar.expected @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="UTF-8"?> +<interface> + <requires lib="gtk+" version="3.0"/> + <object class="GtkActionBar"> + <property name="visible">0</property> + <child type="start"> + <object class="GtkButton" id="button"> + <property name="visible">0</property> + <property name="icon-name">document-new</property> + </object> + </child> + </object> +</interface> diff --git a/testsuite/tools/simplify-data-3to4/actionbar.ui b/testsuite/tools/simplify-data-3to4/actionbar.ui new file mode 100644 index 0000000000..efae5962d9 --- /dev/null +++ b/testsuite/tools/simplify-data-3to4/actionbar.ui @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<interface> + <requires lib="gtk+" version="3.0"/> + <object class="GtkActionBar"> + <child> + <object class="GtkButton" id="button"> + <property name="icon-name">document-new</property> + </object> + <packing> + <property name="pack-type">start</property> + </packing> + </child> + </object> +</interface> diff --git a/testsuite/tools/simplify-data-3to4/fixed.expected b/testsuite/tools/simplify-data-3to4/fixed.expected new file mode 100644 index 0000000000..74953b12c6 --- /dev/null +++ b/testsuite/tools/simplify-data-3to4/fixed.expected @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<interface> + <requires lib="gtk+" version="3.0"/> + <object class="GtkFixed"> + <child> + <object class="GtkButton" id="button"> + <layout> + <property name="transform">translate(10, 15)</property> + </layout> + <property name="visible">0</property> + </object> + </child> + </object> +</interface> diff --git a/testsuite/tools/simplify-data-3to4/fixed.ui b/testsuite/tools/simplify-data-3to4/fixed.ui new file mode 100644 index 0000000000..699bea2e07 --- /dev/null +++ b/testsuite/tools/simplify-data-3to4/fixed.ui @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Generated with glade 3.22.2 --> +<interface> + <requires lib="gtk+" version="3.0"/> + <object class="GtkFixed"> + <property name="visible">True</property> + <child> + <object class="GtkButton" id="button"> + </object> + <packing> + <property name="x">10</property> + <property name="y">15</property> + </packing> + </child> + </object> +</interface> diff --git a/testsuite/tools/simplify-data-3to4/headerbar.expected b/testsuite/tools/simplify-data-3to4/headerbar.expected index aa7351fc06..5b642b28d8 100644 --- a/testsuite/tools/simplify-data-3to4/headerbar.expected +++ b/testsuite/tools/simplify-data-3to4/headerbar.expected @@ -4,6 +4,11 @@ <child type="titlebar"> <object class="GtkHeaderBar" id="headerbar1"> <property name="title-widget">box1</property> + <child type="end"> + <object class="GtkButton"> + <property name="label">A!</property> + </object> + </child> </object> </child> </object> diff --git a/testsuite/tools/simplify-data-3to4/headerbar.ui b/testsuite/tools/simplify-data-3to4/headerbar.ui index 9ad70329d7..c12d3d9ed1 100644 --- a/testsuite/tools/simplify-data-3to4/headerbar.ui +++ b/testsuite/tools/simplify-data-3to4/headerbar.ui @@ -7,6 +7,15 @@ <property name="visible">True</property> <property name="show-close-button">True</property> <property name="custom-title">box1</property> + <child> + <object class="GtkButton"> + <property name="visible">True</property> + <property name="label">A!</property> + </object> + <packing> + <property name="pack-type">end</property> + </packing> + </child> </object> </child> </object> diff --git a/testsuite/tools/simplify-data-3to4/overlay.expected b/testsuite/tools/simplify-data-3to4/overlay.expected new file mode 100644 index 0000000000..67e6ccade1 --- /dev/null +++ b/testsuite/tools/simplify-data-3to4/overlay.expected @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<interface> + <requires lib="gtk+" version="3.0"/> + <object class="GtkOverlay"> + <child type="overlay"> + <object class="GtkButton" id="button"> + <property name="can-target">0</property> + <property name="icon-name">document-new</property> + </object> + </child> + <property name="child"> + <object class="GtkLabel" id="label"> + <property name="visible">0</property> + </object> + </property> + </object> +</interface> diff --git a/testsuite/tools/simplify-data-3to4/overlay.ui b/testsuite/tools/simplify-data-3to4/overlay.ui new file mode 100644 index 0000000000..d83a16149f --- /dev/null +++ b/testsuite/tools/simplify-data-3to4/overlay.ui @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="UTF-8"?> +<interface> + <requires lib="gtk+" version="3.0"/> + <object class="GtkOverlay"> + <property name="visible">1</property> + <child type="overlay"> + <object class="GtkButton" id="button"> + <property name="visible">1</property> + <property name="icon-name">document-new</property> + </object> + <packing> + <property name="pass-through">True</property> + <property name="index">0</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label"/> + </child> + </object> +</interface> diff --git a/testsuite/tools/simplify-data-3to4/paned.expected b/testsuite/tools/simplify-data-3to4/paned.expected new file mode 100644 index 0000000000..a1acaae442 --- /dev/null +++ b/testsuite/tools/simplify-data-3to4/paned.expected @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<interface> + <requires lib="gtk+" version="3.0"/> + <object class="GtkPaned"> + <property name="resize-end-child">0</property> + <property name="shrink-start-child">0</property> + <child> + <object class="GtkButton" id="button"/> + </child> + <child> + <object class="GtkLabel" id="label"/> + </child> + </object> +</interface> diff --git a/testsuite/tools/simplify-data-3to4/paned.ui b/testsuite/tools/simplify-data-3to4/paned.ui new file mode 100644 index 0000000000..13f736438a --- /dev/null +++ b/testsuite/tools/simplify-data-3to4/paned.ui @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<interface> + <requires lib="gtk+" version="3.0"/> + <object class="GtkPaned"> + <property name="visible">1</property> + <child> + <object class="GtkButton" id="button"> + <property name="visible">1</property> + </object> + <packing> + <property name="resize">True</property> + <property name="shrink">False</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label"> + <property name="visible">1</property> + </object> + <packing> + <property name="resize">0</property> + <property name="shrink">1</property> + </packing> + </child> + </object> +</interface> diff --git a/testsuite/tools/simplify-data-3to4/test1.expected b/testsuite/tools/simplify-data-3to4/test1.expected deleted file mode 100644 index 0ddbcae8f5..0000000000 --- a/testsuite/tools/simplify-data-3to4/test1.expected +++ /dev/null @@ -1,10 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<interface> - <object class="GtkWindow"> - <child> - <object class="GtkLabel"> - <property name="visible">0</property> - </object> - </child> - </object> -</interface> diff --git a/testsuite/tools/simplify-data-3to4/toolbar.expected b/testsuite/tools/simplify-data-3to4/toolbar.expected new file mode 100644 index 0000000000..fa090a9284 --- /dev/null +++ b/testsuite/tools/simplify-data-3to4/toolbar.expected @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<interface> + <requires lib="gtk+" version="3.0"/> + <object class="GtkBox"> + <style> + <class name="toolbar"/> + </style> + <child> + <object class="GtkButton"> + <property name="label" translatable="yes">New</property> + <property name="icon-name">document-new</property> + <property name="tooltip-text" translatable="yes">Create a new document</property> + </object> + </child> + <child> + <object class="GtkSeparator"> + <property name="orientation">vertical</property> + </object> + </child> + <child> + <object class="GtkToggleButton"/> + </child> + </object> +</interface> diff --git a/testsuite/tools/simplify-data-3to4/toolbar.ui b/testsuite/tools/simplify-data-3to4/toolbar.ui new file mode 100644 index 0000000000..3f45466024 --- /dev/null +++ b/testsuite/tools/simplify-data-3to4/toolbar.ui @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="UTF-8"?> +<interface> + <requires lib="gtk+" version="3.0"/> + <object class="GtkToolbar"> + <property name="visible">1</property> + <child> + <object class="GtkToolButton"> + <property name="visible">1</property> + <property name="label" translatable="yes">New</property> + <property name="icon-name">document-new</property> + <property name="tooltip-text" translatable="yes">Create a new document</property> + </object> + <packing> + <property name="homogeneous">1</property> + </packing> + </child> + <child> + <object class="GtkSeparatorToolItem"> + <property name="visible">1</property> + </object> + </child> + <child> + <object class="GtkToggleToolButton"> + </object> + </child> + </object> +</interface> diff --git a/testsuite/tools/simplify.in b/testsuite/tools/simplify.in index c92c5c6d9c..e90437337b 100755 --- a/testsuite/tools/simplify.in +++ b/testsuite/tools/simplify.in @@ -7,13 +7,14 @@ TEST_RESULT_DIR=${TEST_RESULT_DIR:-/tmp} shopt -s nullglob TESTS=( "$TEST_DATA_DIR"/*.ui ) -echo "1..${#TESTS[*]}" +echo "1..$((2 * ${#TESTS[*]}))" I=1 for t in ${TESTS[*]}; do name=$(basename $t .ui) expected="$TEST_DATA_DIR/$name.expected" result="$TEST_RESULT_DIR/$name.out" + result2="$TEST_RESULT_DIR/$name.out2" diff="$TEST_RESULT_DIR/$name.diff" ref="$TEST_RESULT_DIR/$name.ref" @@ -28,4 +29,17 @@ for t in ${TESTS[*]}; do fi I=$((I+1)) + + cp $t $result2 + $GTK_BUILDER_TOOL simplify --replace $result2 2>/dev/null + + if diff -u "$expected" "$result2" > "$diff"; then + echo "ok $I $name (--replace)" + rm "$diff" + else + echo "not ok $I $name (--replace)" + cp "$expected" "$ref" + fi + + I=$((I+1)) done diff --git a/testsuite/tools/validate-data/invalid1.expected b/testsuite/tools/validate-data/invalid1.expected new file mode 100644 index 0000000000..77c70ce0dc --- /dev/null +++ b/testsuite/tools/validate-data/invalid1.expected @@ -0,0 +1 @@ +invalid1.ui:3:1 <child> is not a valid tag here diff --git a/testsuite/tools/validate-data/invalid1.ui b/testsuite/tools/validate-data/invalid1.ui new file mode 100644 index 0000000000..0b969c34d8 --- /dev/null +++ b/testsuite/tools/validate-data/invalid1.ui @@ -0,0 +1,5 @@ +<interface> + <child> + <object class="GtkLabel"/> + </child> +</interface> diff --git a/testsuite/tools/validate-data/invalid2.expected b/testsuite/tools/validate-data/invalid2.expected new file mode 100644 index 0000000000..c05e26fece --- /dev/null +++ b/testsuite/tools/validate-data/invalid2.expected @@ -0,0 +1 @@ +invalid2.ui:4:1 <object> is not a valid tag here diff --git a/testsuite/tools/validate-data/invalid2.ui b/testsuite/tools/validate-data/invalid2.ui new file mode 100644 index 0000000000..887b3bcd4b --- /dev/null +++ b/testsuite/tools/validate-data/invalid2.ui @@ -0,0 +1,6 @@ +<interface> + <object class="GtkBox"> + <object class="GtkButton"> + </object> + </object> +</interface> diff --git a/testsuite/tools/validate-data/invalid3.expected b/testsuite/tools/validate-data/invalid3.expected new file mode 100644 index 0000000000..824ce933e6 --- /dev/null +++ b/testsuite/tools/validate-data/invalid3.expected @@ -0,0 +1 @@ +invalid3.ui:3:1 <object> requires attribute 'class' diff --git a/testsuite/tools/validate-data/invalid3.ui b/testsuite/tools/validate-data/invalid3.ui new file mode 100644 index 0000000000..9deb45b268 --- /dev/null +++ b/testsuite/tools/validate-data/invalid3.ui @@ -0,0 +1,4 @@ +<interface> + <object> + </object> +</interface> diff --git a/testsuite/tools/validate-data/invalid4.expected b/testsuite/tools/validate-data/invalid4.expected new file mode 100644 index 0000000000..7a565ffb3b --- /dev/null +++ b/testsuite/tools/validate-data/invalid4.expected @@ -0,0 +1 @@ +Gtk-WARNING: Failed to find accessible property “text”: Could not parse enum: 'text' diff --git a/testsuite/tools/validate-data/invalid4.ui b/testsuite/tools/validate-data/invalid4.ui new file mode 100644 index 0000000000..21e3248b73 --- /dev/null +++ b/testsuite/tools/validate-data/invalid4.ui @@ -0,0 +1,7 @@ +<interface> + <object class="GtkBox"> + <accessibility> + <property name="text">Download</property> + </accessibility> + </object> +</interface> diff --git a/testsuite/tools/validate-data/valid1.expected b/testsuite/tools/validate-data/valid1.expected new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/testsuite/tools/validate-data/valid1.expected diff --git a/testsuite/tools/validate-data/valid1.ui b/testsuite/tools/validate-data/valid1.ui new file mode 100644 index 0000000000..2a9a3f594c --- /dev/null +++ b/testsuite/tools/validate-data/valid1.ui @@ -0,0 +1,3 @@ +<interface> + <object class="GtkLabel"/> +</interface> diff --git a/testsuite/tools/validate-data/valid2.expected b/testsuite/tools/validate-data/valid2.expected new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/testsuite/tools/validate-data/valid2.expected diff --git a/testsuite/tools/validate-data/valid2.ui b/testsuite/tools/validate-data/valid2.ui new file mode 100644 index 0000000000..e0f4cf75df --- /dev/null +++ b/testsuite/tools/validate-data/valid2.ui @@ -0,0 +1,4 @@ +<interface> + <template class="GtkEmojiChooser" parent="GtkPopover"> + </template> +</interface> diff --git a/testsuite/tools/validate.in b/testsuite/tools/validate.in new file mode 100755 index 0000000000..82de80e31d --- /dev/null +++ b/testsuite/tools/validate.in @@ -0,0 +1,35 @@ +#! /bin/bash + +GTK_BUILDER_TOOL=${GTK_BUILDER_TOOL:-gtk4-builder-tool} +TEST_DATA_DIR=${G_TEST_SRCDIR:-.}/validate-data +TEST_RESULT_DIR=${TEST_RESULT_DIR:-/tmp} + +shopt -s nullglob +TESTS=( "$TEST_DATA_DIR"/*.ui ) + +echo "1..${#TESTS[*]}" + +I=1 +for t in ${TESTS[*]}; do + name=$(basename $t .ui) + expected="$TEST_DATA_DIR/$name.expected" + result="$TEST_RESULT_DIR/$name.out" + diff="$TEST_RESULT_DIR/$name.diff" + ref="$TEST_RESULT_DIR/$name.ref" + + cd $TEST_DATA_DIR + + $GTK_BUILDER_TOOL validate $(basename $t) 2>$result + + cd $OLDPWD + + if diff -u "$expected" "$result" > "$diff"; then + echo "ok $I $name" + rm "$diff" + else + echo "not ok $I $name" + cp "$expected" "$ref" + fi + + I=$((I+1)) +done |