Re: Size allocation and redrawing issues



Owen Taylor <otaylor redhat com> writes:

> Could you please review the following: it describes some things I'd
> like to improve with allocation and redrawing, gives a list of
> "invariants" that I think we need to maintain, and proposes a few
> changes to the way we do allocation and redrawing.

What I would do for size negotiation is

	- add two private flags, GTK_HAS_ALLOCATION and
          GTK_HAS_REQUISITION, meaning that the values in
          widget->allocation and widget->requisition are correct.

	- queue_resize redraws the widget non-propagatingly and clears
          the flags HAS_ALLOCATION and HAS_REQUISITION all the way
          from the widget to the toplevel inclusive. Then it sets the
          flag RESIZE_PENDING on the toplevel widget and installs an
          idle handler that will size_allocate the toplevel widget.

	- size_allocate and size_request do not emit their signals if
          the HAS_REQUISITION and HAS_ALLOCATION are set. If the
          signals are emitted, the flags are set.

This would mean that a queue_resize would result in a complete
size-renegotiation of the widget-tree, but the HAS_* flags mean that
only widgets that must actually change have the signals emitted on
them.

This is much simpler than the current system. A lot of code could be
deleted from gtkcontainer.c and also some from gtkwindow.c, because
the resizing invariants would be much simpler to maintain. This system
also completely ignores the resize_mode on containers, but resize_mode
is not of much use anyway, and the caching of requisitions and
allocations should make it completely unnecessary.

This system is probably somewhat more work to code and debug, and it
involves depreceating gtk_container_resize_mode.

I would also make the same invalidation/redrawing changes that you
suggest. Especially the redraw_on_allocate flag should make me and the
Matrox happy.

> There are essentially  issues that I'd like to address:
>  
>  * We need to get rid of hysteresis. This is the phenomena where
>    if a widget's requisitions shrinks, it won't be allocated
>    smaller, until something happens to cause gtk_widget_size_allocate()
>    on the toplevel.

My suggestion would take of this by ensuring that all widgets whose
requisitions change are reallocated.

>  * If you call gtk_widget_queue_resize() on a widget, that must result
>    in:
>   
>     - a call to gtk_widget_size_request() on the widget
>     - a call to gtk_widget_size_allocate() on the widget
>     - the widget being redrawn
>   
>    Currently, all three of these will propagate to descendents
>    of the widget, but I don't think there is actually any real
>    requirement that the second two propagate (except as required
>    by changing allocations, and propagation of exposes to NO_WINDOW
>    children.)

In my suggestion, gtk_widget_size_request() doesn't propagate into a
subtree if that tree doesn't contain a widget that had
gtk_widget_queue_resize() called on it. Is it necessary for
size_request() to propagate always?

Søren



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