Compare commits

...

6 Commits

Author SHA1 Message Date
Benjamin Otte
7f7700d7d9 menu: Only set position in one place 2019-05-29 21:01:50 +02:00
Benjamin Otte
43f4559d17 menu: Simplify function
No need to do complicated math when we can just look at the allocation.
2019-05-29 21:01:50 +02:00
Benjamin Otte
52f5c7830c testgtk: Remove CSS loading
The CSS is not fun.
And it doesn't work.
2019-05-29 21:01:49 +02:00
Benjamin Otte
512778b83a menuitem: Introduce gtk_menu_item_get_menu_shell()
Returns the parent menu shell or NULL.

Replace all calls to gtk_widget_get_parent() with this function.
2019-05-29 21:01:49 +02:00
Benjamin Otte
8c4517cf75 rendernodeparser: Handle empty Cairo nodes
Cairo nodes can contain a NULL surface if they have never been drawn to.
Make this the default Cairo node.
2019-05-29 16:52:13 +02:00
Benjamin Otte
f3e9e3fe82 rendernodeparser: Parse cairo script
Use cairo-script-interpreter to parse the scripts that generate cairo
nodes.

This requires libcairoscriptinterpreter.so to work properly, but if
it isn't found we disable this (unimportant for normal functioning)
code and just emits a parser warning.
The testsuite requires it however or it will fail.

A new test is included that tests all of this.
2019-05-29 16:52:13 +02:00
15 changed files with 264 additions and 170 deletions

View File

@@ -294,6 +294,8 @@
#mesondefine GTK_PRINT_BACKENDS
#mesondefine HAVE_CAIRO_SCRIPT_INTERPRETER
#mesondefine HAVE_HARFBUZZ
#mesondefine HAVE_PANGOFT

View File

