On Sun, 2005-07-03 at 09:23 -0400, muppet wrote:
On Jul 2, 2005, at 9:28 PM, Carl Nygard wrote:On Sat, 2005-07-02 at 10:00 -0400, muppet wrote:At this point, i think you need to post code, because the descriptions don't match up with what should be happening, and the possibilities of what you might be doing differently than expected are too numerous.Unfortunately, it's not really possible/practical to post code, since the main app is a C++/Zaf/OpenMotif/Gdk::Pixbuf happy bastardization of an app that's running an embedded perl interpreter to provide script facilities.Er, sorry, i forgot you'd said it was embedded. Does your embedded interpreter persist, or do you create a new interpreter for each script? Is the interpreter in the main process or do you launch a child process for the interpreter? The gtk2-perl bindings don't unregister their types from glib at shutdown, so you may have bizarre problems with new in-process interpreters.
The embedded interpreter persists, in the main process, no forks/threads. Each script basically defines a function called 'MEL', and there is a loader for the script file which essentially calls 'do $file' to load and parse the file, then calls the MEL() function to run the script, which typically returns an XML block which the app then interprets and acts upon. One question, is it bad to be calling 'use Gtk2 -init' every time I try to pop up a Dialog?
What I do know is that it has nothing to do with GladeXML, since I rewrote the Dialog wrapper to generate the Gtk::Dialog on the fly from scratch, and it exhibits the same problem. And I know the dialog is getting destroy'd after every embedded script run...I just noticed that in an earlier post you said you were overriding DESTROY to call ->destroy on the window... are you overriding DESTROY on a Glib::Object derivative? (E.g., the GladeXML object?) Glib::Object::DESTROY is one of those special "never override this, and if you do, do not fail to chain up" methods. This is where lives the magic that breaks the association between the C GObject and the perl wrapper. If DESTROY doesn't run properly, the object could be kept artificially alive in a zombie state, and would likely keep all its children alive, as well. Another possibility, which seems likely since you said there are multiple toolkits in the app, is that you're not letting the glib main loop run after the call to $window->destroy, and the destruction can't finalize itself (e.g., remove the X window from the screen).
Ok, tried that, still didn't work. I run the Gtk2 main loop before and after I show/hide the dialog, so shouldn't deferred activity get done there anyway?
My current guess revolves around the possibility that Gtk::Dialog-new()does something special to finagle a parent widget,Well, no, it doesn't. Unless you specifically tell a GtkDialog what parent window to use, it considers the root window to be its parent.and that parent widget doesn't have anything to do with the app parent widget (which would be Xlib/Motif window).You'll have to set the parent explicitly. With glade, that would be $glade->get_widget ('the-window')->set_transient_for ($parent); and when creating the dialog by hand, you can pass $parent to the full constructor. Since your app is a mixed bag, you will have to do extra work to get the parent. gtk_window_set_transient_for() wants a GtkWindow, but if your parent window is a motif or Xlib window, you don't have a GtkWidget for it. If you can get the XID of the window, you can use a gdk call, $gdkwindow = Gtk2::Gdk::Window->foreign_new ($xid), to get a GdkWindow for that XID. Then, you can call $dialog->window->set_transient_for ($foreign_gdkwindow); after $dialog is realized.
Ugh. Well, I could probably pass the XID to the MEL() script function and let it do the magic Gdk stuff, that's not a big deal. Hopefully I don't have to mess with XS. But thanks, this is exactly what I needed to know for my next experiment.
As for how to get the XID... if you're embedding the interpreter, you can write some XS. Don't forget that you can hide some of this stuff in XS by using Glib and Gtk2's extension support.So the window manager gets confused about what constitutes "front". Although I have to wonder, if the window manager thinks its in front after the $window->present() function call, why does it blink the panel-icon-button-thingy to show that the window is hidden?This part of the interaction is something on which i can't really comment without something on which to experiment.
Well, you're already the most helpful open source developer I've ever run across, so thanks for what you've already suggested. Here's the Dialog.pm class which provides a simple interface for popping up and populating dialog boxes. The MEL() script would create a Dialog, run it, then deal with the results from the user. Some explanation, you probably only need to deal with Create() and DESTROY(). Most of the other stuff is either cruft from the Glade methods, or infrastructure for a derivation framework that makes the Perl modules seem like C++ objects (i.e. ctor, copy-ctor, operator=, MI, etc) Thanks, Carl
Attachment:
Dialog.pm
Description: Perl program