gtk_widget_queue_resize() forgetting allocation



Hello,

I've run into an issue in a program I'm writing where sometimes a call to
gtk_widget_queue_resize() ends in a request rather than an allocate.  I've
put together a short test case (tested in GTK+ 2.4.4) which keeps the spirit
of the program intact (see below).

First, a little context -- connecting to the toplevel window's
configure-event to queue a resize on one of its grandchildren probably seems
unconventional and even redundant, but it's a requirement of my program (not
this test case) because the request function of that grandchild optimizes
itself to the window's width (i.e. the grandchild needs more information than
just the size requests of its children).  In the real program the change in
the window's width is passed on and then the queue_resize is made.

All of that is beside the point.  Here is the problem: _sometimes_ when the
window is resized, there is no allocation of the grandchild label after a
request.  If the window is resized again, _then_ the allocation happens
(usually followed by another unfulfilled size request).

One thing that's kind-of strange is that if the label is added directly to
the scrolledwindow (without being added to the vbox, which then gets put into
the scrolledwindow), everything works as it should -- every size request is
followed by a size allocate.  I also tried using a table instead of a vbox,
but the result is the same.

Insight welcome.

Thanks,

Stephen

=========

#include <gtk/gtk.h>

static void
allocate_callback(GtkWidget *label, GtkAllocation *allocation, gpointer data) {
	g_print("(allocate)");
}

static void
request_callback(GtkWidget *label, GtkRequisition *requisition, gpointer data) {
	g_print("(request)");
}

static gboolean
configure_callback(GtkWidget* window, GdkEventConfigure* event, gpointer data) {
	GtkWidget* label = data;

	/* Only queue resize if the width is changed */
	if (event->width != window->allocation.width)
		gtk_widget_queue_resize(label);

	return FALSE;
}

int
main(int argc, char* argv[]) {

	GtkWidget* window;
	GtkWidget* scrolled_window;
	GtkWidget* vbox;
	GtkWidget* label;

	gtk_init (&argc, &argv);

	window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
	scrolled_window = gtk_scrolled_window_new(NULL, NULL);
	vbox = gtk_vbox_new(FALSE, 0);
	label = gtk_label_new("Testing");

	g_signal_connect(G_OBJECT(label), "size-allocate",
	                 G_CALLBACK(allocate_callback), NULL);
	g_signal_connect(G_OBJECT(label), "size-request",
	                 G_CALLBACK(request_callback), NULL);
	g_signal_connect(G_OBJECT(window), "configure-event",
	                 G_CALLBACK(configure_callback), label);

	gtk_scrolled_window_set_policy(
		GTK_SCROLLED_WINDOW(scrolled_window),
		GTK_POLICY_NEVER,
		GTK_POLICY_ALWAYS);

	gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
	gtk_scrolled_window_add_with_viewport(
		GTK_SCROLLED_WINDOW(scrolled_window), vbox);
	gtk_container_add(GTK_CONTAINER(window), scrolled_window);

	gtk_widget_show(label);
	gtk_widget_show(vbox);
	gtk_widget_show(scrolled_window);
	gtk_widget_show(window);

	gtk_main();

	return 0;
}




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]