[comp.windows.x] ReParenting Widgets

Kimbrough@dsg.csc.ti.COM (Kerry Kimbrough) (08/11/88)

How does Xt manage to keep the widget hierarchy up-to-date with ReparentWindow
requests?  Quickly scanning the code, I can find that only Shell widgets select
StructureNotify. But what about widgets further down in the hierarchy? Nobody
seems to select for SubstructureNotify. Nor is there an XtReparent.

haynes@WSL.DEC.COM (08/11/88)

You can't reparent widgets unless you're a wizard. Even a wizard would
have to do a lot of research before trying it.

	-- Charles

Kimbrough@dsg.csc.ti.COM (Kerry Kimbrough) (08/11/88)

   > Date: Wed, 10 Aug 88 16:59:26 -0700
   > From: haynes@wsl.dec.com
   > Subject: Re: Reparenting widgets 
   > 
   > You can't reparent widgets unless you're a wizard. Even a wizard would
   > have to do a lot of research before trying it.
   > 
   > 	-- Charles

But what's the rationale? Is reparenting considered harmful or unnecessary?
Doesn't this close off a protocol feature to Xt users? 

Why couldn't there be a XtReparent function that would do this?  This assumes
that ReparentWindow requests on a widget only come from the client that created
it.  But for a non-top-level widget, this is quite reasonable, and for a
top-level widget, there's no parent widget to update anyway.

haynes@WSL.DEC.COM (08/11/88)

We actually wanted really badly to allow repartenting of widgets, but
just couldn't work out all the semantics in a way that satisfied us. We
were particularly worried about reparenting widgets before they were
realized, and reparenting composite widgets. I still believe it's
possible to "safely" repartent a widget, but no one has ever taken the
time to figure all of what's involved. If you're interested, I heartily
encourage you to do the work and figure out what it would take to
implement an XtReparent function.

I would suggest restricting the Reparent to only the client that
created the widget, and requiring the client to use XtReparent to do
the work. Otherwise you end up with StructureNotify on all of your
windows which causes an absolutely horrendous amount of unwanted
information to be delivered to your application.

One fairly simple "hack" way to do a reparent is to destroy the widget
in its old position, remembering the values of its resources (read the
resource list, then do a get values, then destroy it) then re-create it
in the new place passing in all of the resources in the arg list. This
isn't exacly the same as a reparent, but may be good enough.

	-- Charles

klee%daisy%sgi@BLOOM-BEACON.MIT.EDU (Ken Lee) (08/24/88)

We have a large application written in raw Xlib (X11R2).  We would like
to use some X Toolkit widgets as sub-windows of the application (using
explicit dispatching for event handling).  The immediate problem is
that XtInitialize creates the shell widget window as a child of the root
window.  Is there any easy way to create the shell widget as a child of
another (given) window?  If not, are there any problems with using
XReparentWindow on the shell widget's window?  Thanks much for your help.

Ken Lee
Daisy Systems Corp.
--
uucp:  {ames!atari, ucbvax!imagen, nsc, pyramid, uunet}!daisy!klee
arpanet:  atari!daisy!klee@ames.arc.nasa.gov

Don't applaud, just throw money.

swick@ATHENA.MIT.EDU (Ralph R. Swick) (08/24/88)

> are there any problems with using
> XReparentWindow on the shell widget's window?

In principle, no; many window managers do it all the time.  In practice,
for what you are trying to do, I'll make no guarantees.  You will be
better-off creating a new composite widget class to do what you want,
and ignoring the ShellWidget returned by XtInitialize.

ray@COD.NOSC.MIL (William J. Ray) (11/30/88)

     I have a question concerning widgets.  I am running X.V11R3 on
a Sun 4/260 with Sun OS 3.2, but am using Release 2 of the toolkit
to take advantage of the HP widgets.

     I was wondering how to reparent a widget.  I have two processes
running, call them a and b.  both a and b are using widgets and both
call XtInitialize.  Process b maintains a complex graphics image
in a widget which I have written.  Process a sends messages over
a socket to b to tell it how to manipulate the image.  Both come
up in their own window, and each has its own title bar (under twm).

    What I would like to do is reparent the toplevel widget in b,
