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