Re: Our size allocation issues



Michael Meeks <michael ximian com> writes:

> > For any GTK+ widget, showing the widget after the parent is 
> > visible will result in the widget first being mapped with a
> > bogus size (usually 1x1) and then moved to the new location
> > when the idle size pass hits.
> 
> 	Sure; and you typically position that window at -1,-1 so that it's
> invisible AFAIR.

It's very dependent on the widget. It just depends on what
happens to the widget when ::realize is called before ::size-allocate.
 	
> > The easiest, and best, way of getting around this is to
> > simply show your toplevels after all the widgets are in place;
> > doing anything else is going to result in some flashing.
> 
> 	Having the out of proc case, as easy to use as in-proc containment
> seems best in every way to me.

Yes, and for in-proc containment, you are hurting yourself
badly if you don't show your windows after everything inside
them is set up...
 
> > For GtkSocket, you can tell when a child has been added 
> > to the socket using the ::plug-added signal.
> 
> 	Well; I add the plug at socket realize time [ or when the control is
> bound if the socket is already realized ].

I guess I should be happy that things work when you change
the widget heirarchy in a ::realize handler, but it really
isn't a terribly good idea.

If I understand you, the reason why you are not getting
the right allocation on initial map is because GtkWindow::show
looks like:

 a) size_request the toplevel
 b) allocate the toplevel to the requested size 
 c) realize the toplevel
 d) map the toplevel

And the plug is being added at c). We may be able to fix some
aspects of the problems from adding the socket at this point
within GtkSocket, but we aren't going to be able to fix all of them.

 - We have to show _something_ where the plug appears until
   the correct size gets figured out.
 - If the requisition of the socket affects the size of the
   toplevel, then you'll see a size bounce
 
I *think* it is probably possible to generically fix changing
the size requisition at C.... I won't go into the details
right here, because that would make this mail too long, but
I think fixing it involves changing the relationship between
the "mini-copy of gtk_window_move_resize()" in gtk_window_show()
and the subsequent call to gtk_container_check_resize() which
will call the real gtk_window_move_resize().

> > But what you might want to look at instead is what happens
> > for *out-of-process* Plug/Socket combos.
> > 
> > If you look at gtk_socket_add_window(), then in the out-of-process
> > case, it *doesn't* immediately map the plug; instead it 
> > sets the need_map flag, and when a size_allocate() is received,
> > actually goes ahead and maps the child.
> 
> 	I imagine it's intended that we pass the Xid of a mapped widget into
> the socket - and it hides it's GdkWindow until the re-parenting sizing
> is all sorted - such that the plug is mapped and it's XEMBED_MAPPED,
> STATE_WITHDRAWN settings are set - although it is really un-mapped /
> mapped by the Socket at least initially.

I'm having a little trouble following the above, but it seems that
you are describing the way XEMBED works, yes. Do you mean by "intended"
that there is a mismatch between intention and reality? What would
that be?
 
> >  I don't see any reason
> > why we couldn't do the same thing in the in-process case.
> 
> 	I hacked something like this up; I hit the following problems:
> 
> 	*  _gtk_plug_add_to_socket does a gtk_widget_set_parent
> 	   which does a 'map' if the parent is mapped; pre-empting
> 	   the need_map handling in size_allocate.
>
> 	*  doing a gtk_widget_show (socket) propagates quickly
> 	   through socket realize to gtk_container_map on the socket
> 	   which again maps the widget; got around this with a 
> 	   gtk_socket_map handler that only maps if !need_map [
> 	   need_map starts to be a inadequate name, perhaps we want
> 	   delay_map_until_sized ]

Hmm, so, what you are doing is, for the in-process case, instead of
delaying mapping the plug window, delaying mapping the socket
window? 

I don't really like the asymmetry betweeen this and mapping the
socket window immediately and the plug window later for the
out-of-process case.

Delaying mapping the plug window could presumably be done from
gtk_plug_map() for the in-process case.
 
> 	Having done all of this, I have no flicker - at least in-proc

Probably just less flicker? Since the parent window of the socket
will show briefly before the socket window is mapped.

> I imagine the flicker will still be nasty out of process - at least it's
> not clear to me how the socket's gdk_window_move_resize on the plug's
> GdkWindow immediately before showing it will result in getting the out f
> proc child's sub-windows / widgets layed out nicely before they're
> mapped (?) but then perhaps that's handled by the normal mechanisms.

As I recall, the main point is so that the embedded client gets allocated
to the right size before it starts getting expose events. 

 
> 	Anyway; the patch looks like this, although I'd also like to kill the
> socket->same_app, since it's a synonym for socket->plug_widget != NULL;
> and it's only used once. 

Maybe you want to send a separate patch for that cleanup?

Thanks,
                                        Owen



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