bbfu has asked for the wisdom of the Perl Monks concerning the following question:

I was wondering if anyone could point me towards any info on displaying another process as a child/sub window of my Perl/Tk application; ie, as if it were a child widget.

I'm interested in having the positioning, geometery, visibility-state, and focus tied to my window. Having bindings and events passed through (if appropriate, of course) would be nice, as well, but I can do that manually via direct calls to the window manager (Sawfish), if need be. Heck, I could probably do all of it via direct calls to the window manager but I'd like to know if Tk has an easier or more straight-forward way to do it.

I appreciate any info, even if it's negative (ie, it can't be done). TIA! :-)

bbfu
Seasons don't fear The Reaper.
Nor do the wind, the sun, and the rain.
We can be like they are.

Replies are listed 'Best First'.
Re: Tk and processes as child/sub windows
by mugwumpjism (Hermit) on Nov 19, 2001 at 14:27 UTC

    I think what you want to do is to "swallow" the other application's window, or something close to that. Many window managers, and the gnome-panel, for instance, do this to capture programs like xbiff & contain them within a smaller window.

    I don't know how this is done, but I do know that your application first needs to find the window ID of the application to be swallowed, by traversing the list of top level windows in the X server and finding the one you're after (usually by checking the X window name, class, resource, etc).

    It may be instructive to have a look at the "FvwmIdent" and "FvwmButtonBar" modules in fvwm, to see how this is done at an X toolkit level.

Re: Tk and processes as child/sub windows
by {NULE} (Hermit) on Nov 19, 2001 at 20:09 UTC
    Hi,

    I'm not 100% sure that I get the gist of your question, but I'm giving it a shot anyway. First thing I would check if I were you is to read the documentation for Tk::Toplevel. It has an option for "-container" which, if set true "means that this window will be used as a container in which some other application will be embedded". I have not used it myself, but this seems like it might get you pointed in the right direction.

    The other way I could read this, and it probably isn't what you mean - that you want to fork your Tk process and have the children render as sub windows of the parent. I think you could do this as well, if you played with it. I would try forking after creating your main widget and see what happens when you create dependent windows. Just don't go back and try to modify the parent, since you'd be going after copy!

    Good luck,
    {NULE}
    --
    http://www.nule.org

      To answer your unasked question, I want to create a Perl/Tk application with a window that has another, non-Perl/Tk program (VGB linux, to be exact) embedded within it. I apologize if I was not clear enough in my original question. :/

      The -container option is exactly what I was looking for... Now I just need to figure out how to open an application as a contained window. Tk::Toplevel has a -use option that makes the Toplevel contained but I can't find any mention of how to start a totally seperate program and have it be contained.

      Don't suppose you have any suggestions on where I might find more information?

      At any rate, thanks for the start!

      bbfu
      Seasons don't fear The Reaper.
      Nor do the wind, the sun, and the rain.
      We can be like they are.

        Hi,

        As we kind of figured out before Tk::Toplevel and Tk::Frame both accept -container => 1 as an option. The trick is getting another application to accept that window as it's parent.

        You can get the window manager's id for this window very simply. If we had created a frame that we want to work as a container we could say the following:

        my $frame = $main->Frame( -container => 1, -width => 320, -height => 240 )->pack( -side => 'top', -fill => 'both', -expand => 1 );
        We can get the window manager's ID with the id method:
        my $frameID = $frame->id; print "My ID is: $frameID\n";
        If you check the docs for Tk::Widget you see that the id method returns "a hexadecimal string giving a low-level platform-specific identifier"... on UNIX it returns "the X window identifier", on Win "the Windows HWND". The key now is to get another app to accept this ID as its parent.

        This seems like it would be something available in a uniform fashion to any application built on the X Toolkit. I could not find any way to specify a parent using the "standard options" of the toolkit. I also tried using the X Resource Management features of the toolkit to see if such an option was available there. I had no luck persuing these.

        Another thing I did was to delve a bit into some sample X Toolkit code. There seems to be a point in the application where you can specify a parent ID. If my reading is correct the question is - does the toolkit offer a standard way to specify this? (I would think so because it seems the window manager would be the parent of any newly created application.) If not, how would you build an application to accept this value and use the parent provided.

        There is an example (albeit in Tcl/Tk) on the web: http://www.xmission.com/~georgeps/multimedia.html that uses xanim. xanim explicitly accepts a parent id using the +W command line argument. Doing the same kind of thing in Perl::Tk looks like this:

        #! /usr/local/bin/perl -w use strict; use Tk; my $main = MainWindow->new( -title => 'Container Test' ); my $frame1 = $main->Frame->pack( -side => 'top', -fill => 'x' ); my $frame2 = $main->Frame( -container => 1, -width => 320, -height => 240 )->pack( -side => 'top', -fill => 'both', -expand => 1 ); my $frame3 = $main->Frame->pack( -side => 'top', -fill => 'x' ); $frame1->Button(-text => 'xanim', -command => [ \&open_xterm, $frame2 +])->pack; $frame1->Button(-text => 'Quit', -command => \&exit)->pack; $frame1->Label(-text => "This is above the container frame")->pack; $frame3->Label(-text => "This is below the container frame")->pack; MainLoop; exit; sub open_xterm { my $frame = shift; my $display = "xanim -Zr +W".$frame->id." /space/litherm/TheDamian +.gif &"; print $display,"\n"; system($display); }

        Thanks to TheDamian for use of his gif in testing. :)

        I hope this helps you. Good luck,
        {NULE}
        --
        http://www.nule.org