After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 765700 - GtkPaned use causes "How does the code know the size to allocate?"
GtkPaned use causes "How does the code know the size to allocate?"
Status: RESOLVED FIXED
Product: gtk+
Classification: Platform
Component: Widget: Other
3.20.x
Other Linux
: Normal normal
: ---
Assigned To: gtk-bugs
gtk-bugs
Depends on:
Blocks:
 
 
Reported: 2016-04-27 23:31 UTC by Morten Welinder
Modified: 2016-05-14 16:53 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description Morten Welinder 2016-04-27 23:31:15 UTC
I get the following warning upon starting Gnumeric with gtk+ 3.20:

(/home/welinder/gnome/gnumeric/src/.libs/lt-gnumeric:25516): Gtk-WARNING **: Allocating size to GtkLabel 0x1789940 without calling gtk_widget_get_preferred_width/height(). How does the code know the size to allocate?

The same warning can be triggered with the small test program below.
Start the program and drag the GtkPaned handle to the left.

I am blaming GtkPaned, but I have not been able to trigger this without
the GtkGrid.





#include "config.h"
#include <stdio.h>
#include <string.h>
#include <gtk/gtk.h>



static void
create_progress_bar(void)
{
  GtkWidget *window = gtk_window_new (GTK_WINDOW_TOPLEVEL);

  gtk_window_set_title (GTK_WINDOW (window), "GtkProgress_Bar Example");
  gtk_container_set_border_width (GTK_CONTAINER (window), 12);
  g_signal_connect (window, "destroy",
		    G_CALLBACK (gtk_main_quit),
		    NULL);
  g_signal_connect (window, "delete-event",
		    G_CALLBACK (gtk_false),
		    NULL);

  GtkWidget *pbar = gtk_progress_bar_new ();
  gtk_progress_bar_set_ellipsize (GTK_PROGRESS_BAR (pbar), PANGO_ELLIPSIZE_END);
  gtk_progress_bar_set_show_text (GTK_PROGRESS_BAR (pbar), TRUE);
  gtk_progress_bar_set_text (GTK_PROGRESS_BAR (pbar), " ");

  gtk_container_add (GTK_CONTAINER (window), pbar);

  gtk_window_set_default_size (GTK_WINDOW (window), 600, 0);
  gtk_widget_show_all (window);
}

static void
create_paned(void)
{
  GtkWidget *window = gtk_window_new (GTK_WINDOW_TOPLEVEL);

  gtk_window_set_title (GTK_WINDOW (window), "GtkProgress_Bar Example");
  gtk_container_set_border_width (GTK_CONTAINER (window), 12);
  g_signal_connect (window, "destroy",
		    G_CALLBACK (gtk_main_quit),
		    NULL);
  g_signal_connect (window, "delete-event",
		    G_CALLBACK (gtk_false),
		    NULL);
  GtkGrid *grid = GTK_GRID (gtk_grid_new ());

  GtkWidget *paned = gtk_paned_new (GTK_ORIENTATION_HORIZONTAL);
  GtkWidget *c1 = gtk_label_new ("a");
  GtkWidget *c2 = gtk_label_new ("b");
  gtk_paned_add1 (GTK_PANED (paned), c1);
  gtk_container_child_set (GTK_CONTAINER (paned), c1,
			   "resize", FALSE,
			   "shrink", TRUE,
			   NULL);
  gtk_paned_add2 (GTK_PANED (paned), c2);
  gtk_container_child_set (GTK_CONTAINER (paned), c2,
			   "resize", TRUE,
			   "shrink", TRUE,
			   NULL);

  gtk_paned_set_position (GTK_PANED (paned), 42);

  gtk_grid_attach (grid, paned, 0, 4, 4, 1);

  gtk_container_add (GTK_CONTAINER (window), GTK_WIDGET (grid));

  gtk_window_set_default_size (GTK_WINDOW (window), 600, 0);
  gtk_widget_show_all (window);
}


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

  if (g_getenv ("GTK_RTL"))
    gtk_widget_set_default_direction (GTK_TEXT_DIR_RTL);

  if (0) create_progress_bar();

  create_paned();

  gtk_main();

  return(0);
}
/* example-end */
Comment 1 Benjamin Otte (Company) 2016-05-14 16:53:14 UTC
commit ddcf47026dbbe58dca3b34c7bb1ec63bb50a861a
Author: Benjamin Otte <otte@redhat.com>
Date:   Sat May 14 18:35:27 2016 +0200

    widget: No longer postpone style-updated on unrealized widgets
    
    GTK used to not emit GtkWidget::style-updated on widgets that weren't
    realized. This sped up construction of complex widgetry in the early
    days of GTK3 where we instantly invalidated on every change.
    We don't do that anymore, so in theory (and in my limited testing with
    widget-factory) this shouldn't be a prolem anymore.
    
    What is a problem though is that postponing style-updated leads to 2
    problems:
    (1) Unrealized widgets will not emit style-updated which may cause them
        to not properly update their state and return wrong values from
        get_preferred_width/height() etc
    (2) Emitting style-updated during realize can happen too late.
        When a widget is not made child-visible by its parent (common
        examples: notebook, paned) it will also not be realized when the
        parent is initially shown. However, when they get realized later
        (after a resize of the parent), they will emit style-updated (and
        potentially queue a resize) during size-allocate.