@@ -36,6 +36,9 @@
#ifdef CAIRO_HAS_SCRIPT_SURFACE
#include <cairo-script.h>
#endif
#ifdef HAVE_CAIRO_SCRIPT_INTERPRETER
#include <cairo-script-interpreter.h>
#endif
typedef struct _Declaration Declaration;
@@ -132,6 +135,131 @@ clear_texture (gpointer inout_texture)
g_clear_object ((GdkTexture **) inout_texture);
}
static cairo_surface_t *
csi_hooks_surface_create (void *closure,
cairo_content_t content,
double width,
double height,
long uid)
{
return cairo_surface_create_similar (closure, content, width, height);
}
static const cairo_user_data_key_t csi_hooks_key;
static cairo_t *
csi_hooks_context_create (void *closure,
cairo_surface_t *surface)
{
cairo_t *cr = cairo_create (surface);
cairo_set_user_data (cr,
&csi_hooks_key,
cairo_surface_reference (surface),
(cairo_destroy_func_t) cairo_surface_destroy);
return cr;
}
static void
csi_hooks_context_destroy (void *closure,
void *ptr)
{
cairo_surface_t *surface;
cairo_t *cr;
surface = cairo_get_user_data (ptr, &csi_hooks_key);
cr = cairo_create (closure);
cairo_set_source_surface (cr, surface, 0, 0);
cairo_paint (cr);
cairo_destroy (cr);
}
static gboolean
parse_script (GtkCssParser *parser,
gpointer out_data)
{
#ifdef HAVE_CAIRO_SCRIPT_INTERPRETER
GError *error = NULL;
GBytes *bytes;
GtkCssLocation start_location;
char *url, *scheme;
cairo_script_interpreter_t *csi;
cairo_script_interpreter_hooks_t hooks = {
.surface_create = csi_hooks_surface_create,
.context_create = csi_hooks_context_create,
.context_destroy = csi_hooks_context_destroy,
};
start_location = *gtk_css_parser_get_start_location (parser);
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)
{
bytes = gtk_css_data_url_parse (url, NULL, &error);
}
else
{
GFile *file;
file = gtk_css_parser_resolve_url (parser, url);
bytes = g_file_load_bytes (file, NULL, NULL, &error);
g_object_unref (file);
}
g_free (scheme);
g_free (url);
if (bytes == NULL)
{
gtk_css_parser_emit_error (parser,
&start_location,
gtk_css_parser_get_end_location (parser),
error);
g_clear_error (&error);
return FALSE;
}
hooks.closure = cairo_recording_surface_create (CAIRO_CONTENT_COLOR_ALPHA, NULL);
csi = cairo_script_interpreter_create ();
cairo_script_interpreter_install_hooks (csi, &hooks);
cairo_script_interpreter_feed_string (csi, g_bytes_get_data (bytes, NULL), g_bytes_get_size (bytes));
g_bytes_unref (bytes);
if (cairo_surface_status (hooks.closure) != CAIRO_STATUS_SUCCESS)
{
gtk_css_parser_error_value (parser, "Invalid Cairo script: %s", cairo_status_to_string (cairo_surface_status (hooks.closure)));
cairo_script_interpreter_destroy (csi);
return FALSE;
}
if (cairo_script_interpreter_destroy (csi) != CAIRO_STATUS_SUCCESS)
{
gtk_css_parser_error_value (parser, "Invalid Cairo script");
cairo_surface_destroy (hooks.closure);
return FALSE;
}
*(cairo_surface_t **) out_data = hooks.closure;
return TRUE;
#else
gtk_css_parser_warn (parser,
GTK_CSS_PARSER_WARNING_UNIMPLEMENTED,
gtk_css_parser_get_block_location (parser),
gtk_css_parser_get_start_location (parser),
"GTK was compiled with script interpreter support. Using fallback pixel data for Cairo node.");
*(cairo_surface_t **) out_data = NULL;
return TRUE;
#endif
}
static void
clear_surface (gpointer inout_surface)
{
g_clear_pointer ((cairo_surface_t **) inout_surface, cairo_surface_destroy);
}
static gboolean
parse_rounded_rect (GtkCssParser *parser,
gpointer out_rect)
@@ -930,35 +1058,40 @@ parse_cairo_node (GtkCssParser *parser)
{
graphene_rect_t bounds = GRAPHENE_RECT_INIT (0, 0, 50, 50);
GdkTexture *pixels = NULL;
cairo_surface_t *surface = NULL;
const Declaration declarations[] = {
{ "bounds", parse_rect, NULL, &bounds },
{ "pixels", parse_texture, clear_texture, &pixels }
{ "pixels", parse_texture, clear_texture, &pixels },
{ "script", parse_script, clear_surface, &surface }
};
GskRenderNode *node;
cairo_t *cr;
parse_declarations (parser, declarations, G_N_ELEMENTS(declarations));
node = gsk_cairo_node_new (&bounds);
cr = gsk_cairo_node_get_draw_context (node);
if (pixels != NULL)
if (surface != NULL)
{
cairo_surface_t *surface;
cairo_t *cr = gsk_cairo_node_get_draw_context (node);
cairo_set_source_surface (cr, surface, 0, 0);
cairo_paint (cr);
cairo_destroy (cr);
}
else if (pixels != NULL)
{
cairo_t *cr = gsk_cairo_node_get_draw_context (node);
surface = gdk_texture_download_surface (pixels);
cairo_set_source_surface (cr, surface, 0, 0);
cairo_paint (cr);
cairo_surface_destroy (surface);
cairo_destroy (cr);
}
else
{
gdk_cairo_set_source_rgba (cr, &GDK_RGBA ("FF00CC"));
cairo_paint (cr);
/* do nothing */
}
cairo_destroy (cr);
g_clear_object (&pixels);
g_clear_pointer (&surface, cairo_surface_destroy);
return node;
}
@@ -2246,36 +2379,39 @@ render_node_print (Printer *p,
start_node (p, "cairo");
append_rect_param (p, "bounds", &node->bounds);
array = g_byte_array_new ();
cairo_surface_write_to_png_stream (surface, cairo_write_array, array);
b64 = g_base64_encode (array->data, array->len);
if (surface != NULL)
{
array = g_byte_array_new ();
cairo_surface_write_to_png_stream (surface, cairo_write_array, array);
b64 = g_base64_encode (array->data, array->len);
_indent (p);
g_string_append_printf (p->str, "pixels: url(\"data:image/png;base64,%s\");\n", b64);
_indent (p);
g_string_append_printf (p->str, "pixels: url(\"data:image/png;base64,%s\");\n", b64);
g_free (b64);
g_byte_array_free (array, TRUE);
g_free (b64);
g_byte_array_free (array, TRUE);
#ifdef CAIRO_HAS_SCRIPT_SURFACE
if (cairo_surface_get_type (surface) == CAIRO_SURFACE_TYPE_RECORDING)
{
cairo_device_t *script;
array = g_byte_array_new ();
script = cairo_script_create_for_stream (cairo_write_array, array);
if (cairo_script_from_recording_surface (script, surface) == CAIRO_STATUS_SUCCESS)
if (cairo_surface_get_type (surface) == CAIRO_SURFACE_TYPE_RECORDING)
{
b64 = g_base64_encode (array->data, array->len);
_indent (p);
g_string_append_printf (p->str, "script: url(\"data:;base64,%s\");\n", b64);
g_free (b64);
}
cairo_device_t *script;
cairo_device_destroy (script);
g_byte_array_free (array, TRUE);
}
array = g_byte_array_new ();
script = cairo_script_create_for_stream (cairo_write_array, array);
if (cairo_script_from_recording_surface (script, surface) == CAIRO_STATUS_SUCCESS)
{
b64 = g_base64_encode (array->data, array->len);
_indent (p);
g_string_append_printf (p->str, "script: url(\"data:;base64,%s\");\n", b64);
g_free (b64);
}
cairo_device_destroy (script);
g_byte_array_free (array, TRUE);
}
#endif
}
end_node (p);
}

