[GTK3] X11 ConfigureNotify event with bad width/height results in window that doesn't repaint itself anymore
We've recently moved to RHEL 9.2 and observe odd behavior in Eclipse, in a VNC session, when the workstation is under heavy load. When restoring and then maximizing the VNC client window, the GTK3 application stops repainting:
We were able to reproduce the problem, in our environment, with a GTK3 snippet:
#include <gtk/gtk.h>
enum
{
COL_URI = 0,
NUM_COLS
} ;
// gcc -g table.c `pkg-config --cflags --libs gtk+-3.0` -o table && ./table
int main (int argc, char **argv)
{
g_print("major=%d, minor=%d, micro=%d\n", gtk_get_major_version(), gtk_get_minor_version(), gtk_get_micro_version());
GtkWidget *window, *scrolled_window, *box, *tree;
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
g_signal_connect(window, "delete_event", gtk_main_quit, NULL);
gtk_window_set_default_size(GTK_WINDOW(window), 500, 1000);
scrolled_window = gtk_scrolled_window_new (NULL, NULL);
gtk_container_add (GTK_CONTAINER (window), scrolled_window);
box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
gtk_container_add(GTK_CONTAINER(scrolled_window), box);
int n = 25;
int i;
for (i = 0; i < n; ++i)
{
GtkTreeViewColumn *col1;
GtkCellRenderer *renderer;
GtkListStore *liststore;
liststore = gtk_list_store_new(NUM_COLS, G_TYPE_STRING);
tree = gtk_tree_view_new_with_model(GTK_TREE_MODEL(liststore));
g_object_unref(liststore); /* destroy model with view */
col1 = gtk_tree_view_column_new();
gtk_tree_view_column_set_title(col1, "column");
gtk_tree_view_append_column(GTK_TREE_VIEW(tree), col1);
renderer = gtk_cell_renderer_text_new();
gtk_tree_view_column_pack_start(col1, renderer, TRUE);
gtk_tree_view_column_add_attribute(col1, renderer, "text", COL_URI + 0);
renderer = gtk_cell_renderer_pixbuf_new();
gtk_tree_view_column_pack_start(col1, renderer, TRUE);
//gtk_tree_view_column_add_attribute(col1, renderer, "pixbuf", COL_URI + 0);
gtk_tree_view_column_set_fixed_width(col1, 150);
gtk_tree_view_column_set_resizable(col1, TRUE);
gtk_box_pack_start(GTK_BOX(box), tree, TRUE, TRUE, 0);
GtkTreeStore *treestore;
treestore = gtk_tree_store_new(NUM_COLS, G_TYPE_STRING);
gtk_tree_view_set_model(GTK_TREE_VIEW(tree), NULL);
gtk_tree_view_set_model(GTK_TREE_VIEW(tree), GTK_TREE_MODEL(treestore));
GtkTreeIter iter;
int j;
for (j = 0; j < 3; ++j)
{
gtk_tree_store_append(treestore, &iter, NULL);
gtk_tree_store_set(treestore, &iter, COL_URI, "item", -1);
}
GtkTreePath *path;
path = gtk_tree_model_get_path (GTK_TREE_MODEL(treestore), &iter);
gtk_tree_view_set_cursor (GTK_TREE_VIEW(tree), path, col1, FALSE);
gtk_tree_path_free (path);
}
gtk_widget_show_all(window);
gtk_main();
return 0;
}
The steps to reproduce, in our environment, are:
- Start a VNC server on RHEL 9.2, attach a client to it.
- Restore the VNC client window, reduce its size (e.g. to 1/4 of the screen).
- Maximize the VNC client window.
- Run the GTK3 snippet, see the code above.
- Restore the VNC client window.
- Maximize the VNC client window.
- Resize the GTK3 snippet window, observe its not being repainted anymore.
Installed GTK3 version is: gtk3-3.24.31-2.el9.x86_64
We use X11. We opened an issue at RHEL support, unfortunately the issue was not reproducible by the contact at RHEL.
We have debugged the issue, it amounts to the following:
A ConfigureNotify
event is received (I assume, sent by the X11) by the GTK3 application:
Gdk-Message: 14:23:42.125: configure notify: window: 71303171 x,y: 0 0 w,h: 500 65507 b-w: 0 above: 0 ovr: 0
An attached (to the GTK3 application) xev
prints these events as:
ConfigureNotify event, serial 18, synthetic NO, window 0x3800007,
event 0x3800007, window 0x3800007, (0,0), width 500, height 65507,
border_width 0, above 0x0, override NO
ConfigureNotify event, serial 18, synthetic YES, window 0x3800007,
event 0x3800007, window 0x3800007, (710,29), width 500, height 65507,
border_width 0, above 0x0, override NO
This is then delegated by GTK3 to cairo:
#0 _cairo_error (status=status@entry=CAIRO_STATUS_INVALID_SIZE) at cairo-error.c:68
#1 0x00007ffff74472fb in cairo_xlib_surface_set_size (abstract_surface=0x6bf4c0, width=500, height=65507) at cairo-xlib-surface.c:2118
#2 0x00007ffff76d152a in _gdk_x11_window_update_size (impl=0x6f3f00) at gdkwindow-x11.c:196
#3 0x00007ffff76b25f7 in gdk_x11_display_translate_event (translator=0x4350e0, display=0x4350e0, event=0x748290, xevent=0x7fffffffd180) at gdkdisplay-x11.c:1026
#4 0x00007ffff76bf820 in _gdk_x11_event_translator_translate (translator=0x4350e0, display=0x4350e0, xevent=0x7fffffffd180) at gdkeventtranslator.c:51
#5 0x00007ffff76bef6b in gdk_event_source_translate_event (event_source=0x463e20, xevent=0x7fffffffd180) at gdkeventsource.c:243
#6 0x00007ffff76bf1f6 in _gdk_x11_display_queue_events (display=0x4350e0) at gdkeventsource.c:341
#7 0x00007ffff766f9f2 in gdk_display_get_event (display=0x4350e0) at gdkdisplay.c:438
#8 0x00007ffff76bf295 in gdk_event_source_dispatch (source=0x463e20, callback=0x0, user_data=0x0) at gdkeventsource.c:363
#9 0x00007ffff7068e2f in g_main_context_dispatch () at /lib64/libglib-2.0.so.0
#10 0x00007ffff70bd508 in g_main_context_iterate.constprop () at /lib64/libglib-2.0.so.0
#11 0x00007ffff7068483 in g_main_loop_run () at /lib64/libglib-2.0.so.0
#12 0x00007ffff7a2d99a in gtk_main () at gtkmain.c:1323
#13 0x00000000004028d5 in main (argc=1, argv=0x7fffffffd638) at table.c:123
cairo assumes the height to be invalid, due to this definition:
#define XLIB_COORD_MAX 32767
From that point onward, GTK3 determines that the clip area is empty, due to this code:
gboolean
gdk_cairo_get_clip_rectangle (cairo_t *cr,
GdkRectangle *rect)
{
double x1, y1, x2, y2;
gboolean clip_exists;
cairo_clip_extents (cr, &x1, &y1, &x2, &y2);
clip_exists = x1 < x2 && y1 < y2;
...
return clip_exists;
}
cairo_clip_extents
"returns" 0,0,0,0 due to the broken cairo context.
We assume this is some X11 bug, or some bug caused by the VNC session, either server or client (our client is tigervnc
).
So our question for GTK3 is, should GTK3 do some validation on X11 events, to avoid breaking the cairo paint context if such unexpected events are received?