so that its parent is now a widget in process a.  This way, both
widget sets will be under the same window, and be managed as a
single window by the wm.  I know that this is possible with
windows. (Apparently this is how twm places title bars and
such)  But is this possible with widgets, and if so how would
I go about doing such a thing.

     One more question that is unrelated.  How do you set the
initial position of the scroll bar in the HP or Athena widgets.
I am using the HP scrollbar widget to scroll an image.   I would
like the scroll bar to come up with the slider in the middle
instead of at the left side.


Thanks in advance,

I am not on the expert mailing list, so please send any repsponses
to me at:

    ray@nosc.mil

rws@EXPO.LCS.MIT.EDU (Bob Scheifler) (12/07/88)

The intrinsics currently do not provide any support for
reparenting widgets.

meo@stiatl.UUCP (Miles O'Neal) (12/14/88)

While I realize the XToolkit does not really support reparenting
widgets, I wonder if anyone out there has developed ant tools to
do just that under Xt.

If not, can anyone give me a quick primer on doing this?

Thanks,
Miles (gatech!stiatl!meo)

asente@decwrl.dec.com (Paul Asente) (12/17/88)

Although the toolkit supplies no support for reparenting widgets, I have
successfully written a widget that reparents a window -- if that is any
help.

The basic idea was to add a resource that is the window to be reparented,
and, in the Realize procedure, install this window in the core.window
field of the widget and issue an XReparentWindow call.

	-paul asente
	    asente@decwrl.dec.com	decwrl!asente

mpatnode@polyslo.CalPoly.EDU (Dodger) (06/08/89)

In article <8906070106.AA18157@expo.lcs.mit.edu> ISSLCK@NUSVM.BITNET (Law Chee Keong) writes:
>Hi!
Hello

>There seems to be no easy way of doing this short of making a copy of the
>widget, then using XtDestroyWidget to remove it from its parent, then adding
>the copy of the widget to the new parent. 

Yup that's it.  I was working on this for a while and this method is
virtually impossible unless you happen to be keeping track of all the
widgets attributes via a widget independent method. (which we were) If
you try to copy attributes from a widget to another (which I did), you
will discover a plithera of bugs and inconsistencies in the XtGetValues() 
implementations of different widget classes.  I did find performace
to be acceptable for the Destroy-Create method, even with child-bearing
composite widgets. The trick is to realize all the children before mapping
the parent. 

A Copy ability would be very nice if it was intrinsic to the widgets.  It
turns out to be a big sore spot which says "I'm not a object-oriented as
I pretend to be."  I think this problem lies in the C language itself
and current solutions have been stretched to the limit.

BUT, I'm not about to switch to Interviews quite yet...

Any hope of a XtCopyWidget() in a future release?

----------

-- 
Mike "Dodger" Patnode          |      mike@cosmos.ACS.CalPoly.EDU
Yitbos Innovations Inc.        | 		or
244 California Blvd            |     mpatnode@polyslo.CalPoly.EDU
San Luis Obispo, Ca  92630     | (805) 541-2048 / 543-9818 / 756-2516

joe@athena.mit.edu (Joseph C Wang) (07/02/89)

I'm helping to develop an application that requires widgets to be reparented.

Is there a better way than to do it with the following code?  Is anyone
thinking about adding an XtReparentWidget call in the next release of
X toolkit?

Longish code follows.

-----------

void XtReparentWidget(widget, new_parent, x, y)
     Widget widget, new_parent;
     Position x, y;
{
if (!XtIsComposite(new_parent)) return;

if (XtParent(widget) == new_parent) return;

XtUnmanageChild(widget);

(*( ((CompositeWidgetClass)
     XtClass(XtParent(widget)))->composite_class.delete_child)) (widget);

widget->core.x = x;
widget->core.y = y;
widget->core.parent = new_parent;

if (XtWindow(new_parent) && XtWindow(widget))
     XReparentWindow(XtDisplay(widget), XtWindow(widget), XtWindow(new_parent),
                (int) x, (int) y);

(*( ((CompositeWidgetClass)
     XtClass(new_parent))->composite_class.insert_child)) (widget);

XtManageChild(widget);
}

--------------------------------
Joseph Wang (joe@athena.mit.edu) 
450 Memorial Drive C-111
Cambridge, MA 02139

kit@EXPO.LCS.MIT.EDU (Chris D. Peterson) (07/06/89)

Reparenting widgets is not supported withing the toolkit.  By the time you 
produce all the correct semantics there is little or no advantage to
reparenting a widget over destroying it and creating a new one.  The
major problem that you will run into when reparenting widgets is that
the resource specifications for a widget are dependant upon its
position in the widget hierarchy, and when you reparent a widget it is
necessary to reload all of its resources and completely reinitialize
it.  This process is really 99% if what it takes to create a
new widget.  The situation becomes even more complex when the widget
has children, as you must reinitialize all of the children also. 
Because of these problems it was not considered useful or worthwile to
support reparenting widgets.  

> Is anyone thinking about adding an XtReparentWidget call in the next release
> of X toolkit?

Nope, for the reasons stated above.

						Chris D. Peterson     
						MIT X Consortium 

Net:	 kit@expo.lcs.mit.edu
Phone:   (617) 253 - 9608	
Address: MIT - Room NE43-213

mike@cosmos.acs.calpoly.edu (Mike L Patnode) (07/06/89)

kit@EXPO.LCS.MIT.EDU (Chris D. Peterson) writes:
>
The pains of reparenting widgets deleted....
>
>> Is anyone thinking about adding an XtReparentWidget call in the next release
>> of X toolkit?
>
>Nope, for the reasons stated above.

O.K. then, how about a XtCopyWidget() ?  This would simply the operation
greatly for those who are trying to do it, as well as reparenting.

IE:

Widget XtReparentWidget(widget, new_parent, x, y)
    Widget widget, new_parent;
    Position x, y;
    {
    Widget newwidget;

    newwidget=XtCopyWidget(widget, new_parent, x, y);

    XtDestroyWidget(widget);

    return newwidget;
    }

Mike "Dodger" Patnode          |      mike@cosmos.ACS.CalPoly.EDU
Yitbos Innovations Inc.        | 		or
244 California Blvd            |     mpatnode@polyslo.CalPoly.EDU
San Luis Obispo, Ca  92630     | (805) 541-2048 / 543-9818 / 756-2516

kit@EXPO.LCS.MIT.EDU (Chris D. Peterson) (07/06/89)

> O.K. then, how about a XtCopyWidget() ?  This would simply (sic) the operation
> greatly for those who are trying to do it, as well as reparenting.

I remain unconvinced.  Since this will probabally be slower than creating
a new widget, why is it useful?  You should already have a routine
lying around your application that creates this widget, I don't see
any advantage of XCopyWidget() over just calling that piece of application 
code again to recreate the widget.  

						Chris D. Peterson     
						MIT X Consortium 

Net:	 kit@expo.lcs.mit.edu
Phone:   (617) 253 - 9608	
Address: MIT - Room NE43-213

mike@COSMOS.ACS.CALPOLY.EDU (Mike L Patnode) (07/07/89)

> O.K. then, how about a XtCopyWidget() ?  This would simpilfy the operation
> greatly for those who are trying to do it, as well as reparenting.

>>I remain unconvinced.  Since this will probabally be slower than creating
>>a new widget, why is it useful?  You should already have a routine
>>lying around your application that creates this widget, I don't see
>>any advantage of XCopyWidget() over just calling that piece of application 
					   ^^^^^^^^^^^^^^^^^
>>code again to recreate the widget.  

I think I'm beginning to realize the difference in my philosophy.  Everyone
else considers most widgets a static object in the program.  Since I'm
working on a application generator, a widget to me is an object which
could be any size, type, or color; have any label or pixmap inside of
it; a variety of callbacks and event handlers; as well as extra
information.   The routines which created the widget and changed its
attributes were called in some dynamic order choosen by the user. 

Hence when I want to call XtCopyWidget() it's because all I have is a
widget identifier and I want to copy/move it somewhere else.  My current
solution is a hash table of widgets which also point to a separate attributes
list.  Whenever I want to copy a widget, I run though the information in
the attributes list, converting it to the appropiate types, build a Args
list and recreate the widget.  Yuk!  This is what I would expect
XtCopyWidget to do for me.

Now the problem with using the widget's own argslist is that XtGetValues 
doesn't always work. (try to get the foreground color of a text widget,
it took me quite a while to find out where the text went on my copied
widgets)  Hence, XtCopyWidget would have to use a different method, or
else all widgets would have to guarrentee their values. 