View File

@@ -156,6 +156,7 @@ gsk_deps = [
graphene_dep,
pango_dep,
cairo_dep,
cairo_csi_dep,
pixbuf_dep,
libgdk_dep,
]

View File

@@ -62,6 +62,8 @@ typedef enum
* deprecated and will be removed in a future version
* @GTK_CSS_PARSER_WARNING_SYNTAX: A syntax construct was used
* that should be avoided
* @GTK_CSS_PARSER_WARNING_UNIMPLEMENTED: A feature is not
* implemented
*
* Warnings that can occur while parsing CSS.
*

View File

@@ -1814,6 +1814,7 @@ gtk_menu_update_scroll_offset (GtkMenu *menu,
gpointer user_data)
{
GtkBorder arrows_border;
int offset;
g_return_if_fail (GTK_IS_MENU (menu));
@@ -1821,8 +1822,8 @@ gtk_menu_update_scroll_offset (GtkMenu *menu,
return;
get_arrows_border (menu, &arrows_border);
menu->priv->scroll_offset = arrows_border.top + (final_rect->y - flipped_rect->y);
gtk_menu_scroll_to (menu, menu->priv->scroll_offset);
offset = arrows_border.top + (final_rect->y - flipped_rect->y);
gtk_menu_scroll_to (menu, offset);
}
/**
@@ -3521,30 +3522,19 @@ compute_child_offset (GtkMenu *menu,
gint *height)
{
GtkMenuPrivate *priv = menu->priv;
gint item_top_attach;
gint child_offset = 0;
gint i;
GtkAllocation allocation;
get_effective_child_attach (menu_item, &item_top_attach);
gtk_widget_get_allocation (menu_item, &allocation);
if (allocation.width > 0)
{
if (offset)
*offset = allocation.y + priv->scroll_offset;
if (height)
*height = allocation.height;
return TRUE;
}
/* there is a possibility that we get called before _size_request,
* so check the height table for safety.
*/
if (!priv->heights || priv->heights_length < gtk_menu_get_n_rows (menu))
return FALSE;
/* when we have a row with only invisible children, its height will
* be zero, so there's no need to check WIDGET_VISIBLE here
*/
for (i = 0; i < item_top_attach; i++)
child_offset += priv->heights[i];
if (offset)
*offset = child_offset;
if (height)
*height = priv->heights[item_top_attach];
return TRUE;
return FALSE;
}
static void

