Re: changing usize in ::size-request (bug #155139)
- From: Tim Janik <timj gtk org>
- To: Owen Taylor <otaylor redhat com>
- Cc: Gtk+ Developers <gtk-devel-list gnome org>
- Subject: Re: changing usize in ::size-request (bug #155139)
- Date: Tue, 12 Oct 2004 22:15:22 +0200 (CEST)
On Tue, 12 Oct 2004, Owen Taylor wrote:
On Tue, 2004-10-12 at 19:39 +0200, Tim Janik wrote:
so in order to deal with widget size adjustments around ::size-request time,
i see these possibilities:
1) make ::size-request a RUN_LAST signal as it ought to be. this should only
be done, when people are willing to put some work into porting their
applications to a new gtk+ version anyway, e.g. around gtk+-3.0.
2) introduce a ::custom-size or similar signal that is emitted directly
before ::size-request, and can be used by users to setup resizing handler
connections like the above (tab_label_size_request_cb, example_size_request_handler).
3) preserve the current state of affairs, where size adjustments that queue
a new resize during ::size-request are simply not supported.
4) make ::size-request a NO_RECURSE signal, and introduce a new private flag for
widgets (or similar mechanism like a private in-request widget list), which
can be used to detect queueing resizes during emission of ::size-request.
in that case, gtk_widget_queue_resize() could simply emit_by_name (widget,
"size-request"); which will cause a the current emission of ::size-request
to be restarted after the user handler queueing a resize returned.
that is, make ::size-request deal with recursive resize requests the way we
handle GtkAdjustment::value-changed.
this may still be incompatible with some existing user code setups, but
hopefully less so than simply making ::size-request RUN_LAST and as a
consequence, the caveats from (1) about applying this around a 3.0 change
only probably apply here as well.
let me add:
5) change gtk_widget_size_allocate() to re-queue a resize if GTK_REQUEST_NEEDED
remains set upon function exit. this keeps the invariant of ::size-request
having to follow every queue_resize (for DRAWABLE widgets).
this may trigger endless resizing loops, but only if users unconditionally
cause queue_resize from ::size-request signal handlers, in which case it
can be argued they get what they deserve (requested). note that the testcase
from #155139 is such a scenrio though. it only happens to work with
recent CVS because i made set_usize() queue a resize conditionally.
Silly question - doesn't it fix everything if we simply just move
unsetting the GTK_REQUEST_NEEDED flag before we emit ::size-request?
Of the invariants I outlined earlier, the one that is broken is
"REQUEST_NEEDED on child implies REQUEST_NEEDED on parent.
When we emit ::size-request on the widget, one two things can happen:
- Either no descendant calls gtk_widget_queue_resize(), in which case
REQUEST_NEEDED will be unset on all children
- Or a descendant calls gtk_widget_queue_resize() in which case the
REQUEST_NEEDED flag will be set again on the widget.
GTK_RESIZE_IMMEDIATE.
i don't think things will continue to work as smoothly, if one of your
resize containers is an immediate resize container and you queue a resize
from within ::size-request of one of its children.
so some of my suggestions (esp. (4)) tried to implement proper recursion
handling from within ::size-request.
come to think of it, i'm now pretty sure gtksizegroup.c implicitely depends
on asyncronous resizes as well though.
mundane cases can easily be constructed where such circular scenarios either:
- loop endlessly due to ping-pong size requests (the lable<->window dependancy might
request alternating sizes like: 4,5,4,5,4,5,4,5), or
- get into a feedback loop (with size requests: 8,...,256,...,65536,...)
and due to float-round-off, font-sizes, theme settings, etc. these pathologic cases
might not even always be triggered.
if we want to completely prevent such scenarios, i might even add:
(6) explicitely catch queue_resize() during ::size-request emissions by a mechanism
similar to that suggested in (4), and issue a warning.
i think we should stop to look for more use cases for queue_resize() from ::size-request
though. experience shows that code is usually used in unintended or not planned for
ways, so we should rather make a general decision on how to deal with recursive resize
requests, than to focus on getting arbitrary cases to work and ignore others.
I think we should give people the rope ... yes, calling queue_resize()
out of ::size-request or ::size-allocate can easily trigger loops, but
especially when the entire window content is known, it can be safe and
useful in cases... you can use it to emulate height-for-width for a
widget, for example.
ok, for 2.6, i'd sugegst we then do:
- unsetting the GTK_REQUEST_NEEDED flag before we emit ::size-request, as you suggest
- deprecate GTK_RESIZE_IMMEDIATE and internally treat it as GTK_RESIZE_QUEUE
(if somebody would really wanted to shoot himself into the foot with immediate
resizing, he can still call gtk_container_check_resize() himself)
- leave the
s/while (!GTK_WIDGET_ALLOC_NEEDED (widget) ||
!GTK_WIDGET_REQUEST_NEEDED (widget))/while (TRUE)/
change from 2.4 in place. while it shouldn't strictly be neccessary, the
checks aren't strictly necessary either and simply "set ALLOC_NEEDED and
REQUEST_NEEDED up to the resize_container" is easier to read and understand.
Regards,
Owen
---
ciaoTJ
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]