I used this in the FileSnapper addin to deal with similar issues. RunProgram isn't actually tied to a window, but to the window's context, which can be cloned. As long as a clone or the window refers to the context, it won't be destroyed and the RunProgram scripts will still work. The namespace:evalcontext variable isn't ever used, except to keep the context alive. The RunProgram variable/handle (rp maybe) is also kept in the same namespace because it needs the same lifetime.
// addinLoad.jsl - this is the round-about launcher that uses a clone of a transient
// window's evalcontextbox to keep the evalcontext for a callback script alive.
// ideally, this would be, or directly include, FileSnapper.jsl, but that file
// constructs a RunProgram callback script that is somehow tied to a transient
// evalcontext that won't be available at callback time.
Local( {bb},
New Window( "File Snapper Startup", bb = Button Box( "start", Include( "$ADDIN_HOME(com.jmp.hales.FileSnapper)\Additional.jsl" ) ) );
bb << click; // run the script in this window's context
// capture the evalcontext, by cloning the box that references it into our namespace
Namespace( "FileSnapper" ):evalcontext = ((bb << parent) << parent) << clonebox;
bb << closewindow;
if(Namespace( "FileSnapper" ):evalcontext<<classname!="EvalContextBox",throw("FileSnapper addinLoad needs EvalContextBox, got "||(((bb << parent) << parent)<<classname)));
);
None of that is documented or promised to work in the future, but it will probably throw a helpful message if something changes.
@jschroedl - ^Q and OnClose scripts
Craige