I certainly don't see the routine being easy to write but your right in
thinking "If you created it once, why not just destroy it and create it
again?"  which is what we do, it's just a p.i.t.a.

B.T.W: I never lost the text in the text widget, I just couldn't see it!

thp@WESTHAWK.UUCP (07/07/89)

> Mike L Patnode <mike@edu.calpoly.acs.cosmos> said:
> I think I'm beginning to realize the difference in my philosophy.  Everyone
> else considers most widgets a static object in the program.

I agree, could widget implementors please remember that their widgets may be
created/destroyed/changed interactively, possibly many times.

> Whenever I want to copy a widget, I run though the information in
> the attributes list, converting it to the appropiate types, build a Args
> list and recreate the widget.  Yuk!  This is what I would expect
> XtCopyWidget to do for me.
> Now the problem with using the widget's own argslist is that XtGetValues
> doesn't always work.

Well, if you want to "save" the results of an interaction with a widget,
(for inclusion in the "real" application, or to restore the display next time
the program is run) then you _have_ to be able to recreate the widget one
way or another. So unless XtCopyWidget() was much cheaper than the recreation
(and kit@expo.lcs.mit.edu expects it not to be) you might as well use the same
recreation method as the copy method too.

+----------------------------------------------------------------------------+
|Tim Panton, Westhawk Ltd.                                                   |
|Paper: Westhawk Ltd. 26 Rydal Grove, Helsby, Cheshire, WA6 OET. UK.         |
|Phone: +44 92822574             uucp : ..!mcvax!ukc!cam-cl!westhawk!thp     |
+----------------------------------------------------------------------------+

