From: Jim I. <ji...@ap...> - 2001-12-06 22:40:25
|
> All: > > I have been doing some tinkering trying to get Jeff's new Tcl and Tk for > Mac OS X to work with Ruby. I thought I'd share some thoughts about what > I've think I've found so far in case it's of some help to those trying > to get Tk to work with other scripting languages. Jeff? > > As background, I initially wrote directly to Jim a few days back saying > I tried to run a Ruby script that used Tk and nothing showed up. He > suggested I verify that DoActualWait was getting called to listen for > events. You should also knno that while I've been learning Ruby, I'm no > expert. Also, this is my first time looking at Tcl/Tk internals. Please > take the suggestions below as such and feel free to correct any > misunderstandings I might have. > > When I first began to try to debug the problem, I noticed something odd. > When I ran Ruby under gdb a Tk-window appeared with the two buttons that > it's supposed to have. However, I couldn't do anything with it (like > make it key, or close it). But, when run from the command-line without > gdb the window doesn't show up at all. So, from there, I began to try to > track down why DoActualWait() wasn't getting called... > > SUGGESTED CHANGE TO tkMacOSXInit.c:TkpInit() > When a Ruby script that uses Tk starts up, it calls the following Tcl/Tk > functions to get started: > Tcl_FindExecutable > Tcl_CreateInterp > Tcl_Init > Tk_Init > What I noticed is that there are some very important looking functions > that only get called from tkMacOSXAppInit.c:main() or > tkMacOSXAppInit.c:Tcl_AppInit(). Specifically, they are > tk_MacOSXSetupTkNotifier(), TkMacOSXInitAppleEvents(interp), and > TkMacOSXInitMenus(interp). > > I would suggest that these three functions need to be called from > TkpInit() which is the platform specific code called from Tk_Init. No, this won't work. Tk_Init gets called for each interpreter that loads Tk (note for instance that tkConsole.c calls this as well as the Tcl_AppInit). But the menu init & apple events init, and the setup notifier, are only done once per app. I guess we could change these functions to be idempotent, but since they really are for application initialization and not Tk initialization specific things, this seems wrong to me. > > SUGGESTED CHANGE TO tkMacOSXNotify.c:tk_MacOSXSetupTkNotifier() > When I first added tkMacOSXNotify to TkpInit() it didn't do anything. > After some more code reading, I found this comment in > tkMacOSXAppInit.c:main() that made that not so surprising: > <code_snippet> > /* > * NB - You have to swap in the Tk Notifier BEFORE you start up the > * Tcl interpreter for now. It probably should work to do this > * in the other order, but for now it doesn't seem to. > */ > </code_snippet> > > I would like to suggest that we add one line to the end of > tk_MacOSXSetupTKNotifier() that reads: > TclInitNotifier(); > It seems that by calling Tcl_SetNotifier, we update the pointers in > tcl_stubs, but it doesn't seem to be sufficient because the > ThreadSpecificData, tsdPtr, keeps a pointer to the tcl_InitNotifier that > won't be updated unless we call TclInitNotifier. Furthermore, this > guarantees that TkMacOSXInitNotifier() gets called. And, if you look at > the source for tclNotify.c:TclInitNotifier() it becomes very clear why > it was working iff we swapped in the notifier before the interpreter is > created. Let me play with this a bit. If it removes the hacky ordering problem, that would be great. > > SO WHERE DOES THAT LEAVE ME ? > Well, acutally, not much better off :-( I can now guarantee that my > event loop is running which is a Good Thing (TM). However, I still only > see the window appear when I run under gdb. And when I click on the > window I get a new message about SetFrontProcess failing with an error > code of "-600". > > I'm not familiar with Carbon's idea of processes and how to control, it > but after reading the error message for "-600", I decided to try and > call GetProcessInformation to find out more about the running process in > hopes of finding out why I get different behavior in GDB and outside of > GDB. > > When I run outside of GDB, the process has the following properties: > LAUNCH DONT SWITCH > DESK ACCESSORY > MULTI LAUNCH > NEED SUSPEND RESUME > CAN BACKGROUND > DOES ACTIVATE ON FG SWITCH > GET FRONT CLICKS > LOCAL AND REMOTE HL EVENTS > STATIONERY AWARE > > When I run inside of GDB, the process has these very different > properties: > ONLY BACKGROUND > 32 BIT COMPATIBLE > HIGH LEVEL EVENT AWARE > > The "ONLY BACKGROUND" bit being set while running under GDB explains why > it won't let the window be set to the front. However, I don't understand: > a) why don't I get windows when running outside of GDB > b) how can I control what these attributes are ? Are there Carbon > functions to declare what I want them to be ? > > Thanks in advance for any thoughts or help in figuring out what to > tinker with next. How are you building this? The easiest way to get all this right is to use PB, and its Carbon Application template. Short of that, set PB to issue detailed build logs (in the Build preference pane) and then build Wish, and see what it does, and just copy that in your Makefile. Jim -- ++=++=++=++=++=++=++=++=++=++=++=++=++=++=++=++=++=++=++= Jim Ingham ji...@ap... Developer Tools - gdb |