View File

@@ -262,6 +262,12 @@ gtk_menu_item_actionable_interface_init (GtkActionableInterface *iface)
iface->get_action_target_value = gtk_menu_item_get_action_target_value;
}
static GtkMenuShell *
gtk_menu_item_get_menu_shell (GtkMenuItem *item)
{
return GTK_MENU_SHELL (gtk_widget_get_ancestor (GTK_WIDGET (item), GTK_TYPE_MENU_SHELL));
}
static void
gtk_menu_item_size_allocate (GtkWidget *widget,
int width,
@@ -273,13 +279,13 @@ gtk_menu_item_size_allocate (GtkWidget *widget,
GtkAllocation child_allocation;
GtkTextDirection direction;
GtkWidget *child;
GtkWidget *parent;
GtkMenuShell *shell;
g_return_if_fail (GTK_IS_MENU_ITEM (widget));
direction = gtk_widget_get_direction (widget);
parent = gtk_widget_get_parent (widget);
shell = gtk_menu_item_get_menu_shell (menu_item);
child = gtk_bin_get_child (GTK_BIN (widget));
if (child)
@@ -290,7 +296,7 @@ gtk_menu_item_size_allocate (GtkWidget *widget,
child_allocation.x += priv->toggle_size;
child_allocation.width -= priv->toggle_size;
if ((priv->submenu && !GTK_IS_MENU_BAR (parent)) || priv->reserve_indicator)
if ((priv->submenu && !GTK_IS_MENU_BAR (shell)) || priv->reserve_indicator)
{
GtkAllocation arrow_alloc;
@@ -359,13 +365,13 @@ gtk_menu_item_real_get_width (GtkWidget *widget,
GtkMenuItem *menu_item = GTK_MENU_ITEM (widget);
GtkMenuItemPrivate *priv = menu_item->priv;
GtkWidget *child;
GtkWidget *parent;
GtkMenuShell *shell;
guint accel_width;
gint min_width, nat_width;
min_width = nat_width = 0;
parent = gtk_widget_get_parent (widget);
shell = gtk_menu_item_get_menu_shell (menu_item);
child = gtk_bin_get_child (GTK_BIN (widget));
if (child != NULL && gtk_widget_get_visible (child))
@@ -375,7 +381,7 @@ gtk_menu_item_real_get_width (GtkWidget *widget,
gtk_widget_measure (child, GTK_ORIENTATION_HORIZONTAL, -1,
&child_min, &child_nat, NULL, NULL);
if ((priv->submenu && !GTK_IS_MENU_BAR (parent)) || priv->reserve_indicator)
if ((priv->submenu && !GTK_IS_MENU_BAR (shell)) || priv->reserve_indicator)
{
gint arrow_size;
@@ -412,7 +418,7 @@ gtk_menu_item_real_get_height (GtkWidget *widget,
GtkMenuItem *menu_item = GTK_MENU_ITEM (widget);
GtkMenuItemPrivate *priv = menu_item->priv;
GtkWidget *child;
GtkWidget *parent;
GtkMenuShell *shell;
guint accel_width;
gint min_height, nat_height;
gint avail_size = 0;
@@ -422,7 +428,7 @@ gtk_menu_item_real_get_height (GtkWidget *widget,
if (for_size != -1)
avail_size = for_size;
parent = gtk_widget_get_parent (widget);
shell = gtk_menu_item_get_menu_shell (menu_item);
child = gtk_bin_get_child (GTK_BIN (widget));
if (child != NULL && gtk_widget_get_visible (child))
@@ -430,7 +436,7 @@ gtk_menu_item_real_get_height (GtkWidget *widget,
gint child_min, child_nat;
gint arrow_size = 0;
if ((priv->submenu && !GTK_IS_MENU_BAR (parent)) || priv->reserve_indicator)
if ((priv->submenu && !GTK_IS_MENU_BAR (shell)) || priv->reserve_indicator)
gtk_widget_measure (priv->arrow_widget,
GTK_ORIENTATION_VERTICAL,
-1,
@@ -871,7 +877,7 @@ gtk_menu_item_buildable_custom_finished (GtkBuildable *buildable,
GtkMenuShell *menu_shell;
GtkWidget *attach;
menu_shell = GTK_MENU_SHELL (gtk_widget_get_parent (GTK_WIDGET (buildable)));
menu_shell = gtk_menu_item_get_menu_shell (GTK_MENU_ITEM (buildable));
if (menu_shell)
{
while (GTK_IS_MENU (menu_shell) &&
@@ -938,7 +944,7 @@ update_arrow_widget (GtkMenuItem *menu_item)
gboolean should_have_arrow;
should_have_arrow = priv->reserve_indicator ||
(priv->submenu && !GTK_IS_MENU_BAR (gtk_widget_get_parent (widget)));
(priv->submenu && !GTK_IS_MENU_BAR (gtk_menu_item_get_menu_shell (menu_item)));
if (should_have_arrow)
{
@@ -993,9 +999,7 @@ gtk_menu_item_set_submenu (GtkMenuItem *menu_item,
}
update_arrow_widget (menu_item);
if (gtk_widget_get_parent (widget))
gtk_widget_queue_resize (widget);
gtk_widget_queue_resize (widget);
g_object_notify_by_pspec (G_OBJECT (menu_item), menu_item_props[PROP_SUBMENU]);
}
@@ -1113,7 +1117,7 @@ gtk_menu_item_enter (GtkEventController *controller,
gpointer user_data)
{
GtkMenuItem *menu_item = GTK_MENU_ITEM (user_data);
GtkWidget *menu_shell;
GtkMenuShell *menu_shell;
GdkEvent *event;
gboolean is_focus, contains_focus;
@@ -1128,17 +1132,17 @@ gtk_menu_item_enter (GtkEventController *controller,
gdk_event_get_source_device ((GdkEvent*) event))
return;
menu_shell = gtk_widget_get_parent (GTK_WIDGET (menu_item));
menu_shell = gtk_menu_item_get_menu_shell (menu_item);
g_object_get (controller,
"is-pointer-focus", &is_focus,
"contains-pointer-focus", &contains_focus,
NULL);
if (GTK_IS_MENU_SHELL (menu_shell) &&
GTK_MENU_SHELL (menu_shell)->priv->active &&
if (menu_shell != NULL &&
menu_shell->priv->active &&
(is_focus || contains_focus))
gtk_menu_shell_select_item (GTK_MENU_SHELL (menu_shell), GTK_WIDGET (menu_item));
gtk_menu_shell_select_item (menu_shell, GTK_WIDGET (menu_item));
}
static void
@@ -1148,7 +1152,7 @@ gtk_menu_item_leave (GtkEventController *controller,
gpointer user_data)
{
GtkMenuItem *menu_item = GTK_MENU_ITEM (user_data);
GtkWidget *menu_shell = gtk_widget_get_parent (GTK_WIDGET (menu_item));
GtkMenuShell *menu_shell = gtk_menu_item_get_menu_shell (menu_item);
gboolean is_focus, contains_focus;
g_object_get (controller,
@@ -1156,10 +1160,10 @@ gtk_menu_item_leave (GtkEventController *controller,
"contains-pointer-focus", &contains_focus,
NULL);
if (GTK_IS_MENU_SHELL (menu_shell) &&
if (menu_shell &&
!menu_item->priv->submenu &&
!(is_focus || contains_focus))
gtk_menu_shell_deselect (GTK_MENU_SHELL (menu_shell));
gtk_menu_shell_deselect (menu_shell);
}
static void
@@ -1205,19 +1209,18 @@ static gboolean
gtk_menu_item_mnemonic_activate (GtkWidget *widget,
gboolean group_cycling)
{
GtkWidget *parent;
GtkMenuShell *menu_shell;
menu_shell = gtk_menu_item_get_menu_shell (GTK_MENU_ITEM (widget));
parent = gtk_widget_get_parent (widget);
if (GTK_IS_MENU_SHELL (parent))
_gtk_menu_shell_set_keyboard_mode (GTK_MENU_SHELL (parent), TRUE);
if (menu_shell)
_gtk_menu_shell_set_keyboard_mode (menu_shell, TRUE);
if (group_cycling &&
parent &&
GTK_IS_MENU_SHELL (parent) &&
GTK_MENU_SHELL (parent)->priv->active)
menu_shell &&
menu_shell->priv->active)
{
gtk_menu_shell_select_item (GTK_MENU_SHELL (parent), widget);
gtk_menu_shell_select_item (menu_shell, widget);
}
else
g_signal_emit (widget, menu_item_signals[ACTIVATE_ITEM], 0);
@@ -1239,16 +1242,14 @@ static void
gtk_real_menu_item_activate_item (GtkMenuItem *menu_item)
{
GtkMenuItemPrivate *priv = menu_item->priv;
GtkWidget *parent;
GtkMenuShell *menu_shell;
GtkWidget *widget;
widget = GTK_WIDGET (menu_item);
parent = gtk_widget_get_parent (widget);
menu_shell = gtk_menu_item_get_menu_shell (menu_item);
if (parent && GTK_IS_MENU_SHELL (parent))
if (menu_shell)
{
GtkMenuShell *menu_shell = GTK_MENU_SHELL (parent);
if (priv->submenu == NULL)
gtk_menu_shell_activate_item (menu_shell, widget, TRUE);
else
@@ -1327,8 +1328,8 @@ popped_up_cb (GtkMenu *menu,
gboolean flipped_y,
GtkMenuItem *menu_item)
{
GtkWidget *parent = gtk_widget_get_parent (GTK_WIDGET (menu_item));
GtkMenu *parent_menu = GTK_IS_MENU (parent) ? GTK_MENU (parent) : NULL;
GtkMenuShell *menu_shell = gtk_menu_item_get_menu_shell (menu_item);
GtkMenu *parent_menu = GTK_IS_MENU (menu_shell) ? GTK_MENU (menu_shell) : NULL;
if (parent_menu && GTK_IS_MENU_ITEM (parent_menu->priv->parent_menu_item))
menu_item->priv->submenu_direction = GTK_MENU_ITEM (parent_menu->priv->parent_menu_item)->priv->submenu_direction;
@@ -1367,17 +1368,17 @@ gtk_menu_item_real_popup_submenu (GtkWidget *widget,
GtkBorder menu_padding;
gint horizontal_offset;
gint vertical_offset;
GtkWidget *parent;
GtkMenuShell *menu_shell;
GtkMenu *parent_menu;
parent = gtk_widget_get_parent (widget);
parent_menu = GTK_IS_MENU (parent) ? GTK_MENU (parent) : NULL;
menu_shell = gtk_menu_item_get_menu_shell (menu_item);
parent_menu = GTK_IS_MENU (menu_shell) ? GTK_MENU (menu_shell) : NULL;
if (gtk_widget_is_sensitive (priv->submenu) && parent)
if (gtk_widget_is_sensitive (priv->submenu) && menu_shell)
{
gboolean take_focus;
take_focus = gtk_menu_shell_get_take_focus (GTK_MENU_SHELL (parent));
take_focus = gtk_menu_shell_get_take_focus (menu_shell);
gtk_menu_shell_set_take_focus (GTK_MENU_SHELL (priv->submenu), take_focus);
if (remember_exact_time)
@@ -1434,7 +1435,7 @@ gtk_menu_item_real_popup_submenu (GtkWidget *widget,
horizontal_offset = 0;
vertical_offset = 0;
context = gtk_widget_get_style_context (parent);
context = gtk_widget_get_style_context (GTK_WIDGET (menu_shell));
gtk_style_context_get_padding (context, &parent_padding);
context = gtk_widget_get_style_context (priv->submenu);
gtk_style_context_get_padding (context, &menu_padding);
@@ -1501,11 +1502,11 @@ gtk_menu_item_popup_timeout (gpointer data)
PopupInfo *info = data;
GtkMenuItem *menu_item = info->menu_item;
GtkMenuItemPrivate *priv = menu_item->priv;
GtkWidget *parent;
GtkMenuShell *menu_shell;
parent = gtk_widget_get_parent (GTK_WIDGET (menu_item));
menu_shell = gtk_menu_item_get_menu_shell (menu_item);
if (GTK_IS_MENU_SHELL (parent) && GTK_MENU_SHELL (parent)->priv->active)
if (menu_shell && menu_shell->priv->active)
gtk_menu_item_real_popup_submenu (GTK_WIDGET (menu_item), info->trigger_event, TRUE);
priv->timer = 0;
@@ -1519,11 +1520,11 @@ gtk_menu_item_popup_timeout (gpointer data)
static gint
get_popup_delay (GtkWidget *widget)
{
GtkWidget *parent;
GtkMenuShell *menu_shell;
parent = gtk_widget_get_parent (widget);
if (GTK_IS_MENU_SHELL (parent))
return _gtk_menu_shell_get_popup_delay (GTK_MENU_SHELL (parent));
menu_shell = gtk_menu_item_get_menu_shell (GTK_MENU_ITEM (widget));
if (menu_shell)
return _gtk_menu_shell_get_popup_delay (menu_shell);
else
return MENU_POPUP_DELAY;
}
@@ -1590,13 +1591,13 @@ static gboolean
gtk_menu_item_can_activate_accel (GtkWidget *widget,
guint signal_id)
{
GtkWidget *parent;
GtkMenuShell *menu_shell;
parent = gtk_widget_get_parent (widget);
menu_shell = gtk_menu_item_get_menu_shell (GTK_MENU_ITEM (widget));
/* Chain to the parent GtkMenu for further checks */
return (gtk_widget_is_sensitive (widget) && gtk_widget_get_visible (widget) &&
parent && gtk_widget_can_activate_accel (parent, signal_id));
menu_shell && gtk_widget_can_activate_accel (GTK_WIDGET (menu_shell), signal_id));
}
static void
@@ -1627,10 +1628,10 @@ gtk_menu_item_parent_cb (GObject *object,
{
GtkMenuItem *menu_item = GTK_MENU_ITEM (object);
GtkMenu *menu;
GtkWidget *parent;
GtkMenuShell *menu_shell;
parent = gtk_widget_get_parent (GTK_WIDGET (object));
menu = GTK_IS_MENU (parent) ? GTK_MENU (parent) : NULL;
menu_shell = gtk_menu_item_get_menu_shell (menu_item);
menu = GTK_IS_MENU (menu_shell) ? GTK_MENU (menu_shell) : NULL;
if (menu)
_gtk_menu_item_refresh_accel_path (menu_item,
@@ -1731,8 +1732,8 @@ gtk_menu_item_set_accel_path (GtkMenuItem *menu_item,
const gchar *accel_path)
{
GtkMenuItemPrivate *priv = menu_item->priv;
GtkWidget *parent;
GtkWidget *widget;
GtkMenuShell *menu_shell;
g_return_if_fail (GTK_IS_MENU_ITEM (menu_item));
g_return_if_fail (accel_path == NULL ||
@@ -1747,10 +1748,10 @@ gtk_menu_item_set_accel_path (GtkMenuItem *menu_item,
gtk_widget_set_accel_path (widget, NULL, NULL);
/* install accelerators associated with new path */
parent = gtk_widget_get_parent (widget);
if (GTK_IS_MENU (parent))
menu_shell = gtk_menu_item_get_menu_shell (menu_item);
if (GTK_IS_MENU (menu_shell))
{
GtkMenu *menu = GTK_MENU (parent);
GtkMenu *menu = GTK_MENU (menu_shell);
if (menu->priv->accel_group)
_gtk_menu_item_refresh_accel_path (GTK_MENU_ITEM (widget),

View File

@@ -461,11 +461,14 @@ if cc.get_id() == 'msvc'
endif
endif
cairo_csi_dep = cc.find_library('cairo-script-interpreter')
if not harfbuzz_dep.found()
harfbuzz_dep = dependency('harfbuzz', version: '>= 0.9', required: false,
fallback: ['harfbuzz', 'libharfbuzz_dep'])
endif
cdata.set('HAVE_CAIRO_SCRIPT_INTERPRETER', cairo_csi_dep.found())
cdata.set('HAVE_HARFBUZZ', harfbuzz_dep.found())
cdata.set('HAVE_PANGOFT', pangoft_dep.found())

View File

@@ -6597,7 +6597,7 @@ usage (void)
int
main (int argc, char *argv[])
{
GtkCssProvider *provider, *memory_provider;
GtkCssProvider *memory_provider;
GdkDisplay *display;
GtkBindingSet *binding_set;
int i;
@@ -6615,24 +6615,8 @@ main (int argc, char *argv[])
gtk_init ();
provider = gtk_css_provider_new ();
/* Check to see if we are being run from the correct
* directory.
*/
if (file_exists ("testgtk.css"))
gtk_css_provider_load_from_path (provider, "testgtk.css");
else if (file_exists ("tests/testgtk.css"))
gtk_css_provider_load_from_path (provider, "tests/testgtk.css");
else
g_warning ("Couldn't find file \"testgtk.css\".");
display = gdk_display_get_default ();
gtk_style_context_add_provider_for_display (display, GTK_STYLE_PROVIDER (provider),
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
g_object_unref (provider);
gtk_accelerator_set_default_mod_mask (GDK_SHIFT_MASK |
GDK_CONTROL_MASK |
GDK_MOD1_MASK |

View File

@@ -1,21 +0,0 @@
/* testgtk2.css sets all the buttons in the main window to blue by default */
@import url("testgtk2.css");
* {
font-family: Sans;
font-size: 12px;
}
label:selected {
background-color: gray;
}
label:hover {
background-color: mix (#a0a0a0, rgb (75%, 200, 0%), 0.9);
}
/* override testgtk2, introduce the green color in the button list */
#main_window scrolledwindow button:hover {
background-color: rgb (0%, 75%, 0);
}

View File

@@ -1,10 +0,0 @@
/* this file gets included from testgtk.css */
#main_window button {
font-family: Monospace;
font-size: 10px;
}
#main_window button:hover {
background-color: rgba(0%, 0%, 75%, 0.1);
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 153 B

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -0,0 +1,7 @@
transform {
transform: scale(0.5);
child: cairo {
bounds: 0 0 100 100;
script: url("data:;base64,JSFDYWlyb1NjcmlwdAo8PCAvY29udGVudCAvL0NPTE9SX0FMUEhBIC93aWR0aCA1MCAvaGVpZ2h0IDUwID4+IHN1cmZhY2UgY29udGV4dAoxIDAgMC44IHJnYiBzZXQtc291cmNlCnBhaW50CnBvcAo=");
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 B

View File

@@ -23,6 +23,7 @@ compare_render_tests = [
'clip-coordinates-3d',
'clipped_rounded_clip',
'color-blur0',
'color-matrix-identity',
'cross-fade-in-opacity',
'empty-blend',
'empty-blur',
@@ -50,9 +51,9 @@ compare_render_tests = [
'outset_shadow_offset_y',
'outset_shadow_rounded_top',
'outset_shadow_simple',
'scaled-cairo',
'shadow-in-opacity',
'texture-url',
'color-matrix-identity',
]
renderers = [

View File

@@ -1,5 +1,3 @@
cairo {
bounds: 0 0 50 50;
pixels: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAIAAACRXR/mAAAABmJLR0QA/wD/AP+gvaeTAAAATklEQVRYhe3OMQHAIADAMJh/aXgCA3t6wZEoyNxjjfd8twP/tAqtQqvQKrQKrUKr0Cq0Cq1Cq9AqtAqtQqvQKrQKrUKr0Cq0Cq1Cq9AqDsEHAi9RKkB7AAAAAElFTkSuQmCC");
script: url("data:;base64,JSFDYWlyb1NjcmlwdAo8PCAvY29udGVudCAvL0NPTE9SX0FMUEhBIC93aWR0aCA1MCAvaGVpZ2h0IDUwID4+IHN1cmZhY2UgY29udGV4dAoxIDAgMC44IHJnYiBzZXQtc291cmNlCnBhaW50CnBvcAo=");
}