jdb26@chemabs.UUCP (10/19/90)

Has anyone figured out how to reparent widgets?  I know this is not
supported directly in Xt, but I was wondering if anyone has a workaround.
I would like to reuse some widgets by putting them on an 'orphan' list
until they are needed again.  Unmapping/remapping tricks won't work
in this case.  Thanks!!!!!

Jeff Bailey                        |  All opinions are my own and do not
Chemical Abstracts Service         |  necessarily reflect those of my
Columbus, OH 43221                 |  employer.
(614) 447-3600 (x3092)             |
                                   |
BITNET: jdb26@cas.bitnet           |
UUCP:   osu-cis!chemabs!jdb26      |

ben@hpcvlx.cv.hp.com (Benjamin Ellsworth) (10/23/90)

For now (could break anytime), the general solution requires at least
the following, in no particular order:

	- Remove the child from the previous parent's child list; the
	  delete child method ought to work.
	
	- Insert the child in the new parent; the insert method should do
	  it.
	
	- Make sure that the child's parent fiels points to the correct
	  parent.
	
	- Handle the constraint records.

This last is perhaps the most difficult.  You should run the constraint
destroy processing, then the constraint initialize processing.

Doing all of these things in a correct sequence constitutes the general
work-around.  Are you sure that you want to do this?

-----------------------------------------------------------------------
Benjamin Ellsworth      | ben@cv.hp.com                | INTERNET
Hewlett-Packard Company | {backbone}!hplabs!hp-pcd!ben | UUCP
1000 N.E. Circle        | (USA) (503) 750-4980         | FAX
Corvallis, OR 97330     | (USA) (503) 757-2000         | VOICE
-----------------------------------------------------------------------
                     All relevant disclaimers apply.
-----------------------------------------------------------------------

garnaat@verdelak.xerox.com (Mitch Garnaat) (03/26/91)

Is there any safe way to reparent a widget?
I think not, but I'm hoping to be pleasantly surprised.
 
Thank,
	(mitch)
----------------------------------------------------------------
Mitch Garnaat					Xerox Corp.
garnaat@arisia.xerox.com			(716)427-6260

spock.uucp (Spock) (05/25/91)

Hi,

  Can anyone tell me how I might reparent a widget (not window)?

  I don't care how sleazy or non-portable the answer is, I would
  like to hear from you if you have an idea.

Thanks

spock@bigsur.uucp