Re: initial draw problem with gnomedruid/gtklist




NotZed <notzed@helixcode.com> writes:

> Hi guys,
> 
> The attached program below demonstrates a problem i'm
> having with GnomeDruid, Havoc suggested I post here.
> 
> Basically the problem is that some things I have inside of
> viewported'd scrolled windows dont seem to render, until
> you resize the window, and then ones that continue to
> render as i switch pages dont update their contents if the
> contents change during the page setup.
> 
> Anywya, the program is below, and the behaviour is
> self-explanatory.

OK, I tracked this one down and I'd say it is pretty clearly a GTK+
bug, though it could be conceivably blamed on GnomeDruid.
The problem is the following code in gtkcontainer.c:

=====
void
gtk_container_queue_resize (GtkContainer *container)
{
  GtkContainer *resize_container;
  
  g_return_if_fail (container != NULL);
  g_return_if_fail (GTK_IS_CONTAINER (container));

  [...]
  
  resize_container = gtk_container_get_resize_container (container);
  
  if (resize_container)
    {
      if (GTK_WIDGET_VISIBLE (resize_container) &&
	  (GTK_WIDGET_TOPLEVEL (resize_container) || GTK_WIDGET_DRAWABLE (resize_container)))
	{

  [...]
=====

In the test case, list items are added just before switching to a 
new page of the druid.

When the items are added the above code is triggered, and the
resize_container found is the GtkScrolledWindow.

The GtkScrolledWindow is not mapped, since it is in is not
current, so the above code thinks it doesn't need to queue a 
resize, since one will be queued when the window is mapped.

But the scrolled window is visible, and all its parents are visible,
and no resize is queued when it is mapped. For this reason the newly
added list items never get size allocated.

I think the above conditional is just completely bogus. It could
be:

 if (GTK_WIDGET_VISIBLE (resize_container))

Or, if you wanted to be more precise, you could define a function
that checked if a widget and all its parents are visible and 
replace the GTK_WIDGET_DRAWABLE() in the above with that. But I don't
think the win in efficiency from doing so is very large.

Regards,
                                        Owen


> #include <glib.h>
> #include <gtk/gtk.h>
> #include <gnome.h>
> 
> static char *texts[] = { "one", "two", "four", "fifty-seven", 0};
> 
> static void
> prepare_rules(GnomeDruidPage *page, GtkWidget *druid, void *data)
> {
> 	GtkWidget *list;
> 	GList *items = NULL;
> 	GtkWidget *item;
> 	int i=0;
> 
> 	list = gtk_object_get_data(GTK_OBJECT(page), "list");
> 
> 	gtk_list_remove_items(GTK_LIST(list), GTK_LIST(list)->children);
> 
> 	while (texts[i]) {
> 		char *str;
> 
> 		str = texts[i];
> 
> 		item = gtk_list_item_new_with_label(str);
> 		items = g_list_append(items, item);
> 
> 		gtk_widget_show(item);
> 		i++;
> 	}
> 	gtk_list_append_items(GTK_LIST(list), items);
> 	
> 	gtk_widget_show_all(list);
> 	gtk_widget_queue_resize(list);
> }
> 
> GtkWidget *
> create_druid(void)
> {
> 	GnomeDruid *druid;
> 	GtkWidget *list, *html, *frame, *page;
> 	GtkWidget *scrolled_window;
> 
> 	druid = GNOME_DRUID(gnome_druid_new());
> 	gnome_druid_append_page(druid, GNOME_DRUID_PAGE(gnome_druid_page_start_new_with_vals("Options Helper", "Text?", NULL, NULL)));
> 
> 	/* first page, select base rule */
> 	page = gnome_druid_page_standard_new_with_vals("Option setup", NULL);
> 	list = gtk_list_new();
> 	frame = gtk_frame_new(_("A list of options"));
> 
> 	scrolled_window = gtk_scrolled_window_new (NULL, NULL);
> 	gtk_widget_show(list);
> 	gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolled_window), list);
> 	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
> 					GTK_POLICY_AUTOMATIC,
> 					GTK_POLICY_AUTOMATIC);
> 	gtk_container_add(GTK_CONTAINER(frame), scrolled_window);
> 	gtk_widget_show(frame);
> 	gtk_container_set_focus_vadjustment
> 		(GTK_CONTAINER (list),
> 		 gtk_scrolled_window_get_vadjustment
> 		 (GTK_SCROLLED_WINDOW (scrolled_window)));
> 	gtk_widget_show(scrolled_window);
> 
> 	gtk_box_pack_start(GTK_BOX(GNOME_DRUID_PAGE_STANDARD(page)->vbox), frame, TRUE, TRUE, GNOME_PAD);
> 
> 	frame = gtk_frame_new(_("Definition"));
> 	html = gtk_label_new("No its not at all\n\nThe options do not show until you resize\nthis window!");
> 	scrolled_window = gtk_scrolled_window_new (NULL, NULL);
> 	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
> 					GTK_POLICY_AUTOMATIC,
> 					GTK_POLICY_AUTOMATIC);
> 	gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolled_window), html);
> 	gtk_container_add(GTK_CONTAINER(frame), scrolled_window);
> 	gtk_box_pack_start(GTK_BOX(GNOME_DRUID_PAGE_STANDARD(page)->vbox), frame, TRUE, TRUE, GNOME_PAD);
> 
> 	gtk_widget_show_all(page);
> 	gnome_druid_append_page(druid, GNOME_DRUID_PAGE(page));
> 
> 	gtk_object_set_data(GTK_OBJECT(page), "list", list);
> 	gtk_object_set_data(GTK_OBJECT(page), "html", html);
> 	gtk_signal_connect(GTK_OBJECT(page), "prepare", prepare_rules, 0);
> 
> 	return GTK_WIDGET(druid);
> }
> 
> 
> int
> main(int argc, char **argv)
> {
> 	GnomeApp *app;
> 	GtkWidget *druid;
> 
> 	gnome_init("Test", "0.0", argc, argv);
> 	gdk_rgb_init ();
> 	app = GNOME_APP(gnome_app_new("test", "test"));
> 	druid =  create_druid();
> 	gnome_app_set_contents (GNOME_APP (app), druid);
> 	gtk_widget_show_all(GTK_WIDGET(app));
> 	gtk_main();
> 	return 0;
> }



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