Compare commits

...

23 Commits

Author SHA1 Message Date
Matthias Clasen
40b34c76e6 widget: Treat key controllers like gestures
For the purposes of cutting short event handling,
treat key controllers like gestures. It is fairly
common to have multiple key controllers on a widget,
and the event handling can inadvertently cut short
e.g. by modifier key releases that return TRUE
from handle_event.

Closes: https://gitlab.gnome.org/GNOME/gtk/issues/1884
2019-05-12 19:30:56 +00:00
Matthias Clasen
1318d3748a about dialog: Fix page visibility
The handling of page visibility broke when the dialog
was ported to GtkStackPage in 52b83ac553.

Closes: https://gitlab.gnome.org/GNOME/gtk/issues/1877
2019-05-12 18:20:52 +00:00
Matthias Clasen
04754d753b Reinstate the activate-focus keybinding
Commit 3b62d9c027 was a bit overzealous in
removing not just the public API for activating the focus
widget, but also the plumbing needed to make the keybinding
work.

Closes: https://gitlab.gnome.org/GNOME/gtk/issues/1879
2019-05-12 18:07:33 +00:00
Benjamin Otte
f8c1f7173a Merge branch 'wip/otte/for-master' into 'master'
Wip/otte/for master

See merge request GNOME/gtk!832
2019-05-12 16:27:47 +00:00
Benjamin Otte
a04ea72ca1 rendernodeparser: Default color to black
Nobody wants to render transparent text.
2019-05-12 17:28:19 +02:00
Benjamin Otte
0886ade182 cssparser: Make gsk_renderer_consume_url() return a string
We don't want to return a GFile because GFile can't handle can't deal
with data: urls.
That makes the code a bit more complicated that doesn't deal with those
URLs, but it makes the other code actually work.

GtkCssImageUrl also now decodes data urls immediately instead of only at
the first load. So don't use data urls if you care about performance.
2019-05-12 17:28:19 +02:00
Benjamin Otte
0103704171 rendernodeparser: Use parser blocks
Instead of trying to do error handling manually, use the semicolon
blocks feature provided by GtkCssParser.
2019-05-12 17:28:19 +02:00
Benjamin Otte
b76d5bda37 cssparser: Don't allow commit_token() on block EOF
When we're at the end of a block and gtk_css_parser_get_token() returns
NULL, gtk_css_parser_commit_token() still consumed the next token.

It does not anymore.

This does not affect the CSS parser, but it exposes issues with the
render parser, which previously just consumed too many closing } tokens
in the past.
2019-05-12 17:28:19 +02:00
Benjamin Otte
6f6b07aaae testsuite: Stop using g_test_bug()
The calls used old bugzilla URLs and nobody cared about that.
So apparently they are very unused.

There's also a potential conflict between gitlab and bugzilla URLs and
what base bug to use there.

The old usages have been converted to comments.
2019-05-12 17:28:18 +02:00
Benjamin Otte
4bccd17941 node-editor: Report all errors in tooltip
Don't just report the first one.
2019-05-12 17:27:01 +02:00
Benjamin Otte
0049b39375 node-editor: Don't remove all text tags when saving 2019-05-12 17:27:01 +02:00
Benjamin Otte
63578d832a testsuite: Don't die on the first error
Continue running the test, just mark it as a failure.
2019-05-12 17:27:01 +02:00
Benjamin Otte
3a373b9b33 rendernodeparser: Parse images differently
Instead of encoding the raw data, encode the full image to a PNG.
And instead of stuffing that encoding into a string, use a full
data: url.
And then remove the width and height properties, because they're now
implicitly included in the data.
And then change the parser to match.
And because the parser now parses regular urls on top of data: urls, we
can now load any random file.
2019-05-12 17:27:01 +02:00
Benjamin Otte
8be95ca348 css: Add data URL parsing to images 2019-05-12 17:27:01 +02:00
Benjamin Otte
5da58ba47d css: Add gtk_css_data_url_parse()
This surprisingly decodes data URLs.
2019-05-12 17:27:01 +02:00
Benjamin Otte
4505f4f17b rendernode: Set EXTEND_PAD when drawing textures 2019-05-12 15:41:53 +02:00
Christoph Reiter
e0e9d8c6b5 Merge branch 'ci-master-fedora-30' into 'master'
CI: update docker image to Fedora 30

See merge request GNOME/gtk!802
2019-05-10 14:19:16 +00:00
Christoph Reiter
24fcfa91b1 CI: update docker image to fedora 30
So we don't have to build glib as a subproject.
2019-05-10 15:48:33 +02:00
Matthias Clasen
4f0ea69e9b settings: Update docs
We no longer create settings on demand.
2019-05-09 14:53:32 +00:00
Matthias Clasen
f2e197a389 css provider: Stop mentioning key themes
We no longer do this.
2019-05-09 14:53:32 +00:00
Benjamin Otte
777beb0d0a glrenderer: Ensure current context for debug stuff 2019-05-08 19:47:40 +02:00
Benjamin Otte
1fa4b9f58c rendernode: Parse repeat nodes 2019-05-08 19:47:40 +02:00
Benjamin Otte
9117ee83eb node-editor: Never scale nodes up
Scaling down is fine so one can see the nodes, but scaling up just
makes the nodes wrong for no reason at all.
2019-05-08 19:47:40 +02:00
58 changed files with 804 additions and 418 deletions

View File

@@ -13,7 +13,7 @@ stages:
- subprojects/pango/
fedora-x86_64:
image: registry.gitlab.gnome.org/gnome/gtk/master:v5
image: registry.gitlab.gnome.org/gnome/gtk/master:v6
stage: build
script:
- bash -x ./.gitlab-ci/test-docker.sh
@@ -101,7 +101,7 @@ flatpak-master:icon-browser:
<<: *flatpak-master
pages:
image: registry.gitlab.gnome.org/gnome/gtk/master:v4
image: registry.gitlab.gnome.org/gnome/gtk/master:v6
stage: deploy
script:
- meson -Ddocumentation=true _build .

View File

@@ -1,4 +1,4 @@
FROM fedora:29
FROM fedora:30
RUN dnf -y install \
hicolor-icon-theme \
@@ -11,6 +11,7 @@ RUN dnf -y install \
ccache \
colord-devel \
cups-devel \
dbus-daemon \
dejavu-sans-mono-fonts \
desktop-file-utils \
elfutils-libelf-devel \
@@ -59,6 +60,7 @@ RUN dnf -y install \
pango-devel \
pcre-devel \
python3 \
python3-jinja2 \
python3-pip \
python3-wheel \
redhat-rpm-config \
@@ -71,9 +73,7 @@ RUN dnf -y install \
xorg-x11-server-Xvfb \
&& dnf clean all
RUN pip3 install meson==0.50.0
RUN pip3 install jinja2
RUN pip3 install meson==0.50.1
ARG HOST_USER_ID=5555
ENV HOST_USER_ID ${HOST_USER_ID}

View File

@@ -2,7 +2,7 @@
set -e
TAG="registry.gitlab.gnome.org/gnome/gtk/master:v4"
TAG="registry.gitlab.gnome.org/gnome/gtk/master:v6"
sudo docker build --build-arg HOST_USER_ID="$UID" --tag "${TAG}" \
--file "Dockerfile" .

View File

