Assertion failed: (color->type == COLOR_TYPE_LITERAL)
Here's a sample code that triggers an assertion in gtkcsscolorvalue.c:792 (using the Default theme)
#include <gtk/gtk.h>
const char *css = ""
".my-button { filter: drop-shadow(6px 6px 8px gray); }"
"";
static void
on_parsing_error (GtkCssProvider *css_provider,
GtkCssSection *css_section,
GError *error,
gpointer user_data)
{
g_print ("CSS parsing error: %s\n", error ? error->message : "unknown");
}
static void
add_custom_style_sheet ()
{
GtkCssProvider *css_provider = gtk_css_provider_new ();
g_signal_connect (css_provider, "parsing-error", G_CALLBACK (on_parsing_error), NULL);
gtk_css_provider_load_from_data (css_provider, css, -1);
gtk_style_context_add_provider_for_display (gdk_display_get_default (),
GTK_STYLE_PROVIDER (css_provider),
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
}
static void
on_button_clicked (GtkToggleButton *button,
gpointer user_data)
{
/* Removing both both .flat and .my-button classes triggers a transition
* (assuming the Default theme as of GTK 4.10). This in turn introduces
* GTK CSS color values with color-mix type.
*/
gtk_widget_remove_css_class (GTK_WIDGET (button), "my-button");
gtk_button_set_has_frame (GTK_BUTTON (button), FALSE);
}
static void
on_activate (GtkApplication *app,
gpointer user_data)
{
GtkWidget *window = gtk_application_window_new (app);
GtkWidget *button = gtk_button_new_with_label ("Toggle");
add_custom_style_sheet ();
gtk_widget_add_css_class (button, "my-button");
g_signal_connect (button, "clicked", G_CALLBACK (on_button_clicked), NULL);
gtk_window_set_child (GTK_WINDOW (window), button);
gtk_window_present (GTK_WINDOW (window));
}
int main (int argc, char **argv)
{
GtkApplication *app;
int status;
app = gtk_application_new("test.gtk4-style-change", G_APPLICATION_DEFAULT_FLAGS);
g_signal_connect (app, "activate", G_CALLBACK (on_activate), NULL);
status = g_application_run (G_APPLICATION (app), argc, argv);
g_object_unref (app);
return status;
}
The callstack when the assertion is hit:
**
Gtk:ERROR:../gtk4/gtk/gtkcsscolorvalue.c:802:gtk_css_color_value_get_rgba: assertion failed: (color->type == COLOR_TYPE_LITERAL)
Bail out! Gtk:ERROR:../gtk4/gtk/gtkcsscolorvalue.c:802:gtk_css_color_value_get_rgba: assertion failed: (color->type == COLOR_TYPE_LITERAL)
Thread 1 "test-gtk4-style" received signal SIGABRT, Aborted.
0x00007ffff6cf18ec in ?? () from /usr/lib/libc.so.6
(gdb) bt
#0 0x00007ffff6cf18ec in () at /usr/lib/libc.so.6
#1 0x00007ffff6ca2ea8 in raise () at /usr/lib/libc.so.6
#2 0x00007ffff6c8c53d in abort () at /usr/lib/libc.so.6
#3 0x00007ffff6e6f064 in () at /usr/lib/libglib-2.0.so.0
#4 0x00007ffff6ed81e0 in g_assertion_message_expr () at /usr/lib/libglib-2.0.so.0
#5 0x00007ffff77c6412 in gtk_css_color_value_get_rgba (color=0x5555555d6c40) at ../gtk4/gtk/gtkcsscolorvalue.c:802
#6 0x00007ffff77fd2f9 in gtk_css_shadow_value_push_snapshot (value=0x55555560ad10, snapshot=0x555557ac4d80) at ../gtk4/gtk/gtkcssshadowvalue.c:722
#7 0x00007ffff77d0b04 in gtk_css_filter_value_push_snapshot (filter=0x555557a832d0, snapshot=0x555557ac4d80) at ../gtk4/gtk/gtkcssfiltervalue.c:960
#8 0x00007ffff77765d8 in gtk_widget_create_render_node (widget=0x55555563a970, snapshot=0x555557ac4d80) at ../gtk4/gtk/gtkwidget.c:11760
#9 0x00007ffff777683e in gtk_widget_do_snapshot (widget=0x55555563a970, snapshot=0x555557ac4d80) at ../gtk4/gtk/gtkwidget.c:11811
#10 0x00007ffff7777760 in gtk_widget_snapshot_child (widget=0x555555636900, child=0x55555563a970, snapshot=0x555557ac4d80) at ../gtk4/gtk/gtkwidget.c:12232
#11 0x00007ffff775e603 in gtk_widget_real_snapshot (widget=0x555555636900, snapshot=0x555557ac4d80) at ../gtk4/gtk/gtkwidget.c:757
#12 0x00007ffff777668e in gtk_widget_create_render_node (widget=0x555555636900, snapshot=0x555557ac4d80) at ../gtk4/gtk/gtkwidget.c:11771
#13 0x00007ffff777683e in gtk_widget_do_snapshot (widget=0x555555636900, snapshot=0x555557ac4d80) at ../gtk4/gtk/gtkwidget.c:11811
#14 0x00007ffff77768f6 in gtk_widget_snapshot (widget=0x555555636900, snapshot=0x555557ac4d80) at ../gtk4/gtk/gtkwidget.c:11833
#15 0x00007ffff7776a0c in gtk_widget_render (widget=0x555555636900, surface=0x5555556b4150, region=0x555557ae9010) at ../gtk4/gtk/gtkwidget.c:11865
#16 0x00007ffff778634b in surface_render (surface=0x5555556b4150, region=0x555557ae9010, widget=0x555555636900) at ../gtk4/gtk/gtkwindow.c:4738
#17 0x00007ffff79bbbfd in _gdk_marshal_BOOLEAN__BOXEDv
(closure=0x555557a65be0, return_value=0x7fffffffd7b0, instance=0x5555556b4150, args=0x7fffffffd860, marshal_data=0x0, n_params=1, param_types=0x5555556b2250)
at gdk/gdkmarshalers.c:130
#18 0x00007ffff6fce23c in g_signal_emit_valist () at /usr/lib/libgobject-2.0.so.0
#19 0x00007ffff6fce324 in g_signal_emit () at /usr/lib/libgobject-2.0.so.0
#20 0x00007ffff7a6a50c in gdk_surface_process_updates_internal (surface=0x5555556b4150) at ../gtk4/gdk/gdksurface.c:1361
#21 0x00007ffff7a6a874 in gdk_surface_paint_on_clock (clock=0x5555556b1270, data=0x5555556b4150) at ../gtk4/gdk/gdksurface.c:1449
#22 0x00007ffff6fce23c in g_signal_emit_valist () at /usr/lib/libgobject-2.0.so.0
#23 0x00007ffff6fce324 in g_signal_emit () at /usr/lib/libgobject-2.0.so.0
#24 0x00007ffff7a4f80f in _gdk_frame_clock_emit_paint (frame_clock=0x5555556b1270) at ../gtk4/gdk/gdkframeclock.c:708
#25 0x00007ffff7a50872 in gdk_frame_clock_paint_idle (data=0x5555556b1270) at ../gtk4/gdk/gdkframeclockidle.c:612
#26 0x00007ffff6eabd62 in () at /usr/lib/libglib-2.0.so.0
#27 0x00007ffff6eab53b in g_main_context_dispatch () at /usr/lib/libglib-2.0.so.0
#28 0x00007ffff6f08219 in () at /usr/lib/libglib-2.0.so.0
#29 0x00007ffff6eaa1a2 in g_main_context_iteration () at /usr/lib/libglib-2.0.so.0
#30 0x00007ffff70d93de in g_application_run () at /usr/lib/libgio-2.0.so.0
#31 0x000055555555550c in main ()
(gdb) frame 6
#6 0x00007ffff77fd2f9 in gtk_css_shadow_value_push_snapshot (value=0x55555560ad10, snapshot=0x555557ac4d80) at ../gtk4/gtk/gtkcssshadowvalue.c:722
722 if (!gdk_rgba_is_clear (gtk_css_color_value_get_rgba (shadow->color)))
(gdb) frame 5
#5 0x00007ffff77c6412 in gtk_css_color_value_get_rgba (color=0x5555555d6c40) at ../gtk4/gtk/gtkcsscolorvalue.c:802
802 g_assert (color->type == COLOR_TYPE_LITERAL);
(gdb) p *color
$1 = {class = 0x7ffff7cbe060 <GTK_CSS_VALUE_COLOR>, ref_count = 1, is_computed = 0, type = COLOR_TYPE_MIX, last_value = 0x0, sym_col = {
name = 0x55555569e8d0 "`\340\313\367\377\177", rgba = {red = 1.60741332e+13, green = 3.0611365e-41, blue = -8.31586717e+33, alpha = 4.59163468e-41}, shade = {
color = 0x55555569e8d0, factor = 6.9533490114711422e-310}, alpha = {color = 0x55555569e8d0, factor = 6.9533490114711422e-310}, mix = {color1 = 0x55555569e8d0,
color2 = 0x7ffff7cd0080 <current_color>, factor = 0.040689637514677385}}}
(gdb)
Here we can see that gtkcssshadowvalue.c
assumes COLOR_TYPE_LITERAL
values. The COLOR_TYPE_MIX
value is created internally during a transition, and seems a legitimate use-case:
(gdb) bt
#0 _gtk_css_color_value_new_mix (color1=0x5555556372d0, color2=0x7ffff7cd0080 <current_color>, factor=0.076502482208707451) at ../gtk4/gtk/gtkcsscolorvalue.c:625
#1 0x00007ffff77c270e in gtk_css_value_color_transition (start=0x5555556372d0, end=0x7ffff7cd0080 <current_color>, property_id=86, progress=0.076502482208707451)
at ../gtk4/gtk/gtkcsscolorvalue.c:222
#2 0x00007ffff7817ce2 in _gtk_css_value_transition (start=0x5555556372d0, end=0x7ffff7cd0080 <current_color>, property_id=86, progress=0.076502482208707451)
at ../gtk4/gtk/gtkcssvalue.c:282
#3 0x00007ffff77fadec in shadow_value_transition (start=0x555555637328, end=0x55555561adb8, property_id=86, progress=0.076502482208707451, result=0x7fffffffc350)
at ../gtk4/gtk/gtkcssshadowvalue.c:94
#4 0x00007ffff77fb332 in gtk_css_value_shadow_transition (start=0x555555637310, end=0x55555561ada0, property_id=86, progress=0.076502482208707451)
at ../gtk4/gtk/gtkcssshadowvalue.c:186
#5 0x00007ffff7817ce2 in _gtk_css_value_transition (start=0x555555637310, end=0x55555561ada0, property_id=86, progress=0.076502482208707451)
at ../gtk4/gtk/gtkcssvalue.c:282
#6 0x00007ffff77cd109 in gtk_css_filter_transition (result=0x555557a70528, start=0x555555637398, end=0x7fffffffc4b0, property_id=86, progress=0.076502482208707451)
at ../gtk4/gtk/gtkcssfiltervalue.c:529
#7 0x00007ffff77cd332 in gtk_css_value_filter_transition
(start=0x555555637380, end=0x7ffff7cd0dc0 <filter_none_singleton>, property_id=86, progress=0.076502482208707451) at ../gtk4/gtk/gtkcssfiltervalue.c:592
#8 0x00007ffff7817ce2 in _gtk_css_value_transition (start=0x555555637380, end=0x7ffff7cd0dc0 <filter_none_singleton>, property_id=86, progress=0.076502482208707451)
at ../gtk4/gtk/gtkcssvalue.c:282
#9 0x00007ffff7816d25 in gtk_css_transition_apply_values (style_animation=0x5555555fb5c0, style=0x555557b21c40) at ../gtk4/gtk/gtkcsstransition.c:66
#10 0x00007ffff784f265 in _gtk_style_animation_apply_values (animation=0x5555555fb5c0, style=0x555557b21c40) at ../gtk4/gtk/gtkstyleanimation.c:37
#11 0x00007ffff77bdf67 in gtk_css_animated_style_apply_animations (style=0x555557b21c40) at ../gtk4/gtk/gtkcssanimatedstyle.c:870
#12 0x00007ffff77be850 in gtk_css_animated_style_new_advance (source=0x555557b052e0, base_style=0x555557afa660, timestamp=8568438343)
at ../gtk4/gtk/gtkcssanimatedstyle.c:986
#13 0x00007ffff77e88c0 in gtk_css_node_real_update_style
(cssnode=0x5555556548a0, filter=0x7fffffffc7e0, change=1125899906842624, timestamp=8568438343, style=0x555557b052e0) at ../gtk4/gtk/gtkcssnode.c:448
#14 0x00007ffff77e98d1 in gtk_css_node_do_ensure_style (cssnode=0x5555556548a0, filter=0x7fffffffc7e0, current_time=8568438343) at ../gtk4/gtk/gtkcssnode.c:951
#15 0x00007ffff77e9a0a in gtk_css_node_ensure_style (cssnode=0x5555556548a0, filter=0x7fffffffc7e0, current_time=8568438343) at ../gtk4/gtk/gtkcssnode.c:998
#16 0x00007ffff77ea361 in gtk_css_node_validate_internal (cssnode=0x5555556548a0, filter=0x7fffffffc7e0, timestamp=8568438343) at ../gtk4/gtk/gtkcssnode.c:1320
#17 0x00007ffff77ea40a in gtk_css_node_validate_internal (cssnode=0x555555671e00, filter=0x7fffffffc7e0, timestamp=8568438343) at ../gtk4/gtk/gtkcssnode.c:1342
#18 0x00007ffff77ea503 in gtk_css_node_validate (cssnode=0x555555671e00) at ../gtk4/gtk/gtkcssnode.c:1362
#19 0x00007ffff7695df1 in frame_clock_update_cb (clock=0x5555556c9680, native=0x5555556366e0) at ../gtk4/gtk/gtknative.c:103
#20 0x00007ffff6fb0210 in g_closure_invoke () at /usr/lib/libgobject-2.0.so.0
#21 0x00007ffff6fde5c6 in () at /usr/lib/libgobject-2.0.so.0
#22 0x00007ffff6fce095 in g_signal_emit_valist () at /usr/lib/libgobject-2.0.so.0
#23 0x00007ffff6fce324 in g_signal_emit () at /usr/lib/libgobject-2.0.so.0
#24 0x00007ffff7a4f7a5 in _gdk_frame_clock_emit_update (frame_clock=0x5555556c9680) at ../gtk4/gdk/gdkframeclock.c:684
#25 0x00007ffff7a50715 in gdk_frame_clock_paint_idle (data=0x5555556c9680) at ../gtk4/gdk/gdkframeclockidle.c:560
#26 0x00007ffff6eabd62 in () at /usr/lib/libglib-2.0.so.0
--Type <RET> for more, q to quit, c to continue without paging--c
#27 0x00007ffff6eab53b in g_main_context_dispatch () at /usr/lib/libglib-2.0.so.0
#28 0x00007ffff6f08219 in () at /usr/lib/libglib-2.0.so.0
#29 0x00007ffff6eaa1a2 in g_main_context_iteration () at /usr/lib/libglib-2.0.so.0
#30 0x00007ffff70d93de in g_application_run () at /usr/lib/libgio-2.0.so.0
#31 0x000055555555550c in main ()
(gdb)
So I think that the checks for transparent colors in gtkcssshadowvalue should not assume that colors are literals. We could add a gtk_css_color_value_is_clear()
helper.
Question: can GdkRGBA represents colors outside of the sRGB color-space (by going outside of the [0.0, 1.0] range)? If so we could make get_rgba()
realize the color and return an appropriate value whatever the COLOR_TYPE is.