summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2020-11-02 11:52:13 +0000
committerMatthias Clasen <mclasen@redhat.com>2020-11-02 11:52:13 +0000
commitefc314196d639a6216add81b440495a556f2183e (patch)
treec39976ca1d9e65c27685a07e4a9c6dec16ca3e40
parent924796b47866de28b4288521153398daf6339993 (diff)
parent403a70ca89d9666c4eff1554455eb4e22b120dbf (diff)
downloadgtk+-efc314196d639a6216add81b440495a556f2183e.tar.gz
Merge branch 'matthiasc/for-master' into 'master'
Matthiasc/for master See merge request GNOME/gtk!2769
-rw-r--r--NEWS34
-rw-r--r--config.h.meson5
-rw-r--r--demos/gtk-demo/constraints.c12
-rw-r--r--demos/gtk-demo/constraints.ui105
-rw-r--r--demos/gtk-demo/constraints2.c2
-rw-r--r--demos/gtk-demo/constraints3.c4
-rw-r--r--demos/gtk-demo/constraints4.c72
-rw-r--r--demos/gtk-demo/demo.gresource.xml4
-rw-r--r--demos/gtk-demo/meson.build1
-rw-r--r--gsk/gskrenderer.c6
-rw-r--r--gsk/meson.build2
-rw-r--r--gtk/css/gtkcsstokenizer.c2
-rw-r--r--gtk/css/meson.build1
-rw-r--r--gtk/gtkbuildable.c29
-rw-r--r--gtk/gtkbuildableprivate.h4
-rw-r--r--gtk/gtkconstraintlayout.c54
-rw-r--r--gtk/gtkexpression.c4
-rw-r--r--gtk/gtkhsla.c18
-rw-r--r--gtk/gtkhslaprivate.h5
-rw-r--r--gtk/gtkrender.c1
-rw-r--r--gtk/gtksettings.c1
-rw-r--r--gtk/gtkstringlist.c22
-rw-r--r--gtk/gtkwidget.c2
-rw-r--r--gtk/tools/gtk-builder-tool-simplify.c467
-rw-r--r--gtk/tools/gtk-builder-tool-validate.c2
-rw-r--r--gtk/tools/gtk-builder-tool.c55
-rw-r--r--testsuite/css/change/meson.build11
-rw-r--r--testsuite/css/data.c37
-rw-r--r--testsuite/css/nodes/meson.build11
-rw-r--r--testsuite/css/parser/cdo-cdc.css7
-rw-r--r--testsuite/css/parser/cdo-cdc.ref.css3
-rw-r--r--testsuite/css/parser/meson.build16
-rw-r--r--testsuite/css/parser/url-invalid1.css4
-rw-r--r--testsuite/css/parser/url-invalid1.errors1
-rw-r--r--testsuite/css/parser/url-invalid1.ref.css0
-rw-r--r--testsuite/css/parser/url-invalid2.css4
-rw-r--r--testsuite/css/parser/url-invalid2.errors1
-rw-r--r--testsuite/css/parser/url-invalid2.ref.css0
-rw-r--r--testsuite/css/parser/url-valid1.css3
-rw-r--r--testsuite/css/parser/url-valid1.ref.css3
-rw-r--r--testsuite/css/parser/url-valid2.css4
-rw-r--r--testsuite/css/parser/url-valid2.ref.css3
-rw-r--r--testsuite/css/parser/url-valid3.css4
-rw-r--r--testsuite/css/parser/url-valid3.ref.css3
-rw-r--r--testsuite/css/style/meson.build11
-rw-r--r--testsuite/gdk/displaymanager.c55
-rw-r--r--testsuite/gdk/keysyms.c74
-rw-r--r--testsuite/gdk/meson.build2
-rw-r--r--testsuite/gdk/rectangle.c44
-rw-r--r--testsuite/gdk/seat.c39
-rw-r--r--testsuite/gdk/texture.c120
-rw-r--r--testsuite/gtk/expression.c70
-rw-r--r--testsuite/gtk/filter.c30
-rw-r--r--testsuite/gtk/main.c16
-rw-r--r--testsuite/gtk/sorter.c7
-rw-r--r--testsuite/gtk/stringlist.c13
-rw-r--r--testsuite/gtk/ui/constraints.expected1
-rw-r--r--testsuite/gtk/ui/constraints.ui107
-rw-r--r--testsuite/tools/meson.build3
-rwxr-xr-xtestsuite/tools/simplify-3to4.in16
-rw-r--r--testsuite/tools/simplify-data-3to4/actionbar.expected13
-rw-r--r--testsuite/tools/simplify-data-3to4/actionbar.ui14
-rw-r--r--testsuite/tools/simplify-data-3to4/fixed.expected14
-rw-r--r--testsuite/tools/simplify-data-3to4/fixed.ui16
-rw-r--r--testsuite/tools/simplify-data-3to4/headerbar.expected5
-rw-r--r--testsuite/tools/simplify-data-3to4/headerbar.ui9
-rw-r--r--testsuite/tools/simplify-data-3to4/overlay.expected17
-rw-r--r--testsuite/tools/simplify-data-3to4/overlay.ui20
-rw-r--r--testsuite/tools/simplify-data-3to4/paned.expected14
-rw-r--r--testsuite/tools/simplify-data-3to4/paned.ui25
-rw-r--r--testsuite/tools/simplify-data-3to4/test1.expected10
-rw-r--r--testsuite/tools/simplify-data-3to4/toolbar.expected24
-rw-r--r--testsuite/tools/simplify-data-3to4/toolbar.ui27
-rwxr-xr-xtestsuite/tools/simplify.in16
-rw-r--r--testsuite/tools/validate-data/invalid1.expected1
-rw-r--r--testsuite/tools/validate-data/invalid1.ui5
-rw-r--r--testsuite/tools/validate-data/invalid2.expected1
-rw-r--r--testsuite/tools/validate-data/invalid2.ui6
-rw-r--r--testsuite/tools/validate-data/invalid3.expected1
-rw-r--r--testsuite/tools/validate-data/invalid3.ui4
-rw-r--r--testsuite/tools/validate-data/invalid4.expected1
-rw-r--r--testsuite/tools/validate-data/invalid4.ui7
-rw-r--r--testsuite/tools/validate-data/valid1.expected0
-rw-r--r--testsuite/tools/validate-data/valid1.ui3
-rw-r--r--testsuite/tools/validate-data/valid2.expected0
-rw-r--r--testsuite/tools/validate-data/valid2.ui4
-rwxr-xr-xtestsuite/tools/validate.in35
87 files changed, 1548 insertions, 381 deletions
diff --git a/NEWS b/NEWS
index c1c3eb7c75..28a211ac31 100644
--- a/NEWS
+++ b/NEWS
@@ -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