@@ -68,11 +68,20 @@ get_current_text (GtkTextBuffer *buffer)
gtk_text_buffer_get_start_iter (buffer, &start);
gtk_text_buffer_get_end_iter (buffer, &end);
gtk_text_buffer_remove_all_tags (buffer, &start, &end);
return gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
}
static void
text_buffer_remove_all_tags (GtkTextBuffer *buffer)
{
GtkTextIter start, end;
gtk_text_buffer_get_start_iter (buffer, &start);
gtk_text_buffer_get_end_iter (buffer, &end);
gtk_text_buffer_remove_all_tags (buffer, &start, &end);
}
static void
deserialize_error_func (const GtkCssSection *section,
const GError *error,
@@ -146,6 +155,7 @@ text_changed (GtkTextBuffer *buffer,
g_array_remove_range (self->errors, 0, self->errors->len);
text = get_current_text (self->text_buffer);
text_buffer_remove_all_tags (self->text_buffer);
bytes = g_bytes_new_take (text, strlen (text));
/* If this is too slow, go fix the parser performance */
@@ -255,6 +265,7 @@ text_view_query_tooltip_cb (GtkWidget *widget,
{
GtkTextIter iter;
guint i;
GString *text;
if (keyboard_tip)
{
@@ -272,6 +283,8 @@ text_view_query_tooltip_cb (GtkWidget *widget,
gtk_text_view_get_iter_at_position (GTK_TEXT_VIEW (self->text_view), &iter, &trailing, bx, by);
}
text = g_string_new ("");
for (i = 0; i < self->errors->len; i ++)
{
const TextViewError *e = &g_array_index (self->errors, TextViewError, i);
@@ -282,12 +295,23 @@ text_view_query_tooltip_cb (GtkWidget *widget,
if (gtk_text_iter_in_range (&iter, &start_iter, &end_iter))
{
gtk_tooltip_set_text (tooltip, e->message);
return TRUE;
if (text->len > 0)
g_string_append (text, "\n");
g_string_append (text, e->message);
}
}
return FALSE;
if (text->len > 0)
{
gtk_tooltip_set_text (tooltip, text->str);
g_string_free (text, TRUE);
return TRUE;
}
else
{
g_string_free (text, TRUE);
return FALSE;
}
}
gboolean
@@ -620,6 +644,9 @@ node_editor_window_create_renderer_widget (gpointer item,
gtk_container_add (GTK_CONTAINER (box), label);
picture = gtk_picture_new_for_paintable (paintable);
/* don't ever scale up, we want to be as accurate as possible */
gtk_widget_set_halign (picture, GTK_ALIGN_CENTER);
gtk_widget_set_valign (picture, GTK_ALIGN_CENTER);
gtk_container_add (GTK_CONTAINER (box), picture);
row = gtk_list_box_row_new ();

View File

@@ -3145,6 +3145,7 @@ gsk_gl_renderer_render_texture (GskRenderer *renderer,
g_return_val_if_fail (self->gl_context != NULL, NULL);
gdk_gl_context_make_current (self->gl_context);
gdk_gl_context_push_debug_group_printf (self->gl_context,
"Render %s<%p> to texture", root->node_class->type_name, root);
@@ -3152,7 +3153,6 @@ gsk_gl_renderer_render_texture (GskRenderer *renderer,
height = ceilf (viewport->size.height);
self->scale_factor = gdk_surface_get_scale_factor (gsk_renderer_get_surface (renderer));
gdk_gl_context_make_current (self->gl_context);
/* Prepare our framebuffer */
gsk_gl_driver_begin_frame (self->gl_driver);
@@ -3204,6 +3204,7 @@ gsk_gl_renderer_render (GskRenderer *renderer,
if (self->gl_context == NULL)
return;
gdk_gl_context_make_current (self->gl_context);
gdk_gl_context_push_debug_group_printf (self->gl_context,
"Render root node %p", root);

View File

@@ -636,6 +636,7 @@ gsk_texture_node_draw (GskRenderNode *node,
{
GskTextureNode *self = (GskTextureNode *) node;
cairo_surface_t *surface;
cairo_pattern_t *pattern;
surface = gdk_texture_download_surface (self->texture);
@@ -646,11 +647,14 @@ gsk_texture_node_draw (GskRenderNode *node,
node->bounds.size.width / gdk_texture_get_width (self->texture),
node->bounds.size.height / gdk_texture_get_height (self->texture));
cairo_set_source_surface (cr, surface, 0, 0);
pattern = cairo_pattern_create_for_surface (surface);
cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD);
cairo_set_source (cr, pattern);
cairo_paint (cr);
cairo_restore (cr);
cairo_pattern_destroy (pattern);
cairo_surface_destroy (surface);
}

View File

@@ -1,13 +1,16 @@
#include "gskrendernodeparserprivate.h"
#include <gdk/gdkrgbaprivate.h>
#include <gtk/css/gtkcss.h>
#include "gtk/css/gtkcssparserprivate.h"
#include "gskroundedrectprivate.h"
#include "gskrendernodeprivate.h"
#include "gsktransformprivate.h"
#include "gdk/gdkrgbaprivate.h"
#include "gdk/gdktextureprivate.h"
#include <gtk/css/gtkcss.h>
#include "gtk/css/gtkcssparserprivate.h"
#include "gtk/css/gtkcssdataurlprivate.h"
typedef struct _Declaration Declaration;
struct _Declaration
@@ -18,17 +21,12 @@ struct _Declaration
};
static gboolean
parse_semicolon (GtkCssParser *parser)
check_eof (GtkCssParser *parser)
{
const GtkCssToken *token;
token = gtk_css_parser_get_token (parser);
if (gtk_css_token_is (token, GTK_CSS_TOKEN_EOF))
{
gtk_css_parser_warn_syntax (parser, "No ';' at end of block");
return TRUE;
}
else if (!gtk_css_token_is (token, GTK_CSS_TOKEN_SEMICOLON))
if (!gtk_css_token_is (token, GTK_CSS_TOKEN_EOF))
{
gtk_css_parser_error_syntax (parser, "Expected ';' at end of statement");
return FALSE;
@@ -62,7 +60,7 @@ parse_rect (GtkCssParser *parser,
graphene_rect_t r;
if (!parse_rect_without_semicolon (parser, &r) ||
!parse_semicolon (parser))
!check_eof (parser))
return FALSE;
graphene_rect_init_from_rect (out_rect, &r);
@@ -70,35 +68,70 @@ parse_rect (GtkCssParser *parser,
}
static gboolean
parse_data (GtkCssParser *parser,
gpointer out_data)
parse_texture (GtkCssParser *parser,
gpointer out_data)
{
const GtkCssToken *token;
struct {
guchar *data;
gsize data_len;
} *texture_data = out_data;
GdkTexture *texture;
GError *error = NULL;
GtkCssLocation start_location;
char *url, *scheme;
token = gtk_css_parser_get_token (parser);
if (!gtk_css_token_is (token, GTK_CSS_TOKEN_STRING))
start_location = *gtk_css_parser_get_start_location (parser);
url = gtk_css_parser_consume_url (parser);
if (url == NULL)
return FALSE;
if (!g_str_has_prefix (token->string.string, "data:;base64,"))
scheme = g_uri_parse_scheme (url);
if (scheme && g_ascii_strcasecmp (scheme, "data") == 0)
{
gtk_css_parser_error_value (parser, "Only base64 encoded data is allowed");
GInputStream *stream;
GdkPixbuf *pixbuf;
GBytes *bytes;
texture = NULL;
bytes = gtk_css_data_url_parse (url, NULL, &error);
if (bytes)
{
stream = g_memory_input_stream_new_from_bytes (bytes);
pixbuf = gdk_pixbuf_new_from_stream (stream, NULL, &error);
g_object_unref (stream);
if (pixbuf != NULL)
{
texture = gdk_texture_new_for_pixbuf (pixbuf);
g_object_unref (pixbuf);
}
}
}
else
{
GFile *file;
file = gtk_css_parser_resolve_url (parser, url);
texture = gdk_texture_new_from_file (file, &error);
g_object_unref (file);
}
g_free (scheme);
g_free (url);
if (texture == NULL)
{
gtk_css_parser_emit_error (parser,
&start_location,
gtk_css_parser_get_end_location (parser),
error);
g_clear_error (&error);
return FALSE;
}
texture_data->data = g_base64_decode (token->string.string + strlen ("data:;base64,"),
&texture_data->data_len);
gtk_css_parser_consume_token (parser);
if (!parse_semicolon (parser))
if (!check_eof (parser))
{
g_free (texture_data->data);
g_object_unref (texture);
return FALSE;
}
*(GdkTexture **) out_data = texture;
return TRUE;
}
@@ -116,7 +149,7 @@ parse_rounded_rect (GtkCssParser *parser,
if (!gtk_css_parser_try_delim (parser, '/'))
{
if (!parse_semicolon (parser))
if (!check_eof (parser))
return FALSE;
gsk_rounded_rect_init_from_rect (out_rect, &r, 0);
return TRUE;
@@ -171,7 +204,7 @@ parse_rounded_rect (GtkCssParser *parser,
corners[i].height = corners[i].width;
}
if (!parse_semicolon (parser))
if (!check_eof (parser))
return FALSE;
gsk_rounded_rect_init (out_rect, &r, &corners[0], &corners[1], &corners[2], &corners[3]);
@@ -186,7 +219,7 @@ parse_color (GtkCssParser *parser,
GdkRGBA color;
if (!gdk_rgba_parser_parse (parser, &color) ||
!parse_semicolon (parser))
!check_eof (parser))
return FALSE;
*(GdkRGBA *) out_color = color;
@@ -201,7 +234,7 @@ parse_double (GtkCssParser *parser,
double d;
if (!gtk_css_parser_consume_number (parser, &d) ||
!parse_semicolon (parser))
!check_eof (parser))
return FALSE;
*(double *) out_double = d;
@@ -217,7 +250,7 @@ parse_point (GtkCssParser *parser,
if (!gtk_css_parser_consume_number (parser, &x) ||
!gtk_css_parser_consume_number (parser, &y) ||
!parse_semicolon (parser))
!check_eof (parser))
return FALSE;
graphene_point_init (out_point, x, y);
@@ -232,7 +265,7 @@ parse_transform (GtkCssParser *parser,
GskTransform *transform;
if (!gsk_transform_parser_parse (parser, &transform) ||
!parse_semicolon (parser))
!check_eof (parser))
{
gsk_transform_unref (transform);
return FALSE;
@@ -258,7 +291,7 @@ parse_string (GtkCssParser *parser,
s = g_strdup (token->string.string);
gtk_css_parser_consume_token (parser);
if (!parse_semicolon (parser))
if (!check_eof (parser))
{
g_free (s);
return FALSE;
@@ -313,7 +346,7 @@ parse_stops (GtkCssParser *parser,
g_array_free (*(GArray **) out_stops, TRUE);
*(GArray **) out_stops = stops;
return parse_semicolon (parser);
return check_eof (parser);
error:
g_array_free (stops, TRUE);
@@ -333,7 +366,7 @@ parse_colors4 (GtkCssParser *parser,
return FALSE;
}
return parse_semicolon (parser);
return check_eof (parser);
}
static gboolean
@@ -371,7 +404,7 @@ parse_shadows (GtkCssParser *parser,
break;
}
return parse_semicolon (parser);
return check_eof (parser);
}
static const struct
@@ -407,7 +440,7 @@ parse_blend_mode (GtkCssParser *parser,
{
if (gtk_css_parser_try_ident (parser, blend_modes[i].name))
{
if (!parse_semicolon (parser))
if (!check_eof (parser))
return FALSE;
*(GskBlendMode *) out_mode = blend_modes[i].mode;
return TRUE;
@@ -444,7 +477,7 @@ parse_font (GtkCssParser *parser,
/* Skip font name token */
gtk_css_parser_consume_token (parser);
return parse_semicolon (parser);
return check_eof (parser);
}
static gboolean
@@ -497,7 +530,7 @@ parse_glyphs (GtkCssParser *parser,
*((PangoGlyphString **)out_glyphs) = glyph_string;
return parse_semicolon (parser);
return check_eof (parser);
}
static gboolean
@@ -517,15 +550,15 @@ parse_container_node (GtkCssParser *parser)
token = gtk_css_parser_get_token (parser))
{
node = NULL;
/* We don't wand a semicolon here, but the parse_node function will figure
* that out itself and return an error if we encounter one.
*/
gtk_css_parser_start_semicolon_block (parser, GTK_CSS_TOKEN_OPEN_CURLY);
if (parse_node (parser, &node))
{
g_ptr_array_add (nodes, node);
}
else
{
gtk_css_parser_skip_until (parser, GTK_CSS_TOKEN_OPEN_CURLY);
gtk_css_parser_skip (parser);
}
g_ptr_array_add (nodes, node);
gtk_css_parser_end_block (parser);
}
node = gsk_container_node_new ((GskRenderNode **) nodes->pdata, nodes->len);
@@ -535,25 +568,6 @@ parse_container_node (GtkCssParser *parser)
return node;
}
static void
parse_declarations_sync (GtkCssParser *parser)
{
const GtkCssToken *token;
for (token = gtk_css_parser_get_token (parser);
!gtk_css_token_is (token, GTK_CSS_TOKEN_EOF);
token = gtk_css_parser_get_token (parser))
{
if (gtk_css_token_is (token, GTK_CSS_TOKEN_SEMICOLON) ||
gtk_css_token_is (token, GTK_CSS_TOKEN_OPEN_CURLY))
{
gtk_css_parser_skip (parser);
break;
}
gtk_css_parser_skip (parser);
}
}
static guint
parse_declarations (GtkCssParser *parser,
const Declaration *declarations,
@@ -569,6 +583,8 @@ parse_declarations (GtkCssParser *parser,
!gtk_css_token_is (token, GTK_CSS_TOKEN_EOF);
token = gtk_css_parser_get_token (parser))
{
gtk_css_parser_start_semicolon_block (parser, GTK_CSS_TOKEN_OPEN_CURLY);
for (i = 0; i < n_declarations; i++)
{
if (gtk_css_token_is_ident (token, declarations[i].name))
@@ -578,7 +594,6 @@ parse_declarations (GtkCssParser *parser,
if (!gtk_css_token_is (token, GTK_CSS_TOKEN_COLON))
{
gtk_css_parser_error_syntax (parser, "Expected ':' after variable declaration");
parse_declarations_sync (parser);
}
else
{
@@ -587,8 +602,6 @@ parse_declarations (GtkCssParser *parser,
gtk_css_parser_warn_syntax (parser, "Variable \"%s\" defined multiple times", declarations[i].name);
if (declarations[i].parse_func (parser, declarations[i].result))
parsed |= (1 << i);
else
parse_declarations_sync (parser);
}
break;
}
@@ -599,8 +612,9 @@ parse_declarations (GtkCssParser *parser,
gtk_css_parser_error_syntax (parser, "No variable named \"%s\"", token->string.string);
else
gtk_css_parser_error_syntax (parser, "Expected a variable name");
parse_declarations_sync (parser);
}
gtk_css_parser_end_block (parser);
}
return parsed;
@@ -691,35 +705,21 @@ static GskRenderNode *
parse_texture_node (GtkCssParser *parser)
{
graphene_rect_t bounds = GRAPHENE_RECT_INIT (0, 0, 0, 0);
struct {
guchar *data;
gsize data_len;
} texture_data = { NULL, 0 };
double width = 0.0;
double height = 0.0;
GdkTexture *texture = NULL;
const Declaration declarations[] = {
{ "bounds", parse_rect, &bounds },
{ "width", parse_double, &width },
{ "height", parse_double, &height },
{ "texture", parse_data, &texture_data }
{ "texture", parse_texture, &texture }
};
GdkTexture *texture;
GdkPixbuf *pixbuf;
GskRenderNode *node;
parse_declarations (parser, declarations, G_N_ELEMENTS(declarations));
pixbuf = gdk_pixbuf_new_from_data (texture_data.data,
GDK_COLORSPACE_RGB,
TRUE,
8,
(int)width,
(int)height,
4 * (int)width,
(GdkPixbufDestroyNotify)g_free, NULL);
if (texture == NULL)
{
gtk_css_parser_error_syntax (parser, "Missing \"texture\" property definition");
return NULL;
}
texture = gdk_texture_new_for_pixbuf (pixbuf);
g_object_unref (pixbuf);
node = gsk_texture_node_new (texture, &bounds);
g_object_unref (texture);
@@ -903,13 +903,46 @@ parse_blend_node (GtkCssParser *parser)
return result;
}
static GskRenderNode *
parse_repeat_node (GtkCssParser *parser)
{
GskRenderNode *child = NULL;
graphene_rect_t bounds = GRAPHENE_RECT_INIT (0, 0, 0, 0);
graphene_rect_t child_bounds = GRAPHENE_RECT_INIT (0, 0, 0, 0);
const Declaration declarations[] = {
{ "child", parse_node, &child },
{ "bounds", parse_rect, &bounds },
{ "child-bounds", parse_rect, &child_bounds },
};
GskRenderNode *result;
guint parse_result;
parse_result = parse_declarations (parser, declarations, G_N_ELEMENTS(declarations));
if (child == NULL)
{
gtk_css_parser_error_syntax (parser, "Missing \"child\" property definition");
return NULL;
}
if (!(parse_result & (1 << 1)))
gsk_render_node_get_bounds (child, &bounds);
if (!(parse_result & (1 << 2)))
gsk_render_node_get_bounds (child, &child_bounds);
result = gsk_repeat_node_new (&bounds, child, &child_bounds);
gsk_render_node_unref (child);
return result;
}
static GskRenderNode *
parse_text_node (GtkCssParser *parser)
{
PangoFont *font = NULL;
double x = 0;
double y = 0;
GdkRGBA color = { 0, 0, 0, 0 };
GdkRGBA color = { 0, 0, 0, 1 };
PangoGlyphString *glyphs = NULL;
const Declaration declarations[] = {
{ "font", parse_font, &font },
@@ -1091,53 +1124,46 @@ parse_node (GtkCssParser *parser,
{ "blur", parse_blur_node },
{ "debug", parse_debug_node },
{ "blend", parse_blend_node },
#if 0
{ "repeat", parse_repeat_node },
#if 0
{ "cairo", parse_cairo_node },
#endif
};
GskRenderNode **node_p = out_node;
const GtkCssToken *token;
guint i;
token = gtk_css_parser_get_token (parser);
if (!gtk_css_token_is (token, GTK_CSS_TOKEN_IDENT))
{
gtk_css_parser_error_syntax (parser, "Expected a node name");
return FALSE;
}
for (i = 0; i < G_N_ELEMENTS (node_parsers); i++)
{
if (gtk_css_token_is_ident (token, node_parsers[i].name))
if (gtk_css_parser_try_ident (parser, node_parsers[i].name))
{
GskRenderNode *node;
gtk_css_parser_consume_token (parser);
token = gtk_css_parser_get_token (parser);
if (!gtk_css_token_is (token, GTK_CSS_TOKEN_OPEN_CURLY))
if (!gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_EOF))
{
gtk_css_parser_error_syntax (parser, "Expected '{' after node name");
return FALSE;
}
gtk_css_parser_start_block (parser);
gtk_css_parser_end_block_prelude (parser);
node = node_parsers[i].func (parser);
if (node)
{
token = gtk_css_parser_get_token (parser);
if (!gtk_css_token_is (token, GTK_CSS_TOKEN_EOF))
if (!gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_EOF))
gtk_css_parser_error_syntax (parser, "Expected '}' at end of node definition");
g_clear_pointer (node_p, gsk_render_node_unref);
*node_p = node;
}
gtk_css_parser_end_block (parser);
return node != NULL;
}
}
gtk_css_parser_error_value (parser, "\"%s\" is not a valid node name", token->string.string);
if (gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_IDENT))
gtk_css_parser_error_value (parser, "\"%s\" is not a valid node name",
gtk_css_parser_get_token (parser)->string.string);
else
gtk_css_parser_error_syntax (parser, "Expected a node name");
return FALSE;
}
@@ -1464,6 +1490,16 @@ append_node_param (Printer *p,
render_node_print (p, node);
}
static cairo_status_t
surface_write (void *closure,
const unsigned char *data,
unsigned int length)
{
g_byte_array_append (closure, data, length);
return CAIRO_STATUS_SUCCESS;
}
static void
render_node_print (Printer *p,
GskRenderNode *node)
@@ -1704,30 +1740,25 @@ render_node_print (Printer *p,
case GSK_TEXTURE_NODE:
{
GdkTexture *texture = gsk_texture_node_get_texture (node);
int stride;
int len;
guchar *data;
cairo_surface_t *surface;
GByteArray *array;
char *b64;
start_node (p, "texture");
append_rect_param (p, "bounds", &node->bounds);
/* TODO: width and height here are unnecessary and can later be computed from the data length? */
append_float_param (p, "width", gdk_texture_get_width (texture));
append_float_param (p, "height", gdk_texture_get_height (texture));
stride = 4 * gdk_texture_get_width (texture);
len = sizeof (guchar) * stride * gdk_texture_get_height (texture);
data = g_malloc (len);
gdk_texture_download (texture, data, stride);
b64 = g_base64_encode (data, len);
surface = gdk_texture_download_surface (texture);
array = g_byte_array_new ();
cairo_surface_write_to_png_stream (surface, surface_write, array);
b64 = g_base64_encode (array->data, array->len);
_indent (p);
g_string_append_printf (p->str, "texture: \"data:;base64,%s\";\n", b64);
g_string_append_printf (p->str, "texture: url(\"data:image/png;base64,%s\");\n", b64);
end_node (p);
g_free (b64);
g_free (data);
g_byte_array_free (array, TRUE);
cairo_surface_destroy (surface);
}
break;

175
gtk/css/gtkcssdataurl.c Normal file
View File

@@ -0,0 +1,175 @@
/* GStreamer data:// uri source element
* Copyright (C) 2009 Igalia S.L
* Copyright (C) 2009 Sebastian Dröge <sebastian.droege@collabora.co.uk>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
/*<private>
* SECTION:data-url
* @title: data: URLs
*
* These function allow encoding and decoding of data: URLs, see
* [RFC 2397](http://tools.ietf.org/html/rfc2397) for more information.
*/
#include "config.h"
#include "gtkcssdataurlprivate.h"
#include "../gtkintl.h"
#include <string.h>
/*<private>
* gtk_css_data_url_parse:
* @url: the URL to parse
* @out_mimetype: (out nullable optional): Return location to set the contained
* mime type to. If no mime type was specified, this value is set to %NULL.
* @error: error location or %NULL for none
*
* Decodes a data URL according to RFC2397 and returns the decoded data.
*
* Returns: a new #GBytes with the decoded data or %NULL on error
**/
GBytes *
gtk_css_data_url_parse (const char *url,
char **out_mimetype,
GError **error)
{
char *mimetype = NULL;
const char *parameters_start;
const char *data_start;
GBytes *bytes;
gboolean base64 = FALSE;
char *charset = NULL;
gpointer bdata;
gsize bsize;
/* url must be an URI as defined in RFC 2397
* data:[<mediatype>][;base64],<data>
*/
if (g_ascii_strncasecmp ("data:", url, 5) != 0)
{
g_set_error (error,
G_IO_ERROR,
G_IO_ERROR_INVALID_FILENAME,
_("Not a data: URL"));
return NULL;
}
url += 5;
parameters_start = strchr (url, ';');
data_start = strchr (url, ',');
if (data_start == NULL)
{
g_set_error (error,
G_IO_ERROR,
G_IO_ERROR_INVALID_FILENAME,
_("Malformed data: URL"));
return NULL;
}
if (parameters_start > data_start)
parameters_start = NULL;
if (data_start != url && parameters_start != url)
{
mimetype = g_strndup (url,
(parameters_start ? parameters_start
: data_start) - url);
}
else
{
mimetype = NULL;
}
if (parameters_start != NULL)
{
char *parameters_str;
char **parameters;
guint i;
parameters_str = g_strndup (parameters_start + 1, data_start - parameters_start - 1);
parameters = g_strsplit (parameters_str, ";", -1);
for (i = 0; parameters[i] != NULL; i++)
{
if (g_ascii_strcasecmp ("base64", parameters[i]) == 0)
{
base64 = TRUE;
}
else if (g_ascii_strncasecmp ("charset=", parameters[i], 8) == 0)
{
g_free (charset);
charset = g_strdup (parameters[i] + 8);
}
}
g_free (parameters_str);
g_strfreev (parameters);
}
/* Skip comma */
data_start += 1;
if (base64)
{
bdata = g_base64_decode (data_start, &bsize);
}
else
{
/* URI encoded, i.e. "percent" encoding */
/* XXX: This doesn't allow nul bytes */
bdata = g_uri_unescape_string (data_start, NULL);
if (bdata == NULL)
{
g_set_error (error,
G_IO_ERROR,
G_IO_ERROR_INVALID_FILENAME,
_("Could not unescape string"));
g_free (mimetype);
return NULL;
}
bsize = strlen (bdata);
}
/* Convert to UTF8 */
if ((mimetype == NULL || g_ascii_strcasecmp ("text/plain", mimetype) == 0) &&
charset && g_ascii_strcasecmp ("US-ASCII", charset) != 0
&& g_ascii_strcasecmp ("UTF-8", charset) != 0)
{
gsize read;
gsize written;
gpointer data;
data = g_convert_with_fallback (bdata, bsize,
"UTF-8", charset,
(char *) "*",
&read, &written, NULL);
g_free (bdata);
bdata = data;
bsize = written;
}
bytes = g_bytes_new_take (bdata, bsize);
g_free (charset);
if (out_mimetype)
*out_mimetype = mimetype;
else
g_free (mimetype);
return bytes;
}

View File

@@ -0,0 +1,35 @@
/*
* Copyright © 2019 Benjamin Otte
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Authors: Benjamin Otte <otte@gnome.org>
*/
#ifndef __GTK_CSS_DATA_URL_PRIVATE_H__
#define __GTK_CSS_DATA_URL_PRIVATE_H__
#include <gio/gio.h>
G_BEGIN_DECLS
GBytes * gtk_css_data_url_parse (const char *url,
char **out_mimetype,
GError **error);
G_END_DECLS
#endif /* __GTK_CSS_DATA_URL_PRIVATE_H__ */

View File

@@ -335,7 +335,9 @@ gtk_css_parser_consume_token (GtkCssParser *self)
/* unpreserved tokens MUST be consumed via start_block() */
g_assert (gtk_css_token_is_preserved (&self->token, NULL));
gtk_css_token_clear (&self->token);
/* Don't consume any tokens at the end of a block */
if (!gtk_css_token_is (gtk_css_parser_peek_token (self), GTK_CSS_TOKEN_EOF))
gtk_css_token_clear (&self->token);
}
void
@@ -435,7 +437,15 @@ gtk_css_parser_end_block (GtkCssParser *self)
else
{
g_array_set_size (self->blocks, self->blocks->len - 1);
gtk_css_parser_skip (self);
if (gtk_css_token_is_preserved (&self->token, NULL))
{
gtk_css_token_clear (&self->token);
}
else
{
gtk_css_parser_start_block (self);
gtk_css_parser_end_block (self);
}
}
}
@@ -963,11 +973,10 @@ gtk_css_parser_parse_url_arg (GtkCssParser *parser,
*
* Returns: (nullable) (transfer full): the resulting URL or %NULL on error
**/
GFile *
char *
gtk_css_parser_consume_url (GtkCssParser *self)
{
const GtkCssToken *token;
GFile *result;
char *url;
token = gtk_css_parser_get_token (self);
@@ -988,16 +997,7 @@ gtk_css_parser_consume_url (GtkCssParser *self)
return NULL;
}
result = gtk_css_parser_resolve_url (self, url);
if (result == NULL)
{
gtk_css_parser_error_import (self, "Could not resolve \"%s\" to a valid URL", url);
g_free (url);
return NULL;
}
g_free (url);
return result;
return url;
}
gboolean

View File

@@ -134,7 +134,7 @@ gboolean gtk_css_parser_try_token (GtkCssParser
char * gtk_css_parser_consume_ident (GtkCssParser *self) G_GNUC_WARN_UNUSED_RESULT;
char * gtk_css_parser_consume_string (GtkCssParser *self) G_GNUC_WARN_UNUSED_RESULT;
GFile * gtk_css_parser_consume_url (GtkCssParser *self) G_GNUC_WARN_UNUSED_RESULT;
char * gtk_css_parser_consume_url (GtkCssParser *self) G_GNUC_WARN_UNUSED_RESULT;
gboolean gtk_css_parser_consume_number (GtkCssParser *self,
double *number);
gboolean gtk_css_parser_consume_integer (GtkCssParser *self,

View File

@@ -5,6 +5,7 @@ gtk_css_public_sources = files([
])
gtk_css_private_sources = files([
'gtkcssdataurl.c',
'gtkcssparser.c',
'gtkcsstokenizer.c',
])

View File

@@ -684,7 +684,7 @@ update_credits_button_visibility (GtkAboutDialog *about)
gboolean show;
GtkStackPage *page;
page = gtk_stack_get_page (GTK_STACK (priv->stack), priv->system_page);
page = gtk_stack_get_page (GTK_STACK (priv->stack), priv->credits_page);
show = (priv->authors != NULL ||
priv->documenters != NULL ||
@@ -2155,7 +2155,6 @@ add_credits_section (GtkAboutDialog *about,
gtk_widget_set_halign (label, GTK_ALIGN_END);
gtk_widget_set_valign (label, GTK_ALIGN_CENTER);
gtk_grid_attach (grid, label, 0, *row, 1, 1);
gtk_widget_show (label);
for (p = people; *p; p++)
{

View File

@@ -245,10 +245,16 @@ gtk_css_image_recolor_parse_arg (GtkCssParser *parser,
switch (arg)
{
case 0:
self->file = gtk_css_parser_consume_url (parser);
if (self->file == NULL)
return 0;
return 1;
{
char *url = gtk_css_parser_consume_url (parser);
if (url == NULL)
return 0;
self->file = gtk_css_parser_resolve_url (parser, url);
g_free (url);
if (self->file == NULL)
return 0;
return 1;
}
case 1:
self->palette = gtk_css_palette_value_parse (parser);

View File

@@ -27,6 +27,8 @@
#include "gtkcssimagepaintableprivate.h"
#include "gtkstyleproviderprivate.h"
#include "gtk/css/gtkcssdataurlprivate.h"
G_DEFINE_TYPE (GtkCssImageUrl, _gtk_css_image_url, GTK_TYPE_CSS_IMAGE)
static GtkCssImage *
@@ -163,12 +165,52 @@ static gboolean
gtk_css_image_url_parse (GtkCssImage *image,
GtkCssParser *parser)
{
GtkCssImageUrl *url = GTK_CSS_IMAGE_URL (image);
GtkCssImageUrl *self = GTK_CSS_IMAGE_URL (image);
char *url, *scheme;
url->file = gtk_css_parser_consume_url (parser);
if (url->file == NULL)
url = gtk_css_parser_consume_url (parser);
if (url == NULL)
return FALSE;
scheme = g_uri_parse_scheme (url);
if (scheme && g_ascii_strcasecmp (scheme, "data") == 0)
{
GInputStream *stream;
GdkPixbuf *pixbuf;
GBytes *bytes;
GError *error = NULL;
bytes = gtk_css_data_url_parse (url, NULL, &error);
if (bytes)
{
stream = g_memory_input_stream_new_from_bytes (bytes);
pixbuf = gdk_pixbuf_new_from_stream (stream, NULL, &error);
g_object_unref (stream);
if (pixbuf == NULL)
{
gtk_css_parser_emit_error (parser,
gtk_css_parser_get_start_location (parser),
gtk_css_parser_get_end_location (parser),
error);
g_clear_error (&error);
}
else
{
GdkTexture *texture = gdk_texture_new_for_pixbuf (pixbuf);
self->loaded_image = gtk_css_image_paintable_new (GDK_PAINTABLE (texture), GDK_PAINTABLE (texture));
g_object_unref (texture);
g_object_unref (pixbuf);
}
}
}
else
{
self->file = gtk_css_parser_resolve_url (parser, url);
}
g_free (url);
g_free (scheme);
return TRUE;
}

View File

@@ -71,9 +71,6 @@
* `GTK_DATA_PREFIX` environment variable), and `VERSION` is the GTK+ version number.
* If no file is found for the current version, GTK+ tries older versions all the
* way back to 4.0.
*
* In the same way, GTK+ tries to load a gtk-keys.css file for the current
* key theme, as defined by #GtkSettings:gtk-key-theme-name.
*/
@@ -698,7 +695,14 @@ parse_import (GtkCssScanner *scanner)
}
else
{
file = gtk_css_parser_consume_url (scanner->parser);
char *url = gtk_css_parser_consume_url (scanner->parser);
if (url)
{
file = gtk_css_parser_resolve_url (scanner->parser, url);
g_free (url);
}
else
file = NULL;
}
if (file == NULL)

View File

@@ -87,18 +87,7 @@
* Applications can override system-wide settings by setting the property
* of the GtkSettings object with g_object_set(). This should be restricted
* to special cases though; GtkSettings are not meant as an application
* configuration facility. When doing so, you need to be aware that settings
* that are specific to individual widgets may not be available before the
* widget type has been realized at least once. The following example
* demonstrates a way to do this:
* |[<!-- language="C" -->
* gtk_init ();
*
* // make sure the type is realized
* g_type_class_unref (g_type_class_ref (GTK_TYPE_BUTTON));
*
* g_object_set (gtk_settings_get_default (), "gtk-enable-animations", FALSE, NULL);
* ]|
* configuration facility.
*
* There is one GtkSettings instance per display. It can be obtained with
* gtk_settings_get_for_display(), but in many cases, it is more convenient

View File

@@ -78,7 +78,6 @@ gtk_test_init (int *argcp,
g_test_init (argcp, argvp, NULL);
gtk_disable_setlocale();
setlocale (LC_ALL, "en_US.UTF-8");
g_test_bug_base ("http://bugzilla.gnome.org/show_bug.cgi?id=%s");
/* XSendEvent() doesn't work yet on XI2 events.
* So at the moment gdk_test_simulate_* can only

View File

@@ -47,6 +47,7 @@
#include "gtkgestureprivate.h"
#include "gtkgesturesingle.h"
#include "gtkgestureswipe.h"
#include "gtkeventcontrollerkey.h"
#include "gtkintl.h"
#include "gtklayoutmanagerprivate.h"
#include "gtkmain.h"
@@ -5225,7 +5226,9 @@ gtk_widget_run_controllers (GtkWidget *widget,
* to collaborate with anything else. Break early if any such event
* controller handled the event.
*/
if (handled && !GTK_IS_GESTURE (controller))
if (handled &&
!GTK_IS_GESTURE (controller) &&
!GTK_IS_EVENT_CONTROLLER_KEY (controller))
break;
}

View File

@@ -431,6 +431,7 @@ static void gtk_window_move_focus (GtkWidget *widget,
GtkDirectionType dir);
static void gtk_window_real_activate_default (GtkWindow *window);
static void gtk_window_real_activate_focus (GtkWindow *window);
static void gtk_window_keys_changed (GtkWindow *window);
static gboolean gtk_window_enable_debugging (GtkWindow *window,
gboolean toggle);
@@ -804,6 +805,7 @@ gtk_window_class_init (GtkWindowClass *klass)
container_class->forall = gtk_window_forall;
klass->activate_default = gtk_window_real_activate_default;
klass->activate_focus = gtk_window_real_activate_focus;
klass->keys_changed = gtk_window_keys_changed;
klass->enable_debugging = gtk_window_enable_debugging;
klass->close_request = gtk_window_close_request;
@@ -6232,6 +6234,15 @@ get_active_region_type (GtkWindow *window, gint x, gint y)
return GTK_WINDOW_REGION_CONTENT;
}
static void
gtk_window_real_activate_focus (GtkWindow *window)
{
GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
if (priv->focus_widget && gtk_widget_is_sensitive (priv->focus_widget))
gtk_widget_activate (priv->focus_widget);
}
static gboolean
gtk_window_has_mnemonic_modifier_pressed (GtkWindow *window)
{

View File

@@ -111,6 +111,7 @@
<child>
<object class="GtkStackPage">
<property name="name">credits</property>
<property name="visible">0</property>
<property name="title" translatable="yes">Credits</property>
<property name="child">
<object class="GtkBox" id="credits_page">
@@ -147,6 +148,7 @@
<child>
<object class="GtkStackPage">
<property name="name">license</property>
<property name="visible">0</property>
<property name="title" translatable="yes">License</property>
<property name="child">
<object class="GtkBox" id="license_page">
@@ -189,6 +191,7 @@
<child>
<object class="GtkStackPage">
<property name="name">system</property>
<property name="visible">0</property>
<property name="title" translatable="yes">System</property>
<property name="child">
<object class="GtkBox" id="system_page">

View File

@@ -27,7 +27,7 @@ test_popover_parent (void)
GtkWidget *p;
AtkObject *a;
g_test_bug ("733923");
/*http://bugzilla.gnome.org/show_bug.cgi?id=733923 */
w = gtk_entry_new ();
@@ -50,8 +50,6 @@ main (int argc, char *argv[])
{
gtk_test_init (&argc, &argv, NULL);
g_test_bug_base ("http://bugzilla.gnome.org/");
g_test_add_func ("/popover/accessible-parent", test_popover_parent);
return g_test_run ();

View File

@@ -1064,7 +1064,7 @@ test_bold_label (void)
AtkObject *atk_obj;
gchar *text;
g_test_bug ("126797");
/*http://bugzilla.gnome.org/show_bug.cgi?id=126797 */
label = gtk_label_new ("<b>Bold?</b>");
g_object_ref_sink (label);
@@ -1089,8 +1089,6 @@ main (int argc, char *argv[])
{
gtk_test_init (&argc, &argv, NULL);
g_test_bug_base ("http://bugzilla.gnome.org/");
g_test_add_func ("/text/bold/GtkLabel", test_bold_label);
add_text_tests (gtk_label_new (""));

View File

@@ -119,8 +119,6 @@ main (int argc, char *argv[])
{
gtk_test_init (&argc, &argv, NULL);
g_test_bug_base ("http://bugzilla.gnome.org/");
add_value_tests (gtk_spin_button_new_with_range (0, 100, 1));
add_value_tests (gtk_level_bar_new_for_interval (0, 100));

100
testsuite/css/data.c Normal file
View File

@@ -0,0 +1,100 @@
/*
* Copyright © 2019 Benjamin Otte
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Authors: Benjamin Otte <otte@gnome.org>
*/
#include "../../gtk/css/gtkcssdataurlprivate.h"
#include <locale.h>
typedef struct _Test Test;
struct _Test
{
const char *name;
const char *url;
const char *mimetype;
const char *contents;
gsize contents_len;
};
#define CONTENTS(data) (data), sizeof(data) - 1
Test tests[] = {
{ "simple",
"data:,HelloWorld",
NULL, CONTENTS("HelloWorld") },
{ "nodata",
"data:,",
NULL, CONTENTS("") },
{ "case_sensitive",
"dATa:,HelloWorld",
NULL, CONTENTS("HelloWorld") },
{ "semicolon_after_comma",
"data:,;base64",
NULL, CONTENTS(";base64") },
{ "mimetype",
"data:image/png,nopng",
"image/png", CONTENTS("nopng") },
{ "charset",
"data:text/plain;charset=ISO-8859-1,Timm B\344der",
"text/plain", CONTENTS("Timm Bäder") },
{ "charset_base64",
"data:text/plain;charset=ISO-8859-5;base64,wOPh29DdILjW0ePb0OLe0g==",
"text/plain", CONTENTS("Руслан Ижбулатов") },
};
static void
test_parse (gconstpointer data)
{
const Test *test = data;
GError *error = NULL;
char *mimetype = NULL;
GBytes *bytes;
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);
g_bytes_unref (bytes);
}
int
main (int argc, char *argv[])
{
guint i;
g_test_init (&argc, &argv, NULL);
setlocale (LC_ALL, "C");
for (i = 0; i < G_N_ELEMENTS (tests); i++)
{
char *name = g_strdup_printf ("/css/data/load/%s", tests[i].name);
g_test_add_data_func (name, &tests[i], test_parse);
g_free (name);
}
return g_test_run ();
}

View File

@@ -20,6 +20,22 @@ test('api', test_api,
],
suite: 'css')
test_data = executable('data', ['data.c', '../../gtk/css/gtkcssdataurl.c'],
include_directories: [confinc, ],
dependencies: gtk_deps,
install: get_option('install-tests'),
install_dir: testexecdir)
test('data', test_data,
args: ['--tap', '-k' ],
env: [ 'GIO_USE_VOLUME_MONITOR=unix',
'GSETTINGS_BACKEND=memory',
'GTK_CSD=1',
'G_ENABLE_DIAGNOSTIC=0',
'G_TEST_SRCDIR=@0@'.format(meson.current_source_dir()),
'G_TEST_BUILDDIR=@0@'.format(meson.current_build_dir())
],
suite: 'css')
if get_option('install-tests')
conf = configuration_data()
conf.set('libexecdir', gtk_libexecdir)

View File

@@ -181,8 +181,6 @@ main (int argc, char *argv[])
g_test_init (&argc, &argv, NULL);
g_test_bug_base ("http://bugzilla.gnome.org");
enum_class = g_type_class_ref (GDK_TYPE_MEMORY_FORMAT);
for (format = 0; format < GDK_MEMORY_N_FORMATS; format++)

View File

@@ -72,8 +72,6 @@ main (int argc, char *argv[])
gtk_init ();
g_test_bug_base ("http://bugzilla.gnome.org/");
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);

View File

@@ -121,7 +121,7 @@ test_color_parse_nonsense (void)
GdkRGBA color;
gboolean res;
g_test_bug ("667485");
/*http://bugzilla.gnome.org/show_bug.cgi?id=667485 */
res = gdk_rgba_parse (&color, "rgb(,,)");
g_assert (!res);
@@ -151,14 +151,12 @@ test_color_parse_nonsense (void)
int
main (int argc, char *argv[])
{
g_test_init (&argc, &argv, NULL);
g_test_init (&argc, &argv, NULL);
g_test_bug_base ("http://bugzilla.gnome.org");
g_test_add_func ("/rgba/parse", test_color_parse);
g_test_add_func ("/rgba/parse/nonsense", test_color_parse_nonsense);
g_test_add_func ("/rgba/to-string", test_color_to_string);
g_test_add_func ("/rgba/copy", test_color_copy);
g_test_add_func ("/rgba/parse", test_color_parse);
g_test_add_func ("/rgba/parse/nonsense", test_color_parse_nonsense);
g_test_add_func ("/rgba/to-string", test_color_to_string);
g_test_add_func ("/rgba/copy", test_color_copy);
return g_test_run ();
return g_test_run ();
}

View File

@@ -111,8 +111,6 @@ main (int argc, char *argv[])
gtk_init ();
g_test_bug_base ("http://bugzilla.gnome.org/");
g_test_add_func ("/seat/list", test_list_seats);
g_test_add_func ("/seat/default", test_default_seat);

View File

@@ -61,7 +61,8 @@ deserialize_error_func (const GtkCssSection *section,
{
char *section_str = gtk_css_section_to_string (section);
g_error ("Error at %s: %s", section_str, error->message);
g_test_message ("Error at %s: %s", section_str, error->message);
g_test_fail ();
free (section_str);
}

View File

@@ -0,0 +1,11 @@
/* Add a color node to blow up the bounds so that
we can test the texture bounds work. */
color {
bounds: 0 0 50 50;
color: white;
}
texture {
bounds: 10 10 30 30;
texture: url('data:,<svg><rect width="10" height="10" style="fill:red"/></svg>');
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 B

View File

@@ -26,8 +26,11 @@ serialize_deserialize = executable(
)
compare_render_tests = [
'blend-normal',
'blend-difference',
'clip-coordinates-3d',
'clipped_rounded_clip',
'color-blur0',
'cross-fade-in-opacity',
'opacity_clip',
'outset_shadow_offset_both',
@@ -36,9 +39,7 @@ compare_render_tests = [
'outset_shadow_rounded_top',
'outset_shadow_simple',
'shadow-in-opacity',
'blend-normal',
'blend-difference',
'color-blur0',
'texture-url',
]
renderers = [

File diff suppressed because one or more lines are too long

View File

@@ -454,7 +454,6 @@ main (int argc, char *argv[])
g_test_init (&argc, &argv, NULL);
setlocale (LC_ALL, "C");
g_test_bug_base ("http://bugzilla.gnome.org/show_bug.cgi?id=%s");
create_masks ();

View File

@@ -745,7 +745,6 @@ int
main (int argc, char *argv[])
{
gtk_test_init (&argc, &argv);
g_test_bug_base ("http://bugzilla.gnome.org/");
gtk_test_register_all_types();
g_test_add_func ("/tests/iconview-new", test_iconview_new);

View File

@@ -311,7 +311,6 @@ main (int argc, char *argv[])
{
g_test_init (&argc, &argv, NULL);
setlocale (LC_ALL, "C");
g_test_bug_base ("http://bugzilla.gnome.org/show_bug.cgi?id=%s");
number_quark = g_quark_from_static_string ("Hell and fire was spawned to be released.");
changes_quark = g_quark_from_static_string ("What did I see? Can I believe what I saw?");

View File

@@ -5727,7 +5727,7 @@ specific_bug_301558 (void)
int i;
gboolean add;
g_test_bug ("301558");
/*http://bugzilla.gnome.org/show_bug.cgi?id=301558 */
tree = gtk_tree_store_new (2, G_TYPE_INT, G_TYPE_BOOLEAN);
gtk_tree_store_append (tree, &iter, NULL);
@@ -5803,7 +5803,7 @@ specific_bug_311955 (void)
int n;
GtkTreePath *path;
g_test_bug ("311955");
/*http://bugzilla.gnome.org/show_bug.cgi?id=311955 */
store = gtk_tree_store_new (1, G_TYPE_INT);
@@ -5972,7 +5972,7 @@ specific_bug_346800 (void)
store = gtk_tree_store_newv (2, columns);
model = GTK_TREE_MODEL (store);
g_test_bug ("346800");
/*http://bugzilla.gnome.org/show_bug.cgi?id=346800 */
filter = GTK_TREE_MODEL_FILTER (gtk_tree_model_filter_new (model, NULL));
gtk_tree_model_filter_set_visible_column (filter, 1);
@@ -6031,7 +6031,7 @@ specific_bug_464173 (void)
GtkWidget *view G_GNUC_UNUSED;
gboolean visible = TRUE;
g_test_bug ("464173");
/*http://bugzilla.gnome.org/show_bug.cgi?id=464173 */
model = gtk_tree_store_new (1, G_TYPE_STRING);
gtk_tree_store_append (model, &iter1, NULL);
@@ -6075,7 +6075,7 @@ specific_bug_540201 (void)
GtkWidget *tree_view G_GNUC_UNUSED;
g_test_bug ("540201");
/*http://bugzilla.gnome.org/show_bug.cgi?id=540201 */
store = gtk_tree_store_new (1, G_TYPE_INT);
@@ -6128,7 +6128,7 @@ specific_bug_549287 (void)
GtkTreeIter iter;
GtkTreeIter *swap, *parent, *child;
g_test_bug ("529287");
/*http://bugzilla.gnome.org/show_bug.cgi?id=529287 */
store = gtk_tree_store_new (1, G_TYPE_STRING);
filtered = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
@@ -6227,7 +6227,7 @@ specific_bug_621076 (void)
GtkTreeIter item_iter;
SignalMonitor *monitor;
g_test_bug ("621076");
/*http://bugzilla.gnome.org/show_bug.cgi?id=621076 */
store = gtk_tree_store_new (1, G_TYPE_STRING);
filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);

View File

@@ -356,7 +356,6 @@ main (int argc, char *argv[])
{
g_test_init (&argc, &argv, NULL);
setlocale (LC_ALL, "C");
g_test_bug_base ("http://bugzilla.gnome.org/show_bug.cgi?id=%s");
number_quark = g_quark_from_static_string ("Hell and fire was spawned to be released.");
changes_quark = g_quark_from_static_string ("What did I see? Can I believe what I saw?");

View File

@@ -22,7 +22,6 @@ main (int argc, char *argv[])
g_test_init (&argc, &argv, NULL);
gtk_disable_setlocale();
setlocale (LC_ALL, "C");
g_test_bug_base ("http://bugzilla.gnome.org/show_bug.cgi?id=%s");
g_test_add_func ("/main/init", test_init);

View File

@@ -286,7 +286,6 @@ main (int argc, char *argv[])
{
g_test_init (&argc, &argv, NULL);
setlocale (LC_ALL, "C");
g_test_bug_base ("http://bugzilla.gnome.org/show_bug.cgi?id=%s");
number_quark = g_quark_from_static_string ("Hell and fire was spawned to be released.");
changes_quark = g_quark_from_static_string ("What did I see? Can I believe what I saw?");

View File

@@ -49,7 +49,6 @@ main (int argc,
g_test_init (&argc, &argv, NULL);
g_setenv ("GTK_MODULES", "", TRUE);
setlocale (LC_ALL, "C");
g_test_bug_base ("http://bugzilla.gnome.org/show_bug.cgi?id=%s");
g_test_add_func ("/no_gtk_init/gdk_cairo_set_source_pixbuf", test_gdk_cairo_set_source_pixbuf);

View File

@@ -292,7 +292,6 @@ main (int argc, char *argv[])
{
g_test_init (&argc, &argv, NULL);
setlocale (LC_ALL, "C");
g_test_bug_base ("http://bugzilla.gnome.org/show_bug.cgi?id=%s");
g_test_add_func ("/rbtree/crash", test_crash);
g_test_add_func ("/rbtree/crash2", test_crash2);

View File

@@ -514,7 +514,6 @@ main (int argc,
{
g_test_init (&argc, &argv, NULL);
setlocale (LC_ALL, "C");
g_test_bug_base ("http://bugzilla.gnome.org/show_bug.cgi?id=%s");
g_test_add_func ("/rbtree/create", test_create);
g_test_add_func ("/rbtree/insert_after", test_insert_after);

View File

@@ -647,7 +647,6 @@ main (int argc, char *argv[])
{
g_test_init (&argc, &argv, NULL);
setlocale (LC_ALL, "C");
g_test_bug_base ("http://bugzilla.gnome.org/show_bug.cgi?id=%s");
number_quark = g_quark_from_static_string ("Hell and fire was spawned to be released.");
changes_quark = g_quark_from_static_string ("What did I see? Can I believe what I saw?");

View File

@@ -324,7 +324,6 @@ main (int argc, char *argv[])
{
g_test_init (&argc, &argv, NULL);
setlocale (LC_ALL, "C");
g_test_bug_base ("http://bugzilla.gnome.org/show_bug.cgi?id=%s");
number_quark = g_quark_from_static_string ("Hell and fire was spawned to be released.");
changes_quark = g_quark_from_static_string ("What did I see? Can I believe what I saw?");

View File

@@ -385,7 +385,6 @@ main (int argc, char *argv[])
{
g_test_init (&argc, &argv, NULL);
setlocale (LC_ALL, "C");
g_test_bug_base ("http://bugzilla.gnome.org/show_bug.cgi?id=%s");
number_quark = g_quark_from_static_string ("Hell and fire was spawned to be released.");
changes_quark = g_quark_from_static_string ("What did I see? Can I believe what I saw?");

View File

@@ -1040,7 +1040,7 @@ specific_bug_300089 (void)
GtkTreePath *path;
GtkTreeIter iter, iter2, sort_iter;
g_test_bug ("300089");
/*http://bugzilla.gnome.org/show_bug.cgi?id=300089 */
child_model = GTK_TREE_MODEL (gtk_tree_store_new (1, G_TYPE_STRING));
@@ -1084,7 +1084,7 @@ specific_bug_364946 (void)
GtkTreeIter a, aa, aaa, aab, iter;
GtkTreeModel *s_model;
g_test_bug ("364946");
/*http://bugzilla.gnome.org/show_bug.cgi?id=364946 */
store = gtk_tree_store_new (1, G_TYPE_STRING);
@@ -1187,7 +1187,7 @@ specific_bug_698846 (void)
GtkTreeIter iter;
guint count = 0;
g_test_bug ("698846");
/*http://bugzilla.gnome.org/show_bug.cgi?id=698846 */
store = gtk_list_store_new (1, G_TYPE_STRING);
sorted = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (store));
@@ -1228,7 +1228,7 @@ sort_column_change (void)
GtkSortType order;
gboolean ret;
g_test_bug ("792459");
/*http://bugzilla.gnome.org/show_bug.cgi?id=792459 */
store = gtk_list_store_new (1, G_TYPE_STRING);
sorted = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (store));

View File

@@ -254,7 +254,6 @@ main (int argc, char *argv[])
{
g_test_init (&argc, &argv, NULL);
setlocale (LC_ALL, "C");
g_test_bug_base ("http://bugzilla.gnome.org/show_bug.cgi?id=%s");
number_quark = g_quark_from_static_string ("Hell and fire was spawned to be released.");
changes_quark = g_quark_from_static_string ("What did I see? Can I believe what I saw?");

View File

@@ -25,8 +25,6 @@ main (int argc,
{
gtk_test_init (&argc, &argv, NULL);
g_test_bug_base ("http://bugzilla.gnome.org/");
register_list_store_tests ();
register_tree_store_tests ();
register_model_ref_count_tests ();

View File

@@ -1026,7 +1026,7 @@ specific_bug_77977 (void)
/* Stripped down version of test case for bug 77977 by Damon Chaplin */
g_test_bug ("77977");
/*http://bugzilla.gnome.org/show_bug.cgi?id=77977 */
tree_store = gtk_tree_store_new (1, G_TYPE_STRING);
@@ -1064,7 +1064,7 @@ specific_bug_698396 (void)
GtkTreeStore *tree_store;
gint new_order[1] = { 0 };
g_test_bug ("698396");
/*http://bugzilla.gnome.org/show_bug.cgi?id=698396 */
tree_store = gtk_tree_store_new (1, G_TYPE_STRING);

View File

@@ -26,7 +26,7 @@ test_bug_546005 (void)
GtkListStore *list_store;
GtkWidget *view;
g_test_bug ("546005");
/*http://bugzilla.gnome.org/show_bug.cgi?id=546005 */
/* Tests provided by Bjorn Lindqvist, Paul Pogonyshev */
view = gtk_tree_view_new ();
@@ -78,7 +78,7 @@ test_bug_539377 (void)
GtkTreePath *path;
GtkListStore *list_store;
g_test_bug ("539377");
/*http://bugzilla.gnome.org/show_bug.cgi?id=539377 */
/* Test provided by Bjorn Lindqvist */
@@ -236,7 +236,7 @@ test_selection_count (void)
GtkTreeSelection *selection;
GtkWidget *view;
g_test_bug ("702957");
/*http://bugzilla.gnome.org/show_bug.cgi?id=702957 */
list_store = gtk_list_store_new (1, G_TYPE_STRING);
view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (list_store));
@@ -299,7 +299,7 @@ test_selection_empty (void)
GtkWidget *view;
GtkTreeIter iter;
g_test_bug ("712760");
/*http://bugzilla.gnome.org/show_bug.cgi?id=712760 */
list_store = gtk_list_store_new (1, G_TYPE_STRING);
view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (list_store));
@@ -340,7 +340,6 @@ main (int argc,
char **argv)
{
gtk_test_init (&argc, &argv, NULL);
g_test_bug_base ("http://bugzilla.gnome.org/");
g_test_add_func ("/TreeView/cursor/bug-546005", test_bug_546005);
g_test_add_func ("/TreeView/cursor/bug-539377", test_bug_539377);

View File

@@ -218,7 +218,7 @@ test_show_hide (void)
GtkWidget *window;
gint w, h, w1, h1;
g_test_bug ("696882");
/*http://bugzilla.gnome.org/show_bug.cgi?id=696882 */
/* test that hide/show does not affect the size */
@@ -258,7 +258,6 @@ main (int argc, char *argv[])
gint i;
gtk_test_init (&argc, &argv);
g_test_bug_base ("http://bugzilla.gnome.org/");
for (i = 0; i < argc; i++)
{

View File

@@ -0,0 +1,3 @@
.background {
background: red url('data:,<svg><rect width="20" height="20" style="fill:lime"/></svg>');
}

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkWindow">
<property name="type">popup</property>
<child>
<object class="GtkPicture">
<property name="can-shrink">0</property>
<property name="paintable">green-20x20.png</property>
</object>
</child>
</object>
</interface>

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkWindow" id="window1">
<property name="width_request">20</property>
<property name="height_request">20</property>
<property name="type">popup</property>
</object>
</interface>

View File

@@ -194,6 +194,9 @@ testdata = [
'css-multi-state.css',
'css-multi-state.ref.ui',
'css-multi-state.ui',
'data-url.css',
'data-url.ref.ui',
'data-url.ui',
'fixed-widget-stacking.ref.ui',
'fixed-widget-stacking.ui',
'flipping-icons.ref.ui',