Skip to main content
10-Marble
June 3, 2025
Solved

How to register callback when Arbortext is truly exiting

  • June 3, 2025
  • 1 reply
  • 1507 views

Product: PTC Arbortext Editor 8.2.2.1

 

The documentation for the session_add_callback and how the 'quit' callback function is invoked is confusing with regard to how the quit code is documented.  I need the ability to do some proper cleanup with Arbortext process is closing, but not sure how to reliable do this with a quit callback.

 

The code that is passed to the quit callback is 0, 1, 2, but some testing has shown that when called with a '0', the application may not fully exit if the user decides to cancel the quit (e.g. has unsaved edits).  For example, the following scenario happens:

  1. I select Exit from the File menu while there is unsaved changes.
  2. My callback is called with code equal to 0.  Since I do not know if the application is truly exiting, I have the callback do nothing.
  3. The Arbortext then pops up the do-you-want-to-save changes dialog.
  4. I cancel the dialog, so the application is still running.
  5. I choose exit again.
  6. Unsaved-changes dialog pops up again (my callback is NOT called). 
  7. Choose to not save changes to exit application (again, my callback is NOT called).

After canceling the first dialog, my callback is not called again when the application truly exits., so I am unable to do proper cleanup.  Is there any reliable way via ACL (or Java) to have a callback invoked when Arbortext is truly exiting, when the user no longer has options to cancel it.

Best answer by ClayHelberg

I just did a quick test, and my quit callback continues to trigger on subsequent exits even if the user is prompted to save and selects "cancel". I'm not sure why yours stops after the first cancel. You don't have anything in your code that removes the session callback explicitly, do you? My quit callback is very simple:

function bye(code, system) {
 response("Bye! code = " . code . ", system = " . system);
 return 0;
}

session_add_callback("quit", bye);

You can check whether the user will get prompted by looking for any modified documents, something like this:

function check_dirty_docs() {
 local docs[];
 doc_list(docs, 0x64); # only check main documents, modify flags as needed
 # if you use entities or xincludes
 local dirty = 0;
 for (d in docs) {
 if (modified(docs[d])) {
 dirty = 1;
 }
 }
 return dirty;
}

If there are no dirty documents, then there won't be any save prompt, and you can run your cleanup code. If there are dirty documents, you could possibly write your own prompt to ask them to save or discard changes. It's up to you if you want to offer them the chance to cancel there. If you don't, you're good--just run exit or quit ok to save all or discard all (respectively). If do you offer the cancel option, and they choose it, you can return -1 from the callback, but if it's working right, it should trigger again after the user finishes and re-quits.

1 reply

18-Opal
June 6, 2025

I guess it depends what kind of "proper cleanup" you are trying to do. Would it make sense to do the cleanup when the document is destroyed (unloaded from memory) instead? If so, you could possibly use doc_add_callback() to assign a "destroy" callback.

 

ehood10-MarbleAuthor
10-Marble
June 6, 2025

Thanks for the response, but unfortunately what you suggest will not work for me.  My extension operates across the entire session of Arbortext Editor, which can include multiple documents being opened.  I need to know when the Editor process itself is terminating, and where the user does not have the option to cancel termination.

 

To provide some more context, my extension monitors a folder under the user's local data area (of the operating system), where it checks for command files to be placed by another process.  These command files contains the pathname and location (represented as an XPath expression) within a document that should be opened in Editor.  The file system approach for communication was taken since creating a server process within Editor (I know I can create a listener socket via ACL) is likely not allowed in the environments our customers normally operate under.

 

Where cleanup comes in to play is the termination of the watcher thread running in Editor  (via Java) that monitors the directory.  I would like to perform an action when Editor terminates.  I tried registering a shutdown hook with the JVM, but apparently, the way Editor terminates the JVM prevents my shutdown hook from executing.  Therefore, trying to figure out via ACL on how to hook into the Editor termination process. I have something else I am going to try on the Java-side, but it would be nice if Editor provided the hook I needed.

18-Opal
June 9, 2025

I just did a quick test, and my quit callback continues to trigger on subsequent exits even if the user is prompted to save and selects "cancel". I'm not sure why yours stops after the first cancel. You don't have anything in your code that removes the session callback explicitly, do you? My quit callback is very simple:

function bye(code, system) {
 response("Bye! code = " . code . ", system = " . system);
 return 0;
}

session_add_callback("quit", bye);

You can check whether the user will get prompted by looking for any modified documents, something like this:

function check_dirty_docs() {
 local docs[];
 doc_list(docs, 0x64); # only check main documents, modify flags as needed
 # if you use entities or xincludes
 local dirty = 0;
 for (d in docs) {
 if (modified(docs[d])) {
 dirty = 1;
 }
 }
 return dirty;
}

If there are no dirty documents, then there won't be any save prompt, and you can run your cleanup code. If there are dirty documents, you could possibly write your own prompt to ask them to save or discard changes. It's up to you if you want to offer them the chance to cancel there. If you don't, you're good--just run exit or quit ok to save all or discard all (respectively). If do you offer the cancel option, and they choose it, you can return -1 from the callback, but if it's working right, it should trigger again after the user finishes and re-quits.