On Tue, 2004-10-12 at 18:04 +0200, Tim Janik wrote: > that is, in the label's ::size-request handler tab_label_size_request_cb() > (at which point the label itself has already been size requested), the > testcase unconditionally sets the label's usize. that in turn queues a > new resize on the label. > however, due to the handling of the ::size-request signal inside > gtk, this request is later forgotten about (gtksizegroup.c): > > > g_signal_emit_by_name (widget, > > "size_request", > > &widget->requisition); > > > > GTK_PRIVATE_UNSET_FLAG (widget, GTK_REQUEST_NEEDED); How does this actually cause drawing to break? Is the problem that the requisition of the label is changing without a new call to gtk_label_size_request()? I don't see how that would matter, offhand. > basically, gtk doesn't support queueing new size requests from > ::size-request, and that's been that way for a looong time. > > [owen: FYI, applying my if (GTK_WIDGET_REQUEST_NEEDED (widget)) > gtk_widget_size_request (widget); fix from last week did indeed trigger an > endless resizing loop with the test case and without the set_usize() guards.] > > the bug at hand can fairly easily be circumvented in gtk by not queueing a > resize from set_usize() if the new usize doesn't actually change anything. > since this is a reasonable efficiency improvement to make anyway, Yeah, looks good. (Though not understanding the problem, I don't understand how it fixes it.) > i've > comitted the appropriate guards to gtk_widget_set_usize_internal(). it > doesn't fix the more fundamental problem of people wanting to adjust widget > sizes around size requisition time though. What's the use case? Generally, I'd expect the example to use: gtk_widget_set_size_request (label, label_width, -1); With *requisition.width = label_width; This won't actually work because it will break GtkLabel's alignment code, but you could introduce an intermediate container and get it to work. > ideally, the ::size-request signal would be RUN_LAST. it's not, > due to historic reasons though, and i'm afraid making it RUN_LAST > will significantly affect signal connections in exiting code: Yeah, I don't think we could do that compatibly. > 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. > > for the first three cases, it might actually make sense to add some magic to the > signal code, to issue a warning once per runtime, for !AFTER signal connections > to ::size-request. I'd like to get a clearer idea of what we are trying to support before commenting on the above. To some extent it would be nice to simply support calls to queue_resize() at any point. But really changing the size of a widget in response to size_request() is pretty odd. Regards, Owen
Attachment:
signature.asc
Description: This is a digitally signed message part