[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Rumors of dead macptrs
- To: Steve_Mitchell-R1946C@email.sps.mot.com
- Subject: Re: Rumors of dead macptrs
- From: bill@cambridge.apple.com (Bill St. Clair)
- Date: Mon, 10 Apr 1995 10:48:14 -0400
- Cc: info-mcl@digitool.com, Wookye@aol.com
- Sender: owner-info-mcl@digitool.com
At 8:30 PM 4/8/95, Steve_Mitchell-R1946C@email.sps.mot.com wrote:
>Dear MCL Mavens;
>
>As usual, I'm turning to you when I have a problem that's
>hard to characterize, and has "bugged" me for awhile.
>
>I have a menu that pops up on option-click in a window
>(The GUI Police need not respond; it's "temporary", I swear).
>If the menu is created once and the application is saved,
>there is a problem when the saved application is run. Now
>option-click leads not to a menu of commands, but a
>DEAD-MACPTR error.
Sounds like you're storing the pop-up menu in a global variable,
but not clearing that global with either an entry in *save-exit-functions*,
*lisp-startup-functions* or a def-load-pointers function. Any
one of the above will likely fix the problem.
>
>This is easy to rationalize. When the application was
>saved, MCL didn't know about this menu, so it didn't
>deal with the menu object's macptr into the Mac heap,
>so the old macptr is invalid in the new application.
>This assumes that at save-application time, MCL recognizes
>and deals with installed menus, which I suspect is not
>what happens at all.
MCL deals correctly with the menus in the menubar, but the
pop-up-menu package is not designed that way. Since most
pop-up menus are static subviews of a view, and not stored
in a global variable, forcing them to be recreated when the
saved application is restarted, noone thought to add this
to the pop-up-menu design.
>
>I noticed that font-menus.lisp contains the line:
>(pushnew 'add-font-menus *lisp-startup-functions*).
>The fn should actually be called add-fonts-menu, because
>what it does is rebuild the Fonts heirarchical menu,
>just in case your font mix changed since the last time
>you ran your application. Anyway, using this technique
>made the error go away, but, as usual, I'm still not
>happy.
It will make the saved application slightly smaller if you
clear out all the dead macptrs (with a *save-exit-function*)
before saving. Often it's easier to just have a def-load-pointers
or *lisp-startup-functions* entry that will reinitialize at
startup. The final result is the same.
>
>A formerly-perfectly-good menu containing a destined-to-
>be-dead macptr still got saved in the application. I
>suspect that when the popup menu vanishes (unpops) from
>the screen its menu-handle slot's macptr should be
>deallocated and the slot set to nil. Similarly the
>menu-id slot should be set to nil.
Normally, you'd rather not need allocate the toolbox menu
each time the user clicks and deallocate it afterwards.
>
>Questions:
>
>1. Does this mean something more should be done when the
> popup menu unpops? e.g. I don't think menu-deinstall
> is being called.
menu-deinstall is called on a pop-up-menu when it is removed
from its window (see the remove-view-from-window method in
"pop-up-menu.lisp". Normally, this is sufficient. You could
use this method if it makes you feel better. Call
set-view-container before popping up your pop-up menu to
install it in the clicked-on window, and afterwards, to remove
it and deallocate the mac heap data.
>
>2. If my "solution" is basically correct, shouldn't a
> *save-exit-functions* fn clean up before the save,
> and what would that fn look like?
It would look like the following. if your code does
(set-view-container *pop-up-menu* clicked-on-window)
when the user option-clicks, you could use this
instead of the *lisp-startup-function*.
(defun cleanup-pop-up-menu ()
(when *pop-up-menu* (set-view-container *pop-up-menu* nil)))
(pushnew 'cleanup-pop-up-menu *save-exit-functions*)
>
>3. I had a similar problem with the HIERARCHICAL menus in
> Matt Cornell's fred-keystroke-macros; anyone know why?
Works fine for me. Maybe I'm using a different version of
that code.
>
>4. I had a similar problem (boy I have a lot of problems)
> with a CHECK-MARK I put on a menu-item:
> (add-new-item menu "Debugging" nil
> 'debugging-menu-item-action
> :menu-item-checked *debugging*)
> When the saved app started it called
> set-menu-item-check-mark on a dead MacPtr in a tight
> loop breaking a mile a minute. Does this mean check-mark
> menu items have to be removed before a save? Doesn't
> seem likely, but I haven't solved it.
I'd have to see your code to answer this one.
>
>5. If the line above from font-menus.lisp allocates a
> macptr, why is it using *lisp-startup-functions* vice
> def-load-pointers? (MCL Reference p651).
Hard to say. It may be that the system is not sufficiently initialized
at def-load-pointers time to add menus. More likely is that the
writer of "font-menus.lisp" happenned to think of *lisp-startup-functions*
before def-load-pointers.
>
>6. Anyone got a meaty example of def-load-pointers usage?
My "define-interrupt-handler" contribution contains a def-load-pointers
to initialize its mac heap state. It should still be available for
anonymous FTP from digitool.com in the file
"/pub/mcl2/contrib/define-interrupt-handler.hqx".
Conclusion. There are two ways to handle this. The *lisp-startup-functions*
entry as you're doing now, or a *save-exit-function* that forces your
code to reinstall the menu the first time it's called.