Re: gtk_widget_queue_resize() forgetting allocation



On Sat, 2004-09-25 at 11:04 -0400, Stephen Bach wrote:
> For posterity:
> 
> I isolated the issue to the GtkViewport widget.  I found that if I packed the
> label/vbox into a GtkLayout and packed that into the GtkScrolledWindow,
> the size negotiations worked the way they should.  I don't know if the
> problem is caused by some function of the viewport that I don't understand,
> but I'm not going to spend any more time on it.  Using a layout works, though
> it requires a little more massaging.

The basic problem you are running into use that GtkViewport uses
GTK_RESIZE_QUEUE not GTK_RESIZE_PARENT for the container's 
'resize mode' (gtk_container_set_resize_mode()). Viewports are basically
treated independently of the toplevels in resizing, since the size of
the children of a viewport doesn't affect the size of the toplevel.

So, sequence of events is:

 gtk_widget_queue_resize(label) -
  sets ALLOC_NEEDED and REQUEST_NEEDED flags on label => viewport

                      ALLOC    REQUEST                     
    Window              
    ScrolledWindow
    Viewport            *         *
    VBox                *         *
    Label               *         *

 The idle sizer fires for the toplevel, gtk_window_move_resize() calls
 gtk_widget_size_request() on the Window, since REQUEST_NEEDED isn't
 set on the Window it doesn't propagate down, but just uses the cached
 size.

 gtk_window_move_resize() then calls size_allocate() at the new
 toplevel size, which propagates down the stack

                      ALLOC    REQUEST                     
    Window              
    ScrolledWindow
    Viewport                      *
    VBox                          *
    Label                         *
   
 The idle sizer fires for the viewport, which calls 
 gtk_widget_size_request() on the viewport, which propagates down the
 stack:

                      ALLOC    REQUEST                     
    Window              
    ScrolledWindow
    Viewport                      
    VBox                          
    Label                         

 gtk_widget_size_allocate() is then called, but since ALLOC_NEEDED
 isn't set, and the viewport is already at the right size, nothing
 happens.

I'm not *completely* sure this should be considered a GTK+ bug, since
what you are doing is fairly marginal. But there is a fairly easy
fix, which would be, in gtk_widget_size_allocate(), do:

   alloc_needed = GTK_WIDGET_ALLOC_NEEDED (widget);
-  GTK_PRIVATE_UNSET_FLAG (widget, GTK_ALLOC_NEEDED);
+  /* Preserve request/allocate ordering */
+  if (!GTK_WIDGET_REQUEST_NEEDED (widget))
+    GTK_PRIVATE_UNSET_FLAG (widget, GTK_ALLOC_NEEDED);

So, I'd actually appreciate it if you could file a bug in bugzilla
with your test case as an attachment and a link to this analysis
in the mail.gnome.org archives.

Two easy workarounds for your problem you might want to try:

 - Change the resize mode on the Viewport to PARENT after creating it.

 - Do your label_resize in a handler for 'size-allocate' on the
   toplevel rather than '::configure-event'.

I think either by itself should fix your problem; the second should
increase efficiency if the resizing is expense, but might also cause
double drawing.

Regards,
						Owen

Attachment: signature.asc
Description: This is a digitally signed message part



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