Need some Javascript help…

I have a custom HTML prompt window that I'd like the users to be able to leave onscreen, even if the macro isn't running. That part's fine and working great. But what I need is for them to not be able to open another of the same window (by choosing the same option in the macro's menu) if that window still exists.

The window ID thing doesn't help, as it's per instance. So what I was thinking of doing was:

  1. Set a permanent variable when the user opens the window.
  2. Using Javascript, reset that variable on window close.

Then my menu code could just check if that variable were set, and remove the menu option when it existed. In looking at what's available, it seems that KMWillCloseWindow() would do what I want…if I had any idea how to use it.

I've looked for examples here, and not had much luck. I'd just like to reset my variable when the window closes, and it seems that function communicates back to KM. But I know so little about Javascript that I don't know how to actually make it do anything—it just needs to set the value of a global variable to some known value.


So I think I've worked this out. Which is neat because I've read a lot of your blog over the years and never thought I would be able to help you out.

My thinking is that Peter has added code in the background that intercepts any method of closing the window and then calls a JavaScript function just before it closes <- probably not news to you.
The key is that you can then just write a function that uses the name as listed in the wiki as the function name and Peters code will make sure that your custom function is run at the appropriate time. You / I don't need to make sure that the function is attached to any element or event because Peter has done that for us.
See my example where the third function is simply named the special words "KMWillCloseWindow" and it seems to work as desired.

  • JS closeWindow function example Macro (v10.0.2)
  • [Edit to show setting value when the window opens as well]: This macro will set the global variable to "alfred" and then change it to "bob" when the window initialises, and then "colin" when the HTML prompt is closed. This can be confirmed in the editor window where the actions show the current value of the global variables.

JS closeWindow function example.kmmacros (3.0 KB)

Keyboard Maestro Export

1 Like

OMG thank you so much! I was so close, yet so far. I had this bit...

function KMWillCloseWindow() {
    window.KeyboardMaestro.SetVariable( 'zztest_Testing', 'isclosed' );

But I was missing this bit entirely:

function closeThisWindow() {

I just assumed that the window closing would trigger the KMWillCloseWindow routine, but it never did. Added the close this window function, and yep, works like a charm!


I still assume that... Clicking the red cross in the top left at least does seem to trigger KMWillCloseWindow(), and that doesn't touch my function at all.

Hmm, then I don't know what I was doing wrong :). But it's definitely working now, so thanks for the help!


Detecting whether the custom prompt window is still active, the following will do the job. Ensure "Failure Aborts Macro" is disabled. Basically if the executeJavascript action is ok, means the window is responding , hence do nothing.

If the detection fails, then those subsequent actions can follow (like calling custom prompt action to show window).

Thanks for the suggestion (and I do seem to understand how it would work), but the problem is my main macro can actually not be running at all when this window is still open, so I need a way to detect it when they relaunch the macro. @vincent_ardern's solution works great—I wrapped a section of my menu builder with an if-then that skips the "display window" option if it's already open.


No, you do not need the main macro to be running because the custom prompt window is asynchronous (which you will have set it to be). The window will stay even though main macro has finished running.
The above actions are just to check whether the window is been shown before further actions are processed.

Ah, OK, that makes sense—thanks! Always nice to have two solutions :).